9 * To avoid deadlock, the following rules must be followed.
10 * Always lock child then parent, never parent then child.
11 * If holding the free file lock, do not lock any Files.
26 static File *freefilelist;
36 if(freefilelist == nil){
37 f = emalloc9p(N*sizeof(*f));
46 freefilelist = f->aux;
50 memset(f, 0, sizeof *f);
58 Filelist *fl, *flnext;
60 for(fl=f->filelist; fl; fl=flnext){
72 f->aux = freefilelist;
78 cleanfilelist(File *f)
84 * can't delete filelist structures while there
85 * are open readers of this directory, because
86 * they might have references to the structures.
87 * instead, just leave the empty refs in the list
88 * until there is no activity and then clean up.
90 if(f->readers.ref != 0)
96 * no dir readers, file is locked, and
97 * there are empty entries in the file list.
100 for(l=&f->filelist; fl=*l; ){
132 werrstr("no parent");
138 werrstr("cannot remove root");
146 werrstr("has children");
154 werrstr("parent changed underfoot");
161 for(fl=fp->filelist; fl; fl=fl->link)
164 assert(fl != nil && fl->f == f);
175 closefile(fp); /* reference from child */
176 closefile(f); /* reference from tree */
182 createfile(File *fp, char *name, char *uid, ulong perm, void *aux)
188 if((fp->qid.type&QTDIR) == 0){
189 werrstr("create in non-directory");
194 if(fp->parent == nil){
196 werrstr("create in deleted directory");
201 * We might encounter blank spots along the
202 * way due to deleted files that have not yet
203 * been flushed from the file list. Don't reuse
204 * those - some apps (e.g., omero) depend on
205 * the file order reflecting creation order.
206 * Always create at the end of the list.
208 for(l=&fp->filelist; fl=*l; l=&fl->link){
209 if(fl->f && strcmp(fl->f->name, name) == 0){
211 werrstr("file already exists");
216 fl = emalloc9p(sizeof *fl);
220 f->name = estrdup9p(name);
221 f->uid = estrdup9p(uid ? uid : fp->uid);
222 f->gid = estrdup9p(fp->gid);
223 f->muid = estrdup9p(uid ? uid : "unknown");
229 f->qid.path = t->qidgen++;
232 f->qid.type |= QTDIR;
234 f->qid.type |= QTAPPEND;
236 f->qid.type |= QTEXCL;
238 f->atime = f->mtime = time(0);
244 incref(f); /* being returned */
245 incref(f); /* for the tree */
254 walkfile1(File *dir, char *elem)
260 if(strcmp(elem, "..") == 0){
270 for(fl=dir->filelist; fl; fl=fl->link)
271 if(fl->f && strcmp(fl->f->name, elem)==0){
283 walkfile(File *f, char *path)
285 char *os, *s, *nexts;
287 if(strchr(path, '/') == nil)
288 return walkfile1(f, path); /* avoid malloc */
290 os = s = estrdup9p(path);
292 if(nexts = strchr(s, '/'))
305 alloctree(char *uid, char *gid, ulong mode, void (*destroy)(File*))
311 t = emalloc9p(sizeof *t);
313 f->name = estrdup9p("/");
319 uid = estrdup9p(uid);
322 gid = estrdup9p(uid);
324 gid = estrdup9p(gid);
326 muid = estrdup9p(uid);
328 f->qid = (Qid){0, 0, QTDIR};
330 f->atime = f->mtime = time(0);
331 f->mode = DMDIR | mode;
344 t->destroy = destroy;
352 Filelist *fl, *flnext;
354 for(fl=f->filelist; fl; fl=flnext){
372 opendirfile(File *dir)
377 if((dir->mode & DMDIR)==0){
381 r = emalloc9p(sizeof(*r));
384 * This reference won't go away while we're
385 * using it because file list entries are not freed
386 * until the directory is removed and all refs to
387 * it (our fid is one!) have gone away.
389 r->fl = dir->filelist;
391 incref(&dir->readers);
397 readdirfile(Readdir *r, uchar *buf, long n, long o)
403 fl = r->dir->filelist;
406 for(m=0; fl && m+2<=n; fl=fl->link, m+=x){
409 else if((x=convD2M(fl->f, buf+m, n-m)) <= BIT16SZ)
417 closedirfile(Readdir *r)
419 if(decref(&r->dir->readers) == 0){
421 cleanfilelist(r->dir);