ref: ce708f49bf5ec6c6b3fe1bb29d401c42b841b649
dir: /names.c/
#include "all.h" s8 searchnames(Dentry *d, char *searchname, u64 *relip) { u16 searchnamelen, slen; s8 *namebuf; u64 n, reli; Name nm; /* is this valid? */ if(d == nil || searchname == nil || relip == nil) panic("searchnames: should not be happening"); searchnamelen = strlen(searchname); if(searchnamelen == 0) error(errstring[Ebadname]); reli = *relip = 0; slen = min(searchnamelen,Nfirst); if(searchnamelen > Nfirst){ namebuf = emalloc9p(searchnamelen); if(waserror()){ free(namebuf); nexterror(); } }else namebuf = nil; while(readfile(d->dblocks[In], d->qpath+1+In, (s8*)&nm, sizeof(Name), reli*sizeof(Name)) == sizeof(Name)){ if(searchnamelen == nm.namelen && strncmp(nm.name, searchname, slen) == 0){ if(searchnamelen <= Nfirst){ *relip = reli; return 1; }else{ n = readfile(d->dblocks[Inl], d->qpath+1+Inl, namebuf, searchnamelen, nm.noffset); if(n != searchnamelen) error(errstring[Einvread]); if(n == searchnamelen && strncmp(searchname, namebuf, searchnamelen) == 0){ *relip = reli; poperror(); free(namebuf); return 1; } } } if(*relip == 0 && nm.namelen == 0) *relip = reli; /* a zeroed out reli, reuse if none found */ reli++; } if(namebuf){ poperror(); free(namebuf); } /* nothing found */ if(*relip == 0) *relip = reli; /* use a new reli at the end */ return 0; } void newnames(Dentry *pd, u16 uid, u64 pdblkno, Iobuf **iobufs) { Iobuf *iobuf; Dentry *d; u8 i; for(i = 0; i < 3; i++){ iobuf = iobufs[i]; pd->dblocks[i] = iobuf->blkno; d = iobuf->d; if(i == In) d->flags = Fn; else if(i == Inle) d->flags = Fe; d->flags |= Fsys; d->pdblkno = pdblkno; d->pqpath = pd->qpath; d->preli = i; d->uid = pd->uid; d->gid = pd->gid; d->muid = pd->muid; d->mode = pd->mode & ~DMDIR; d->mtime = nsec(); d->version = 1; putbuf(iobuf, 1); } addname(pd, uid, 0, ".n"); addname(pd, uid, 1, ".nl"); addname(pd, uid, 2, ".nle"); } /* returns namelen */ u16 readname(Dentry *pd, u64 preli, s8 **namep, u16 *namelen) { u16 n; Name nm; n = readfile(pd->dblocks[In], pd->qpath+1+In, (s8*)&nm, sizeof(Name), preli*sizeof(Name)); if(n != sizeof(Name)) error(errstring[Einvread]); *namelen = nm.namelen; *namep = emalloc9p(nm.namelen+1); if(nm.namelen <= Nfirst){ strncpy(*namep, nm.name, nm.namelen); return nm.namelen; } return readfile(pd->dblocks[Inl], pd->qpath+1+Inl, *namep, nm.namelen, nm.noffset); } void rmname(Dentry *pd, s16 uid, u64 preli) { u64 n; Name nm; Extents *nes; s8 esname[32]; n = readfile(pd->dblocks[In], pd->qpath+1+In, (s8*)&nm, sizeof(Name), preli*sizeof(Name)); if(n != sizeof(Name)) error(errstring[Einvread]); if(nm.namelen > Nfirst){ nes = emalloc9p(sizeof(Extents)); if(waserror()){ freeextents(nes); nexterror(); } snprint(esname, 32, "%llud", pd->qpath); initextents(nes, esname, 0, 0, 2, nil, dprintfd, panic, malloc9p); loadextentsfile(pd->dblocks[Inle], pd->qpath+1+Inle, nes); ufree(nes, nm.noffset, nm.namelen); saveextentstofile(pd->dblocks[Inle], pd->qpath+1+Inle, uid, nes); poperror(); freeextents(nes); } memset(&nm, 0, sizeof(Name)); n = writefile(pd->dblocks[In], pd->qpath+1+In, uid, (s8*)&nm, sizeof(Name), preli*sizeof(Name)); if(n != sizeof(Name)) error(errstring[Einvwrite]); } u16 addnamelen(Dentry *pd, u16 uid, u64 preli, s8 *name, u16 namelen) { Extents *nes; s8 esname[32]; u64 start, size; Name nm; nm.namelen = namelen; strncpy(nm.name, name, Nfirst); if(nm.namelen <= Nfirst){ nm.noffset = 0; if(writefile(pd->dblocks[In], pd->qpath+1+In, uid, (s8*)&nm, sizeof(Name), preli*sizeof(Name)) == sizeof(Name)) return nm.namelen; return 0; } nes = emalloc9p(sizeof(Extents)); if(waserror()){ freeextents(nes); nexterror(); } snprint(esname, 32, "%llud", pd->qpath); initextents(nes, esname, 0, 0, 2, nil, dprintfd, panic, malloc9p); loadextentsfile(pd->dblocks[Inle], pd->qpath+1+Inle, nes); /* reusing */ if(ualloc(nes, namelen, &start)){ if(writefile(pd->dblocks[Inl], pd->qpath+1+Inl, uid, name, nm.namelen, start) != namelen) error(errstring[Einvwrite]); nm.noffset = start; saveextentstofile(pd->dblocks[Inle], pd->qpath+1+Inle, uid, nes); }else{ nm.noffset = size = readfilesize(pd->dblocks[Inl], pd->qpath+1+Inl); if(writefile(pd->dblocks[Inl], pd->qpath+1+Inl, uid, name, nm.namelen, size) != nm.namelen) error(errstring[Einvwrite]); } poperror(); freeextents(nes); if(writefile(pd->dblocks[In], pd->qpath+1+In, uid, (s8*)&nm, sizeof(Name), preli*sizeof(Name)) != sizeof(Name)) error(errstring[Einvwrite]); return nm.namelen; } u16 addname(Dentry *pd, u16 uid, u64 preli, s8 *name) { return addnamelen(pd, uid, preli, name, strlen(name)); } u16 updatename(Dentry *pd, u16 uid, u64 preli, s8 *name) { u16 newlen, n; Name nm; /* if the namelen matches with the existing, change in-place */ newlen = strlen(name); n = readfile(pd->dblocks[In], pd->qpath+1+In, (s8*)&nm, sizeof(Name), preli*sizeof(Name)); if(n != sizeof(Name)) error(errstring[Einvread]); if(nm.namelen > Nfirst) rmname(pd, uid, preli); return addnamelen(pd, uid, preli, name, newlen); }