In file.c there seemed to be a leak. Also, the order of sons in a file is preserved wrt creation order. If we create ./a ./b then rm ./b and create ./c, the list of sons has ./a ./c. This is important for omero, where the order of files determines the order of widgets. In srv.c an incref (already marked in sources(?)) was missing. Notes: Sat Oct 29 10:55:15 EDT 2005 rsc I applied your fix to srv.c, which was correct. I did not apply your change to removefile. The reason the filelist structure exists at all is to keep them around beyond remove time because they are referenced by open directory readers (see bottom of file). I made a different change that should have the effect you wanted - the listing of files in a directory reflects the create order. I could not tell from your diffs what the leak was in file.c. Could you point it out to me? Thanks. Russ Reference: /n/sources/patch/applied/lib9p Date: Thu Oct 27 20:51:56 CES 2005 Reviewed-by: rsc --- /sys/src/lib9p/file.c Thu Oct 27 20:50:10 2005 +++ /sys/src/lib9p/file.c Thu Oct 27 20:50:08 2005 @@ -85,7 +85,7 @@ removefile(File *f) { File *fp; - Filelist *fl; + Filelist *fl, **flp; fp = f->parent; if(fp == nil){ @@ -118,12 +118,15 @@ return -1; } - for(fl=fp->filelist; fl; fl=fl->link) - if(fl->f == f) + for(flp=&fp->filelist; fl=*flp; flp=&(*flp)->link) + if(fl->f == f){ + *flp = fl->link; break; + } assert(fl != nil && fl->f == f); fl->f = nil; + free(fl); fp->nchild--; f->parent = nil; wunlock(fp); @@ -139,7 +142,7 @@ createfile(File *fp, char *name, char *uid, ulong perm, void *aux) { File *f; - Filelist *fl, *freel; + Filelist *fl, *freel, *fle; Tree *t; if((fp->qid.type&QTDIR) == 0){ @@ -148,6 +151,7 @@ } freel = nil; + fle = nil; wlock(fp); for(fl=fp->filelist; fl; fl=fl->link){ if(fl->f == nil) @@ -157,12 +161,18 @@ werrstr("file already exists"); return nil; } + fle = fl; } if(freel == nil){ freel = emalloc9p(sizeof *freel); - freel->link = fp->filelist; - fp->filelist = freel; + if (fle == nil){ + freel->link = fp->filelist; + fp->filelist = freel; + } else { + freel->link = nil; + fle->link = freel; + } } f = allocfile(); @@ -209,6 +219,11 @@ rlock(dir); if(strcmp(elem, "..") == 0){ fp = dir->parent; + if (fp == nil){ + werrstr("walk on a deleted file"); + runlock(dir); + return nil; + } incref(fp); runlock(dir); closefile(dir); --- /sys/src/lib9p/srv.c Thu Oct 27 20:50:24 2005 +++ /sys/src/lib9p/srv.c Sat Oct 29 16:17:35 2005 @@ -218,7 +218,7 @@ r->fid->uid = estrdup9p(r->ifcall.uname); if(srv->tree){ r->fid->file = srv->tree->root; - /* BUG? incref(r->fid->file) ??? */ + incref(r->fid->file); r->ofcall.qid = r->fid->file->qid; r->fid->qid = r->ofcall.qid; }