📄 9fsys.c
字号:
goto error; } vtMemFree(de.elem); de.elem = vtStrDup(argv[1]); } if(strcmp(argv[2], "-") != 0){ if(!validUserName(argv[2])){ vtSetError("console wstat - bad uid"); goto error; } vtMemFree(de.uid); de.uid = vtStrDup(argv[2]); } if(strcmp(argv[3], "-") != 0){ if(!validUserName(argv[3])){ vtSetError("console wstat - bad gid"); goto error; } vtMemFree(de.gid); de.gid = vtStrDup(argv[3]); } if(strcmp(argv[4], "-") != 0){ if(!fsysParseMode(argv[4], &de.mode)){ vtSetError("console wstat - bad mode"); goto error; } } if(strcmp(argv[5], "-") != 0){ de.size = strtoull(argv[5], &p, 0); if(argv[5][0] == '\0' || *p != '\0' || (vlong)de.size < 0){ vtSetError("console wstat - bad length"); goto error; } } if(!fileSetDir(f, &de, uidadm)){ vtSetError("console wstat - %R"); goto error; } deCleanup(&de); if(!fileGetDir(f, &de)){ vtSetError("console wstat - stat2 - %R"); goto error; } fsysPrintStat("\tnew: w", argv[0], &de); deCleanup(&de); fileDecRef(f); vtRUnlock(fsys->fs->elk); return 1;error: deCleanup(&de); /* okay to do this twice */ fileDecRef(f); vtRUnlock(fsys->fs->elk); return 0;}static voidfsckClri(Fsck *fsck, char *name, MetaBlock *mb, int i, Block *b){ USED(name); if((fsck->flags&DoClri) == 0) return; mbDelete(mb, i); mbPack(mb); blockDirty(b); }static voidfsckClose(Fsck *fsck, Block *b, u32int epoch){ Label l; if((fsck->flags&DoClose) == 0) return; l = b->l; if(l.state == BsFree || (l.state&BsClosed)){ consPrint("%#ux is already closed\n", b->addr); return; } if(epoch){ l.state |= BsClosed; l.epochClose = epoch; }else l.state = BsFree; if(!blockSetLabel(b, &l, 0)) consPrint("%#ux setlabel: %R\n", b->addr);}static voidfsckClre(Fsck *fsck, Block *b, int offset){ Entry e; if((fsck->flags&DoClre) == 0) return; if(offset<0 || offset*VtEntrySize >= fsck->bsize){ consPrint("bad clre\n"); return; } memset(&e, 0, sizeof e); entryPack(&e, b->data, offset); blockDirty(b);}static voidfsckClrp(Fsck *fsck, Block *b, int offset){ if((fsck->flags&DoClrp) == 0) return; if(offset<0 || offset*VtScoreSize >= fsck->bsize){ consPrint("bad clre\n"); return; } memmove(b->data+offset*VtScoreSize, vtZeroScore, VtScoreSize); blockDirty(b);}static intfsysCheck(Fsys *fsys, int argc, char *argv[]){ int i, halting; char *usage = "usage: [fsys name] check [-v] [options]"; Fsck fsck; Block *b; Super super; memset(&fsck, 0, sizeof fsck); fsck.fs = fsys->fs; fsck.clri = fsckClri; fsck.clre = fsckClre; fsck.clrp = fsckClrp; fsck.close = fsckClose; fsck.print = consPrint; ARGBEGIN{ default: return cliError(usage); }ARGEND for(i=0; i<argc; i++){ if(strcmp(argv[i], "pblock") == 0) fsck.printblocks = 1; else if(strcmp(argv[i], "pdir") == 0) fsck.printdirs = 1; else if(strcmp(argv[i], "pfile") == 0) fsck.printfiles = 1; else if(strcmp(argv[i], "bclose") == 0) fsck.flags |= DoClose; else if(strcmp(argv[i], "clri") == 0) fsck.flags |= DoClri; else if(strcmp(argv[i], "clre") == 0) fsck.flags |= DoClre; else if(strcmp(argv[i], "clrp") == 0) fsck.flags |= DoClrp; else if(strcmp(argv[i], "fix") == 0) fsck.flags |= DoClose|DoClri|DoClre|DoClrp; else if(strcmp(argv[i], "venti") == 0) fsck.useventi = 1; else if(strcmp(argv[i], "snapshot") == 0) fsck.walksnapshots = 1; else{ consPrint("unknown option '%s'\n", argv[i]); return cliError(usage); } } halting = fsys->fs->halted==0; if(halting) fsHalt(fsys->fs); if(fsys->fs->arch){ b = superGet(fsys->fs->cache, &super); if(b == nil){ consPrint("could not load super block\n"); goto Out; } blockPut(b); if(super.current != NilBlock){ consPrint("cannot check fs while archiver is running; wait for it to finish\n"); goto Out; } } fsCheck(&fsck); consPrint("fsck: %d clri, %d clre, %d clrp, %d bclose\n", fsck.nclri, fsck.nclre, fsck.nclrp, fsck.nclose);Out: if(halting) fsUnhalt(fsys->fs); return 1;}static intfsysVenti(char* name, int argc, char* argv[]){ int r; char *host; char *usage = "usage: [fsys name] venti [address]"; Fsys *fsys; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc == 0) host = nil; else if(argc == 1) host = argv[0]; else return cliError(usage); if((fsys = _fsysGet(name)) == nil) return 0; vtLock(fsys->lock); if(host == nil) host = fsys->venti; else{ vtMemFree(fsys->venti); if(host[0]) fsys->venti = vtStrDup(host); else{ host = nil; fsys->venti = nil; } } /* already open: do a redial */ if(fsys->fs != nil){ if(fsys->session == nil){ vtSetError("file system was opened with -V"); r = 0; goto out; } r = 1; if(!vtRedial(fsys->session, host) || !vtConnect(fsys->session, 0)) r = 0; goto out; } /* not yet open: try to dial */ if(fsys->session) vtClose(fsys->session); r = 1; if((fsys->session = vtDial(host, 0)) == nil || !vtConnect(fsys->session, 0)) r = 0;out: vtUnlock(fsys->lock); fsysPut(fsys); return r;}static intfsysOpen(char* name, int argc, char* argv[]){ char *p, *host; Fsys *fsys; long ncache; int noauth, noventi, noperm, rflag, wstatallow; char *usage = "usage: fsys name open [-APVWr] [-c ncache]"; ncache = 1000; noauth = noperm = wstatallow = noventi = 0; rflag = OReadWrite; ARGBEGIN{ default: return cliError(usage); case 'A': noauth = 1; break; case 'P': noperm = 1; break; case 'V': noventi = 1; break; case 'W': wstatallow = 1; break; case 'c': p = ARGF(); if(p == nil) return cliError(usage); ncache = strtol(argv[0], &p, 0); if(ncache <= 0 || p == argv[0] || *p != '\0') return cliError(usage); break; case 'r': rflag = OReadOnly; break; }ARGEND if(argc) return cliError(usage); if((fsys = _fsysGet(name)) == nil) return 0; vtLock(fsys->lock); if(fsys->fs != nil){ vtSetError(EFsysBusy, fsys->name); vtUnlock(fsys->lock); fsysPut(fsys); return 0; } if(noventi){ if(fsys->session){ vtClose(fsys->session); fsys->session = nil; } } else if(fsys->session == nil){ if(fsys->venti && fsys->venti[0]) host = fsys->venti; else host = nil; fsys->session = vtDial(host, 1); if(!vtConnect(fsys->session, nil) && !noventi) fprint(2, "warning: connecting to venti: %R\n"); } if((fsys->fs = fsOpen(fsys->dev, fsys->session, ncache, rflag)) == nil){ vtSetError("fsOpen: %R"); vtUnlock(fsys->lock); fsysPut(fsys); return 0; } fsys->noauth = noauth; fsys->noperm = noperm; fsys->wstatallow = wstatallow; vtUnlock(fsys->lock); fsysPut(fsys); if(strcmp(name, "main") == 0) usersFileRead(nil); return 1;}static intfsysUnconfig(char* name, int argc, char* argv[]){ Fsys *fsys, **fp; char *usage = "usage: fsys name unconfig"; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc) return cliError(usage); vtLock(sbox.lock); fp = &sbox.head; for(fsys = *fp; fsys != nil; fsys = fsys->next){ if(strcmp(fsys->name, name) == 0) break; fp = &fsys->next; } if(fsys == nil){ vtSetError(EFsysNotFound, name); vtUnlock(sbox.lock); return 0; } if(fsys->ref != 0 || fsys->fs != nil){ vtSetError(EFsysBusy, fsys->name); vtUnlock(sbox.lock); return 0; } *fp = fsys->next; vtUnlock(sbox.lock); if(fsys->session != nil){ vtClose(fsys->session); vtFree(fsys->session); } if(fsys->venti != nil) vtMemFree(fsys->venti); if(fsys->dev != nil) vtMemFree(fsys->dev); if(fsys->name != nil) vtMemFree(fsys->name); vtMemFree(fsys); return 1;}static intfsysConfig(char* name, int argc, char* argv[]){ Fsys *fsys; char *usage = "usage: fsys name config dev"; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc != 1) return cliError(usage); if((fsys = _fsysGet(argv[0])) != nil){ vtLock(fsys->lock); if(fsys->fs != nil){ vtSetError(EFsysBusy, fsys->name); vtUnlock(fsys->lock); fsysPut(fsys); return 0; } vtMemFree(fsys->dev); fsys->dev = vtStrDup(argv[0]); vtUnlock(fsys->lock); } else if((fsys = fsysAlloc(name, argv[0])) == nil) return 0; fsysPut(fsys); return 1;}static struct { char* cmd; int (*f)(Fsys*, int, char**); int (*f1)(char*, int, char**);} fsyscmd[] = { { "close", fsysClose, }, { "config", nil, fsysConfig, }, { "open", nil, fsysOpen, }, { "unconfig", nil, fsysUnconfig, }, { "venti", nil, fsysVenti, }, { "bfree", fsysBfree, }, { "block", fsysBlock, }, { "check", fsysCheck, }, { "clre", fsysClre, }, { "clri", fsysClri, }, { "clrp", fsysClrp, }, { "create", fsysCreate, }, { "df", fsysDf, }, { "epoch", fsysEpoch, }, { "halt", fsysHalt, }, { "label", fsysLabel, }, { "remove", fsysRemove, }, { "snap", fsysSnap, }, { "snaptime", fsysSnapTime, }, { "snapclean", fsysSnapClean, }, { "stat", fsysStat, }, { "sync", fsysSync, }, { "unhalt", fsysUnhalt, }, { "wstat", fsysWstat, }, { "vac", fsysVac, }, { nil, nil, },};static intfsysXXX1(Fsys *fsys, int i, int argc, char* argv[]){ int r; vtLock(fsys->lock); if(fsys->fs == nil){ vtUnlock(fsys->lock); vtSetError(EFsysNotOpen, fsys->name); return 0; } if(fsys->fs->halted && fsyscmd[i].f != fsysUnhalt && fsyscmd[i].f != fsysCheck){ vtSetError("file system %s is halted", fsys->name); vtUnlock(fsys->lock); return 0; } r = (*fsyscmd[i].f)(fsys, argc, argv); vtUnlock(fsys->lock); return r;}static intfsysXXX(char* name, int argc, char* argv[]){ int i, r; Fsys *fsys; for(i = 0; fsyscmd[i].cmd != nil; i++){ if(strcmp(fsyscmd[i].cmd, argv[0]) == 0) break; } if(fsyscmd[i].cmd == nil){ vtSetError("unknown command - '%s'", argv[0]); return 0; } /* some commands want the name... */ if(fsyscmd[i].f1 != nil){ if(strcmp(name, FsysAll) == 0){ vtSetError("cannot use fsys %#q with %#q command", FsysAll, argv[0]); return 0; } return (*fsyscmd[i].f1)(name, argc, argv); } /* ... but most commands want the Fsys */ if(strcmp(name, FsysAll) == 0){ r = 1; vtRLock(sbox.lock); for(fsys = sbox.head; fsys != nil; fsys = fsys->next){ fsys->ref++; r = fsysXXX1(fsys, i, argc, argv) && r; fsys->ref--; } vtRUnlock(sbox.lock); }else{ if((fsys = _fsysGet(name)) == nil) return 0; r = fsysXXX1(fsys, i, argc, argv); fsysPut(fsys); } return r;}static intcmdFsysXXX(int argc, char* argv[]){ char *name; if((name = sbox.curfsys) == nil){ vtSetError(EFsysNoCurrent, argv[0]); return 0; } return fsysXXX(name, argc, argv);}static intcmdFsys(int argc, char* argv[]){ Fsys *fsys; char *usage = "usage: fsys [name ...]"; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc == 0){ vtRLock(sbox.lock); for(fsys = sbox.head; fsys != nil; fsys = fsys->next) consPrint("\t%s\n", fsys->name); vtRUnlock(sbox.lock); return 1; } if(argc == 1){ fsys = nil; if(strcmp(argv[0], FsysAll) != 0 && (fsys = fsysGet(argv[0])) == nil) return 0; sbox.curfsys = vtStrDup(argv[0]); consPrompt(sbox.curfsys); if(fsys) fsysPut(fsys); return 1; } return fsysXXX(argv[0], argc-1, argv+1);}intfsysInit(void){ int i; fmtinstall('H', encodefmt); fmtinstall('V', scoreFmt); fmtinstall('R', vtErrFmt); fmtinstall('L', labelFmt); sbox.lock = vtLockAlloc(); cliAddCmd("fsys", cmdFsys); for(i = 0; fsyscmd[i].cmd != nil; i++){ if(fsyscmd[i].f != nil) cliAddCmd(fsyscmd[i].cmd, cmdFsysXXX); } /* the venti cmd is special: the fs can be either open or closed */ cliAddCmd("venti", cmdFsysXXX); cliAddCmd("printconfig", cmdPrintConfig); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -