Teach CFS to check remote server identity (via getnetconninfo) and wipe the cache on mismatch. This should help in the case of a terminal that switches between mounts of several different file systems as root. Reference: /n/sources/patch/applied/cfs-ident Date: Tue Nov 28 01:02:10 CET 2006 Signed-off-by: nwf+412@andrew.cmu.edu --- /sys/man/4/cfs Tue Nov 28 01:01:24 2006 +++ /sys/man/4/cfs Tue Nov 28 01:01:23 2006 @@ -4,14 +4,14 @@ .SH SYNOPSIS .B cfs .B -s -.RB [ -rdS ] +.RB [ -krdS ] .RB [ -f .IR partition ] .PP .B cfs .B -a .I netaddr -.RB [ -rdS ] +.RB [ -krdS ] .RB [ -f .IR partition ] .RI [ mtpt ] @@ -66,6 +66,10 @@ use file .I partition as the cache disk partition. +.TP +.BI k +Keep cache contents even if they might have come from a different server. +Cfs will obey the -r flag even if -k is given. .PP All 9P messages except .BR read , @@ -77,12 +81,6 @@ are passed through .I cfs unchanged to the remote server. -A -.B clone -followed immediately by a -.B walk -is converted into a -.BR clwalk . If possible, a .B read is satisfied by cached data. --- /sys/src/cmd/cfs/cformat.h Tue Nov 28 01:01:29 2006 +++ /sys/src/cmd/cfs/cformat.h Tue Nov 28 01:01:28 2006 @@ -15,7 +15,7 @@ Amagic= 0xbebedded, /* allocation block magic */ Imagic= 0xbadc0c0a, /* inode block magic */ BtoUL= 8*sizeof(ulong),/* bits in a ulong */ - KNAMELEN= 28 /* old NAMELEN: BUG */ + CACHENAMELEN= 128 }; #define Indbno 0x80000000 /* indirect block */ #define Notabno 0xFFFFFFFF /* not a block number */ @@ -29,7 +29,7 @@ { ulong magic; ulong bsize; /* logical block size */ - char name[KNAMELEN]; + char name[CACHENAMELEN]; short nab; /* number of allocation blocks */ }; struct Dalloc --- /sys/src/cmd/cfs/cfs.c Tue Nov 28 01:01:35 2006 +++ /sys/src/cmd/cfs/cfs.c Tue Nov 28 01:01:33 2006 @@ -81,7 +81,7 @@ void rcvmsg(P9fs*, Fcall*); int delegate(void); int askserver(void); -void cachesetup(int, char*); +void cachesetup(int, char*, char*); int ctltest(Mfile*); void genstats(void); @@ -119,8 +119,8 @@ void usage(void) { - fprint(2, "usage:\tcfs -s [-rd] [-f partition]"); - fprint(2, "\tcfs [-rd] [-f partition] [-a netaddr] [mt-pt]\n"); + fprint(2, "usage:\tcfs -s [-krd] [-f partition]\n"); + fprint(2, "\tcfs [-krd] [-f partition] [-a netaddr] [mt-pt]\n"); exits("usage"); } @@ -133,8 +133,12 @@ char *server; char *mtpt; + int chkid; + NetConnInfo * snci; + std = 0; format = 0; + chkid = 1; part = "/dev/sdC0/cache"; server = "il!emelie"; mtpt = "/tmp"; @@ -162,6 +166,9 @@ case 'd': debug = 1; break; + case 'k': + chkid = 0; + break; default: usage(); }ARGEND @@ -171,8 +178,6 @@ if(debug) fmtinstall('F', fcallfmt); - cachesetup(format, part); - c.name = "client"; s.name = "server"; if(std){ @@ -181,6 +186,19 @@ }else mountinit(server, mtpt); + if(chkid){ + if((snci = getnetconninfo(nil, s.fd[0])) == nil){ + /* Failed to lookup information; format */ + cachesetup(1, nil, part); + }else{ + /* Do partition check */ + cachesetup(0, snci->raddr, part); + } + }else{ + /* Obey -f w/o regard to cache vs. remote server */ + cachesetup(format, nil, part); + } + switch(fork()){ case 0: io(); @@ -193,7 +211,7 @@ } void -cachesetup(int format, char *partition) +cachesetup(int format, char *name, char *partition) { int f; int secsize; @@ -208,8 +226,12 @@ if(f < 0) error("opening partition"); - if(format || iinit(&ic, f, secsize)<0){ - if(iformat(&ic, f, inodes, "bootes", blocksize, secsize) < 0) + if(format || iinit(&ic, f, secsize, name)<0){ + /* If we need to format and don't have a name, fall + * back to our old behavior of using "bootes" + */ + name = (name == nil) ? "bootes" : name; + if(iformat(&ic, f, inodes, name, blocksize, secsize) < 0) error("formatting failed"); } } --- /sys/src/cmd/cfs/disk.c Thu Mar 1 16:20:31 2007 +++ /sys/src/cmd/cfs/disk.c Tue Nov 28 01:01:39 2006 @@ -12,7 +12,7 @@ * is inconsistent. */ int -dinit(Disk *d, int f, int psize) +dinit(Disk *d, int f, int psize, char *expname) { Dir *dir; char buf[1024]; @@ -61,6 +61,13 @@ d->p2b = d->bsize/sizeof(Dptr); strncpy(d->name, ba->name, sizeof(d->name)); + if ( (expname != nil) && + ( strncmp(d->name, expname, sizeof(d->name)) != 0 )) { + /* Mismatch with recorded name; fail here to force a format */ + fprint(2, "cfs name mismatch\n"); + return -1; + } + /* * check allocation blocks for consistency */ @@ -349,7 +356,7 @@ /* * then all the pages it points to * - * DANGER: this algorithm may fail if their are more + * DANGER: this algorithm may fail if there are more * allocation blocks than block buffers */ b = bcread(d, bno); --- /sys/src/cmd/cfs/disk.h Tue Nov 28 01:01:47 2006 +++ /sys/src/cmd/cfs/disk.h Tue Nov 28 01:01:46 2006 @@ -10,10 +10,10 @@ int nab; /* number of allocation blocks */ int b2b; /* allocation bits to a block */ int p2b; /* Dptr's per page */ - char name[KNAMELEN]; + char name[CACHENAMELEN]; }; -int dinit(Disk*, int, int); +int dinit(Disk*, int, int, char*); int dformat(Disk*, int, char*, ulong, ulong); ulong dalloc(Disk*, Dptr*); ulong dpalloc(Disk*, Dptr*); --- /sys/src/cmd/cfs/inode.c Tue Nov 28 01:01:54 2006 +++ /sys/src/cmd/cfs/inode.c Tue Nov 28 01:01:53 2006 @@ -18,7 +18,7 @@ * nab is the first inode block. */ int -iinit(Icache *ic, int f, int psize) +iinit(Icache *ic, int f, int psize, char* name) { Ibuf *b; Imap *m; @@ -29,7 +29,7 @@ /* * get basic sizes and allocation info from disk */ - if(dinit(ic, f, psize) < 0) + if(dinit(ic, f, psize, name) < 0) return -1; /* @@ -143,7 +143,7 @@ bcsync(ic); - return iinit(ic, f, psize); + return iinit(ic, f, psize, name); } /* --- /sys/src/cmd/cfs/inode.h Tue Nov 28 01:02:03 2006 +++ /sys/src/cmd/cfs/inode.h Tue Nov 28 01:02:02 2006 @@ -52,7 +52,7 @@ Ibuf* iget(Icache*, Qid); Ibuf* iread(Icache*, ulong); int iformat(Icache*, int, ulong, char*, int, int); -int iinit(Icache*, int, int); +int iinit(Icache*, int, int, char*); int iremove(Icache*, ulong); int iupdate(Icache*, ulong, Qid); int iwrite(Icache*, Ibuf*);