afsnode * afsusrdir::lookup (const str &name, sfs_aid rqaid) { if (afsnode *n = afsdir::lookup (name, aid)) return n; ptr<aclnt> ch; if (negcache[name] || !nameok (name) || !(ch = agentc ())) return NULL; ref<delaypt> dpt = delaypt::alloc (); link (dpt, name); sfs_filename lname = path ? str (path << "/" << name) : name; ref<sfsagent_lookup_res> resp = New refcounted<sfsagent_lookup_res>; ch->timedcall (agent_timeout, AGENTCB_LOOKUP, &lname, resp, wrap (mkref (this), &afsusrdir::lookup_cb, name, dpt, resp)); return dpt; }
void afsusrdir::nfs_mkdir (svccb *sbp) { str name = sbp->vers () == 2 ? str (sbp->Xtmpl getarg<createargs> ()->where.name) : str (sbp->Xtmpl getarg<mkdir3args> ()->where.name); if (entries[name]) { nfs_error (sbp, NFSERR_EXIST); return; } if (!nameok (name)) { nfs_error (sbp, nfsstat (NFSERR_ACCES)); return; } clrulink (name); ptr<afsnode> e = mkdir (name); dirop_reply (sbp, e); }
Arena* newarena(Part *part, uint32_t vers, char *name, uint64_t base, uint64_t size, uint32_t blocksize) { int bsize; Arena *arena; if(nameok(name) < 0){ seterr(EOk, "illegal arena name", name); return nil; } arena = MKZ(Arena); arena->part = part; arena->version = vers; if(vers == ArenaVersion4) arena->clumpmagic = _ClumpMagic; else{ do arena->clumpmagic = fastrand(); while(arena->clumpmagic==_ClumpMagic || arena->clumpmagic==0); } arena->blocksize = blocksize; arena->clumpmax = arena->blocksize / ClumpInfoSize; arena->base = base + blocksize; arena->size = size - 2 * blocksize; namecp(arena->name, name); bsize = sizeof zero; if(bsize > arena->blocksize) bsize = arena->blocksize; if(wbarena(arena)<0 || wbarenahead(arena)<0 || writepart(arena->part, arena->base, zero, bsize)<0){ freearena(arena); return nil; } return arena; }
void afsusrdir::nfs_remove (svccb *sbp) { if (!chkaid (sbp)) return; str name = sbp->vers () == 2 ? str (sbp->Xtmpl getarg<diropargs> ()->name) : str (sbp->Xtmpl getarg<diropargs3> ()->name); if (!entries[name]) nfs_error (sbp, NFSERR_NOENT); else if (!nameok (name) && !sfs_parsepath (name)) nfs_error (sbp, NFSERR_ACCES); else { clrulink (name); if (sbp->vers () == 2) sbp->replyref (NFS_OK); else sbp->replyref (wccstat3 (NFS3_OK)); } }
bool afsusrdir::mkulink (const str &path, const str &name) { if (!nameok (name)) return false; unlink (name); if (path && path.len ()) { negcache.remove (name); if (nentries < maxulinks) symlink (path, name); else { // XXX - what to do? warn ("afsusrdir: maxulinks exceeded\n"); return false; } } else { if (negcache.size () >= maxulinks) // XXX - this is kind of low-tech negcache.clear (); negcache.insert (name); } return true; }
void threadmain(int argc, char *argv[]) { int vers; ArenaPart *ap; Part *part; Arena *arena; uint64_t addr, limit, asize, apsize; char *file, *name, aname[ANameSize]; int i, n, blocksize, tabsize, zero; ventifmtinstall(); statsinit(); blocksize = 8 * 1024; asize = 512 * 1024 *1024; tabsize = 512 * 1024; /* BUG: should be determine from number of arenas */ zero = -1; vers = ArenaVersion5; ARGBEGIN{ case 'D': settrace(EARGF(usage())); break; case 'a': asize = unittoull(EARGF(usage())); if(asize == TWID64) usage(); break; case 'b': blocksize = unittoull(EARGF(usage())); if(blocksize == ~0) usage(); if(blocksize > MaxDiskBlock){ fprint(2, "block size too large, max %d\n", MaxDiskBlock); threadexitsall("usage"); } break; case '4': vers = ArenaVersion4; break; case 'Z': zero = 0; break; default: usage(); break; }ARGEND if(zero == -1){ if(vers == ArenaVersion4) zero = 1; else zero = 0; } if(argc != 2) usage(); name = argv[0]; file = argv[1]; if(nameok(name) < 0) sysfatal("illegal name template %s", name); part = initpart(file, ORDWR|ODIRECT); if(part == nil) sysfatal("can't open partition %s: %r", file); if(zero) zeropart(part, blocksize); maxblocksize = blocksize; initdcache(20*blocksize); ap = newarenapart(part, blocksize, tabsize); if(ap == nil) sysfatal("can't initialize arena: %r"); apsize = ap->size - ap->arenabase; n = apsize / asize; if(apsize - (n * asize) >= MinArenaSize) n++; fprint(2, "fmtarenas %s: %,d arenas, %,lld bytes storage, %,d bytes for index map\n", file, n, apsize, ap->tabsize); ap->narenas = n; ap->map = MKNZ(AMap, n); ap->arenas = MKNZ(Arena*, n); addr = ap->arenabase; for(i = 0; i < n; i++){ limit = addr + asize; if(limit >= ap->size || ap->size - limit < MinArenaSize){ limit = ap->size; if(limit - addr < MinArenaSize) sysfatal("bad arena set math: runt arena at %lld,%lld %lld", addr, limit, ap->size); } snprint(aname, ANameSize, "%s%d", name, i); if(0) fprint(2, "adding arena %s at [%lld,%lld)\n", aname, addr, limit); arena = newarena(part, vers, aname, addr, limit - addr, blocksize); if(!arena) fprint(2, "can't make new arena %s: %r", aname); freearena(arena); ap->map[i].start = addr; ap->map[i].stop = limit; namecp(ap->map[i].name, aname); addr = limit; } if(wbarenapart(ap) < 0) fprint(2, "can't write back arena partition header for %s: %r\n", file); flushdcache(); threadexitsall(0); }
int main(int argc, char *argv[]) { struct dirent *dirent; DIR *dir; unsigned long that, next, now; #ifdef DAEMON if (argc != 2) { fprintf(stderr, "usage: atd spooldir\n"); exit(2); } { int pid; pid = fork(); if (pid > 0) { exit(0); } else if (pid < 0) { exit(-1); } } if (setsid() == -1) { exit(-1); } close(0); close(1); close(2); openlog("atd", LOG_PID, LOG_DAEMON); #else if (argc != 2) die("usage: atd spooldir"); #endif if (chdir(argv[1]) < 0) die("cannot chdir"); if (mkfifo("trigger.new", 0777) < 0) die("cannot mkfifo trigger.new"); if (rename("trigger.new","trigger")) die("cannot rename trigger.new"); enable_rtc_wakeup(); while(1) { /* run all the jobs in the past */ now = time(NULL); dir = opendir("."); while ((dirent = readdir(dir))) { that = nameok(dirent->d_name); /* run jobs which are in the past, and find the next job in the future */ /* avoid race conditions. Run jobs scheduled for the next second now */ if (that) if (that <= now + 1) runjob(dirent->d_name); } closedir(dir); /* find the next job in the future. A job we just ran might have * rescheduled itself. */ dir = opendir("."); next = ULONG_MAX; while ((dirent = readdir(dir))) { that = nameok(dirent->d_name); /* schedule jobs that we haven't just run */ if (that) if (that > now + 1) if (that < next) next = that; } closedir(dir); #ifdef DAEMON syslog(LOG_DEBUG, "next: %ld\n", next); #else printf("next: %ld\n", next); #endif if (next == ULONG_MAX) next = 0; waitfor(next); } #ifdef DAEMON closelog(); #endif return 0; }
void threadmain(int argc, char *argv[]) { int vers; ISect *is; Part *part; char *file, *name; int blocksize, setsize, zero; ventifmtinstall(); statsinit(); blocksize = 8 * 1024; setsize = 512 * 1024; zero = -1; vers = ISectVersion2; ARGBEGIN{ case 'b': blocksize = unittoull(ARGF()); if(blocksize == ~0) usage(); if(blocksize > MaxDiskBlock){ fprint(2, "block size too large, max %d\n", MaxDiskBlock); threadexitsall("usage"); } break; case '1': vers = ISectVersion1; break; case 'Z': zero = 0; break; default: usage(); break; }ARGEND if(zero == -1){ if(vers == ISectVersion1) zero = 1; else zero = 0; } if(argc != 2) usage(); name = argv[0]; file = argv[1]; if(nameok(name) < 0) sysfatal("illegal name %s", name); part = initpart(file, ORDWR|ODIRECT); if(part == nil) sysfatal("can't open partition %s: %r", file); if(zero) zeropart(part, blocksize); is = newisect(part, vers, name, blocksize, setsize); if(is == nil) sysfatal("can't initialize new index: %r"); fprint(2, "fmtisect %s: %,d buckets of %,d entries, %,d bytes for index map\n", file, is->blocks, is->buckmax, setsize); if(wbisect(is) < 0) fprint(2, "can't write back index section header for %s: %r\n", file); threadexitsall(0); }