⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -