📄 nfs.c
字号:
/* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */#include <u.h>#include <libc.h>#include <bio.h>#include <fcall.h>#include <thread.h>#include <9p.h>#include <sunrpc.h>#include <nfs3.h>SunClient *nfscli;SunClient *mntcli;char *defaultpath = "/";Channel *fschan;char *sys;int verbose;int readplus = 0;typedef struct Auth Auth;struct Auth{ int ref; uchar *data; int ndata;};typedef struct FidAux FidAux;struct FidAux{ Nfs3Handle handle; u64int cookie; /* for continuing directory reads */ char *name; /* botch: for remove and rename */ Nfs3Handle parent; /* botch: for remove and rename */ char err[ERRMAX]; /* for walk1 */ Auth *auth;};/* * various RPCs. here is where we'd insert support for NFS v2 */voidportCall(SunCall *c, PortCallType type){ c->rpc.prog = PortProgram; c->rpc.vers = PortVersion; c->rpc.proc = type>>1; c->rpc.iscall = !(type&1); c->type = type;}intgetport(SunClient *client, uint prog, uint vers, uint prot, uint *port){ PortTGetport tx; PortRGetport rx; memset(&tx, 0, sizeof tx); portCall(&tx.call, PortCallTGetport); tx.map.prog = prog; tx.map.vers = vers; tx.map.prot = prot; memset(&rx, 0, sizeof rx); portCall(&rx.call, PortCallRGetport); if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) return -1; *port = rx.port; return 0;}voidmountCall(Auth *a, SunCall *c, NfsMount3CallType type){ c->rpc.iscall = !(type&1); c->rpc.proc = type>>1; c->rpc.prog = NfsMount3Program; c->rpc.vers = NfsMount3Version; if(c->rpc.iscall && a){ c->rpc.cred.flavor = SunAuthSys; c->rpc.cred.data = a->data; c->rpc.cred.ndata = a->ndata; } c->type = type;}intmountNull(ulong tag){ NfsMount3TNull tx; NfsMount3RNull rx; memset(&tx, 0, sizeof tx); mountCall(nil, &tx.call, NfsMount3CallTNull); memset(&rx, 0, sizeof rx); mountCall(nil, &rx.call, NfsMount3CallTNull); return sunClientRpc(mntcli, tag, &tx.call, &rx.call, nil);}intmountMnt(Auth *a, ulong tag, char *path, Nfs3Handle *h){ uchar *freeme; NfsMount3TMnt tx; NfsMount3RMnt rx; memset(&tx, 0, sizeof tx); mountCall(a, &tx.call, NfsMount3CallTMnt); tx.path = path; memset(&rx, 0, sizeof rx); mountCall(a, &rx.call, NfsMount3CallRMnt); if(sunClientRpc(mntcli, tag, &tx.call, &rx.call, &freeme) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; }if(verbose)print("handle %.*H\n", rx.len, rx.handle); if(rx.len >= Nfs3MaxHandleSize){ free(freeme); werrstr("server-returned handle too long"); return -1; } memmove(h->h, rx.handle, rx.len); h->len = rx.len; free(freeme); return 0;}voidnfs3Call(Auth *a, SunCall *c, Nfs3CallType type){ c->rpc.iscall = !(type&1); c->rpc.proc = type>>1; c->rpc.prog = Nfs3Program; c->rpc.vers = Nfs3Version; if(c->rpc.iscall && a){ c->rpc.cred.flavor = SunAuthSys; c->rpc.cred.data = a->data; c->rpc.cred.ndata = a->ndata; } c->type = type;}intnfsNull(ulong tag){ Nfs3TNull tx; Nfs3RNull rx; memset(&tx, 0, sizeof tx); nfs3Call(nil, &tx.call, Nfs3CallTNull); memset(&rx, 0, sizeof rx); nfs3Call(nil, &rx.call, Nfs3CallTNull); return sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil);}intnfsGetattr(Auth *a, ulong tag, Nfs3Handle *h, Nfs3Attr *attr){ Nfs3TGetattr tx; Nfs3RGetattr rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTGetattr); tx.handle = *h; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRGetattr); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } *attr = rx.attr; return 0;}intnfsAccess(Auth *a, ulong tag, Nfs3Handle *h, ulong want, ulong *got, u1int *have, Nfs3Attr *attr){ Nfs3TAccess tx; Nfs3RAccess rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTAccess); tx.handle = *h; tx.access = want; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRAccess); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } *got = rx.access; *have = rx.haveAttr; if(rx.haveAttr) *attr = rx.attr; return 0;}intnfsMkdir(Auth *a, ulong tag, Nfs3Handle *h, char *name, Nfs3Handle *nh, ulong mode, uint gid, u1int *have, Nfs3Attr *attr){ Nfs3TMkdir tx; Nfs3RMkdir rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTMkdir); tx.handle = *h; tx.name = name; tx.attr.setMode = 1; tx.attr.mode = mode; tx.attr.setGid = 1; tx.attr.gid = gid; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRMkdir); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } if(!rx.haveHandle){ werrstr("nfs mkdir did not return handle"); return -1; } *nh = rx.handle; *have = rx.haveAttr; if(rx.haveAttr) *attr = rx.attr; return 0;}intnfsCreate(Auth *a, ulong tag, Nfs3Handle *h, char *name, Nfs3Handle *nh, ulong mode, uint gid, u1int *have, Nfs3Attr *attr){ Nfs3TCreate tx; Nfs3RCreate rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTCreate); tx.handle = *h; tx.name = name; tx.attr.setMode = 1; tx.attr.mode = mode; tx.attr.setGid = 1; tx.attr.gid = gid; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRCreate); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } if(!rx.haveHandle){ werrstr("nfs create did not return handle"); return -1; } *nh = rx.handle; *have = rx.haveAttr; if(rx.haveAttr) *attr = rx.attr; return 0;}intnfsRead(Auth *a, ulong tag, Nfs3Handle *h, u32int count, u64int offset, uchar **pp, u32int *pcount, uchar **pfreeme){ uchar *freeme; Nfs3TRead tx; Nfs3RRead rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTRead); tx.handle = *h; tx.count = count; tx.offset = offset; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRRead); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, &freeme) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } if(rx.count != rx.ndata){ werrstr("nfs read returned count=%ud ndata=%ud", (uint)rx.count, (uint)rx.ndata); free(freeme); return -1; } *pfreeme = freeme; *pcount = rx.count; *pp = rx.data; return 0;}intnfsWrite(Auth *a, ulong tag, Nfs3Handle *h, uchar *data, u32int count, u64int offset, u32int *pcount){ Nfs3TWrite tx; Nfs3RWrite rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTWrite); tx.handle = *h; tx.count = count; tx.offset = offset; tx.data = data; tx.ndata = count; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRWrite); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } *pcount = rx.count; return 0;}intnfsRmdir(Auth *a, ulong tag, Nfs3Handle *h, char *name){ Nfs3TRmdir tx; Nfs3RRmdir rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTRmdir); tx.handle = *h; tx.name = name; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRRmdir); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } return 0;}intnfsRemove(Auth *a, ulong tag, Nfs3Handle *h, char *name){ Nfs3TRemove tx; Nfs3RRemove rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTRemove); tx.handle = *h; tx.name = name; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRRemove); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } return 0;}intnfsRename(Auth *a, ulong tag, Nfs3Handle *h, char *name, Nfs3Handle *th, char *tname){ Nfs3TRename tx; Nfs3RRename rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTRename); tx.from.handle = *h; tx.from.name = name; tx.to.handle = *th; tx.to.name = tname; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRRename); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } return 0;}intnfsSetattr(Auth *a, ulong tag, Nfs3Handle *h, Nfs3SetAttr *attr){ Nfs3TSetattr tx; Nfs3RSetattr rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTSetattr); tx.handle = *h; tx.attr = *attr; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRSetattr); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } return 0;}intnfsCommit(Auth *a, ulong tag, Nfs3Handle *h){ Nfs3TCommit tx; Nfs3RCommit rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTCommit); tx.handle = *h; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRCommit); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } return 0;}intnfsLookup(Auth *a, ulong tag, Nfs3Handle *h, char *name, Nfs3Handle *nh, u1int *have, Nfs3Attr *attr){ Nfs3TLookup tx; Nfs3RLookup rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTLookup); tx.handle = *h; tx.name = name; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRLookup); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, nil) < 0) return -1; if(rx.status != Nfs3Ok){ nfs3Errstr(rx.status); return -1; } *nh = rx.handle; *have = rx.haveAttr; if(rx.haveAttr) *attr = rx.attr; return 0;}intnfsReadDirPlus(Auth *a, ulong tag, Nfs3Handle *h, u32int count, u64int cookie, uchar **pp, u32int *pcount, int (**unpack)(uchar*, uchar*, uchar**, Nfs3Entry*), uchar **pfreeme){ Nfs3TReadDirPlus tx; Nfs3RReadDirPlus rx; memset(&tx, 0, sizeof tx); nfs3Call(a, &tx.call, Nfs3CallTReadDirPlus); tx.handle = *h; tx.maxCount = count; tx.dirCount = 1000; tx.cookie = cookie; memset(&rx, 0, sizeof rx); nfs3Call(a, &rx.call, Nfs3CallRReadDirPlus); if(sunClientRpc(nfscli, tag, &tx.call, &rx.call, pfreeme) < 0) return -1; if(rx.status != Nfs3Ok){ free(*pfreeme); *pfreeme = 0; nfs3Errstr(rx.status); return -1; } *unpack = nfs3EntryPlusUnpack; *pcount = rx.count; *pp = rx.data; return 0;}intnfsReadDir(Auth *a, ulong tag, Nfs3Handle *h, u32int count, u64int cookie, uchar **pp, u32int *pcount, int (**unpack)(uchar*, uchar*, uchar**, Nfs3Entry*), uchar **pfreeme){ /* BUG: try readdirplus */ char e[ERRMAX]; Nfs3TReadDir tx; Nfs3RReadDir rx; if(readplus!=-1){ if(nfsReadDirPlus(a, tag, h, count, cookie, pp, pcount, unpack, pfreeme) == 0){ readplus = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -