12 #define stime configstime /* sometimes in <time.h> */
13 typedef struct Entry Entry;
22 uchar score[VtScoreSize]; /* of fsys */
24 uchar sha1[VtScoreSize]; /* of path to this entry */
28 typedef struct Config Config;
38 static ulong mtime; /* mod time */
39 static ulong stime; /* sync time */
40 static char* configfile;
42 static int addpath(Config*, char*, uchar[VtScoreSize], ulong);
51 for(i=0; i<nelem(c->hash); i++){
52 for(e=c->hash[i]; e; e=next){
63 return (s[0]<<2)|(s[1]>>6);
67 entrybyhandle(Nfs3Handle *h)
73 for(e=config->hash[hh]; e; e=e->nexthash)
74 if(memcmp(e->sha1, h->h, VtScoreSize) == 0)
80 readconfigfile(char *name, VtCache *vcache)
82 char *p, *pref, *f[10];
85 uchar score[VtScoreSize];
90 configfile = vtstrdup(name);
92 if((dir = dirstat(name)) == nil)
95 if((b = Bopen(name, OREAD)) == nil){
102 c = emalloc(sizeof(Config));
106 c->root = emalloc(sizeof(Entry));
108 c->root->parent = c->root;
109 sha1((uchar*)"/", 1, c->root->sha1, nil);
110 h = namehash(c->root->sha1);
111 c->hash[h] = c->root;
113 for(; (p = Brdstr(b, '\n', 1)) != nil; free(p)){
117 nf = tokenize(p, f, nelem(f));
119 fprint(2, "%s:%d: syntax error\n", name, line);
123 if(vtparsescore(f[1], &pref, score) < 0){
124 fprint(2, "%s:%d: bad score '%s'\n", name, line, f[1]);
129 fprint(2, "%s:%d: unrooted path '%s'\n", name, line, f[0]);
133 if(addpath(c, f[0], score, strtoul(f[2], 0, 0)) < 0){
134 fprint(2, "%s:%d: %s: %r\n", name, line, f[0]);
159 if((d = dirstat(configfile)) == nil)
161 if(d->mtime == mtime){
167 c = readconfigfile(configfile, config->vcache);
182 entrylookup(Entry *e, char *p, int np)
184 for(e=e->kids; e; e=e->nextdir)
185 if(strlen(e->name) == np && memcmp(e->name, p, np) == 0)
191 walkpath(Config *c, char *name)
202 nextp = strchr(p, '/');
206 werrstr("%.*s is already a mount point", utfnlen(name, nextp-name), name);
209 if((ee = entrylookup(e, p, nextp-p)) == nil){
210 ee = emalloc(sizeof(Entry)+(nextp-p)+1);
212 ee->nextdir = e->kids;
214 ee->name = (char*)&ee[1];
215 memmove(ee->name, p, nextp-p);
216 ee->name[nextp-p] = 0;
217 sha1((uchar*)name, nextp-name, ee->sha1, nil);
218 h = namehash(ee->sha1);
219 ee->nexthash = c->hash[h];
225 werrstr("%s already has children; cannot be mount point", name);
232 addpath(Config *c, char *name, uchar score[VtScoreSize], ulong time)
236 e = walkpath(c, name);
241 memmove(e->score, score, VtScoreSize);
246 mkhandle(Nfs3Handle *h, Entry *e)
248 memmove(h->h, e->sha1, VtScoreSize);
249 h->len = VtScoreSize;
253 handleparse(Nfs3Handle *h, Fsys **pfsys, Nfs3Handle *nh, int isgetattr)
262 if(h->len < VtScoreSize)
263 return Nfs3ErrBadHandle;
266 for(e=config->hash[hh]; e; e=e->nexthash)
267 if(memcmp(e->sha1, h->h, VtScoreSize) == 0)
270 return Nfs3ErrBadHandle;
272 if(e->isfsys == 1 && e->fsys == nil && (h->len != VtScoreSize || !isgetattr)){
273 if((disk = diskopenventi(config->vcache, e->score)) == nil){
274 fprint(2, "cannot open disk %V: %r\n", e->score);
277 if((fsys = fsysopen(disk)) == nil){
278 fprint(2, "cannot open fsys on %V: %r\n", e->score);
285 if(e->fsys == nil || (isgetattr && h->len == VtScoreSize)){
286 if(h->len != VtScoreSize)
287 return Nfs3ErrBadHandle;
288 *pfsys = &fsysconfig;
293 if(h->len == VtScoreSize)
294 return fsysroot(*pfsys, nh);
295 nh->len = h->len - VtScoreSize;
296 memmove(nh->h, h->h+VtScoreSize, nh->len);
301 handleunparse(Fsys *fsys, Nfs3Handle *h, Nfs3Handle *nh, int dotdot)
308 if(fsys == &fsysconfig)
311 if(dotdot && nh->len == h->len - VtScoreSize
312 && memcmp(h->h+VtScoreSize, nh->h, nh->len) == 0){
313 /* walked .. but didn't go anywhere: must be at root */
315 for(e=config->hash[hh]; e; e=e->nexthash)
316 if(memcmp(e->sha1, h->h, VtScoreSize) == 0)
319 return; /* cannot happen */
323 nh->len = VtScoreSize;
324 memmove(nh->h, e->sha1, VtScoreSize);
328 /* otherwise just insert the same prefix */
329 memmove(nh->h+VtScoreSize, nh->h, VtScoreSize);
330 nh->len += VtScoreSize;
331 memmove(nh->h, h->h, VtScoreSize);
335 fsysconfigroot(Fsys *fsys, Nfs3Handle *h)
339 mkhandle(h, config->root);
344 fsysconfiggetattr(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
351 if(h->len != VtScoreSize)
352 return Nfs3ErrBadHandle;
354 e = entrybyhandle(h);
358 memset(attr, 0, sizeof *attr);
359 attr->type = Nfs3FileDir;
363 attr->fileid = *(u64int*)h->h;
364 attr->atime.sec = e->time;
365 attr->mtime.sec = e->time;
366 attr->ctime.sec = e->time;
371 fsysconfigaccess(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
373 want &= Nfs3AccessRead|Nfs3AccessLookup|Nfs3AccessExecute;
375 return fsysconfiggetattr(fsys, au, h, attr);
379 fsysconfiglookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
386 if(h->len != VtScoreSize)
387 return Nfs3ErrBadHandle;
389 e = entrybyhandle(h);
393 if(strcmp(name, "..") == 0)
395 else if(strcmp(name, ".") == 0){
398 if((e = entrylookup(e, name, strlen(name))) == nil)
407 fsysconfigreadlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link)
414 return Nfs3ErrNotSupp;
418 fsysconfigreadfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
429 return Nfs3ErrNotSupp;
433 fsysconfigreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
435 uchar *data, *p, *ep, *np;
443 if(h->len != VtScoreSize)
444 return Nfs3ErrBadHandle;
446 e = entrybyhandle(h);
461 data = emalloc(count);
466 ne.namelen = strlen(e->name);
467 ne.cookie = ++cookie;
468 ne.fileid = *(u64int*)e->sha1;
469 if(nfs3entrypack(p, ep, &np, &ne) < 0)
481 fsysconfigclose(Fsys *fsys)
487 readconfig(char *name, VtCache *vcache, Nfs3Handle *h)
492 if((d = dirstat(name)) == nil)
495 c = readconfigfile(name, vcache);
506 mkhandle(h, c->root);
507 fsysconfig._lookup = fsysconfiglookup;
508 fsysconfig._access = fsysconfigaccess;
509 fsysconfig._getattr = fsysconfiggetattr;
510 fsysconfig._readdir = fsysconfigreaddir;
511 fsysconfig._readfile = fsysconfigreadfile;
512 fsysconfig._readlink = fsysconfigreadlink;
513 fsysconfig._root = fsysconfigroot;
514 fsysconfig._close = fsysconfigclose;