Plan 9 from Bell Labs’s /usr/web/sources/contrib/uriel/changes/2005/1029/3

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


Keep children in create order.
 [rsc] --rw-rw-r-- M 431581 glenda sys 6695 Oct 29 10:54 sys/src/lib9p/file.c
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:10,20 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:10,27
	   * Always lock child then parent, never parent then child.
	   * If holding the free file lock, do not lock any Files.
	   */
	- struct Filelist {
	+ struct Filelist
	+ {
	  	File *f;
	  	Filelist *link;
	  };
	  
	+ struct Readdir
	+ {
	+ 	File *dir;
	+ 	Filelist *fl;
	+ };
	+ 
	  static QLock filelk;
	  static File *freefilelist;
	  
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:67,72 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:74,112
	  	qunlock(&filelk);
	  }
	  
	+ static void
	+ cleanfilelist(File *f)
	+ {
	+ 	Filelist **l;
	+ 	Filelist *fl;
	+ 	
	+ 	/*
	+ 	 * can't delete filelist structures while there
	+ 	 * are open readers of this directory, because
	+ 	 * they might have references to the structures.
	+ 	 * instead, just leave the empty refs in the list
	+ 	 * until there is no activity and then clean up.
	+ 	 */
	+ 	if(f->readers.ref != 0)
	+ 		return;
	+ 	if(f->nxchild == 0)
	+ 		return;
	+ 
	+ 	/*
	+ 	 * no dir readers, file is locked, and
	+ 	 * there are empty entries in the file list.
	+ 	 * clean them out.
	+ 	 */
	+ 	for(l=&f->filelist; fl=*l; ){
	+ 		if(fl->f == nil){
	+ 			*l = (*l)->link;
	+ 			free(fl);
	+ 		}else
	+ 			l = &(*l)->link;
	+ 	}
	+ 	f->nxchild = 0;
	+ }
	+ 
	  void
	  closefile(File *f)
	  {
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:125,134 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:165,177
	  
	  	fl->f = nil;
	  	fp->nchild--;
	+ 	fp->nxchild++;
	  	f->parent = nil;
	- 	wunlock(fp);
	  	wunlock(f);
	  
	+ 	cleanfilelist(fp);
	+ 	wunlock(fp);
	+ 
	  	closefile(fp);	/* reference from child */
	  	closefile(f);	/* reference from tree */
	  	closefile(f);
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:139,145 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:182,188
	  createfile(File *fp, char *name, char *uid, ulong perm, void *aux)
	  {
	  	File *f;
	- 	Filelist *fl, *freel;
	+ 	Filelist **l, *fl;
	  	Tree *t;
	  
	  	if((fp->qid.type&QTDIR) == 0){
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:147,170 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:190,215
	  		return nil;
	  	}
	  
	- 	freel = nil;
	  	wlock(fp);
	- 	for(fl=fp->filelist; fl; fl=fl->link){
	- 		if(fl->f == nil)
	- 			freel = fl;
	- 		else if(strcmp(fl->f->name, name) == 0){
	+ 	/*
	+ 	 * We might encounter blank spots along the
	+ 	 * way due to deleted files that have not yet
	+ 	 * been flushed from the file list.  Don't reuse
	+ 	 * those - some apps (e.g., omero) depend on
	+ 	 * the file order reflecting creation order. 
	+ 	 * Always create at the end of the list.
	+ 	 */
	+ 	for(l=&fp->filelist; fl=*l; l=&fl->link){
	+ 		if(fl->f && strcmp(fl->f->name, name) == 0){
	  			wunlock(fp);
	  			werrstr("file already exists");
	  			return nil;
	  		}
	  	}
	+ 	
	+ 	fl = emalloc9p(sizeof *fl);
	+ 	*l = fl;
	  
	- 	if(freel == nil){
	- 		freel = emalloc9p(sizeof *freel);
	- 		freel->link = fp->filelist;
	- 		fp->filelist = freel;
	- 	}
	- 
	  	f = allocfile();
	  	f->name = estrdup9p(name);
	  	f->uid = estrdup9p(uid ? uid : fp->uid);
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:193,199 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:238,244
	  
	  	incref(f);	/* being returned */
	  	incref(f);	/* for the tree */
	- 	freel->f = f;
	+ 	fl->f = f;
	  	fp->nchild++;
	  	wunlock(fp);
	  
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:245,251 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:290,296
	  		else
	  			nexts = s+strlen(s);
	  		nf = walkfile1(f, s);
	- 		decref(f);
	+ 		closefile(f);
	  		f = nf;
	  		if(f == nil)
	  			break;
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:323,332 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:368,373
	  	free(t);
	  }
	  
	- struct Readdir {
	- 	Filelist *fl;
	- };
	- 
	  Readdir*
	  opendirfile(File *dir)
	  {
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:340,349 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:381,394
	  	r = emalloc9p(sizeof(*r));
	  
	  	/*
	- 	 * This reference won't go away while we're using it
	- 	 * since we are dir->rdir.
	+ 	 * This reference won't go away while we're 
	+ 	 * using it because file list entries are not freed
	+ 	 * until the directory is removed and all refs to
	+ 	 * it (our fid is one!) have gone away.
	  	 */
	  	r->fl = dir->filelist;
	+ 	r->dir = dir;
	+ 	incref(&dir->readers);
	  	runlock(dir);
	  	return r;
	  }
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/file.c:367,371 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/file.c:412,421
	  void
	  closedirfile(Readdir *r)
	  {
	+ 	if(decref(&r->dir->readers) == 0){
	+ 		wlock(r->dir);
	+ 		cleanfilelist(r->dir);
	+ 		wunlock(r->dir);
	+ 	}
	  	free(r);
	  }
 [rsc] --rw-rw-r-- M 431581 glenda sys 16871 Oct 29 10:54 sys/src/lib9p/srv.c
	/n/sourcesdump/2005/1029/plan9/sys/src/lib9p/srv.c:218,224 - 
	/n/sourcesdump/2005/1030/plan9/sys/src/lib9p/srv.c:218,224
	  	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;
	  	}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].