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

📄 nfs_server.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	dr->dr_status = puterrno(error);	grele(vp);	return(0);}/* * Remove a directory. * Remove the given directory name from the given parent directory. */intrfs_rmdir(da, status, req, xprt, xpd)	struct nfsdiropargs *da;	enum nfsstat *status;	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	register struct vnode *vp;	struct timeval duptime;	int dupmark;	vp = fhtovp(&da->da_fhandle, xprt, RFS_RMDIR, xpd);	if (vp == NULL) {		*status = NFSERR_STALE;		return(ESTALE);	}	if (rdonly(vp, xpd)) {		gfs_unlock(vp);		error = EROFS;	} else {		if (svckudp_dup(req, &duptime, &dupmark) &&			duptime.tv_sec == vp->g_ctime.tv_sec &&			duptime.tv_usec == vp->g_ctime.tv_usec) {				++nfs_dupstats.rmdirs;				gfs_unlock(vp);		}		else {			error = VOP_RMDIR(vp, da->da_name, u.u_cred);		}		if (error) {			svckudp_dupsave(req, *timepick, DUP_FAIL);		} else {			svckudp_dupsave(req, vp->g_ctime, DUP_DONE);		}	}	*status = puterrno(error);	grele(vp);	return(0);}intrfs_readdir(rda, rd, req, xprt, xpd)	struct nfsrddirargs *rda;	register struct nfsrddirres  *rd;	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	register u_long offset;	register u_long skipped;	register struct vnode *vp;	register struct direct *dp;	struct iovec iov;	struct uio uio;	vp = fhtovp(&rda->rda_fh, xprt, RFS_READDIR, xpd);	if (vp == NULL) {		rd->rd_status = NFSERR_STALE;		return(ESTALE);	}	/*	 * check cd access to dir.  we have to do this here because	 * the opendir doesn't go over the wire.	 */	error = VOP_ACCESS(vp, VEXEC, u.u_cred);	if (error) {		goto bad;	}	/*	 * Allocate data for entries.  This will be freed by rfs_rdfree.	 */	rd->rd_bufallocsize = rd->rd_bufsize = rda->rda_count;	kmem_alloc(rd->rd_bufallocaddr, char *, rda->rda_count, KM_NFS);	rd->rd_entries = (struct direct *)rd->rd_bufallocaddr;nxtblk:	rd->rd_offset = rda->rda_offset & ~(DIRBLKSIZ -1);	/*	 * Set up io vector to read directory data	 */	iov.iov_base = (caddr_t)rd->rd_bufallocaddr;	iov.iov_len = rda->rda_count;	uio.uio_iov = &iov;	uio.uio_iovcnt = 1;	uio.uio_segflg = UIO_SYSSPACE;	uio.uio_offset = rd->rd_offset;	uio.uio_resid = rda->rda_count;	/*	 * read directory	 */	error = VOP_READDIR(vp, &uio, u.u_cred);	/*	 * Clean up	 */	if (error) {			rd->rd_size = 0;		goto bad;	}	/*	 * set size and eof	 */	if (uio.uio_resid) {		rd->rd_size = rda->rda_count - uio.uio_resid;		rd->rd_eof = TRUE;	} else {		rd->rd_size = rda->rda_count;		rd->rd_eof = FALSE;	}	/*	 * if client request was in the middle of a block	 * or block begins with null entries skip entries	 * til we are on a valid entry >= client's requested	 * offset.	 */	dp = rd->rd_entries;	offset = rd->rd_offset;	skipped = 0;	while ((skipped < rd->rd_size) &&	    ((offset + dp->d_reclen <= rda->rda_offset) || (dp->d_ino == 0))) {		skipped += dp->d_reclen;		offset += dp->d_reclen;		dp = (struct direct *)((int)dp + dp->d_reclen);	}	/*	 * Reset entries pointer	 */	if (skipped) {		rd->rd_size -= skipped;		if (rd->rd_size == 0 && !rd->rd_eof) {			/*			 * we have skipped a whole block, reset offset			 * and read another block (unless eof)			 */			rda->rda_offset = offset;			goto nxtblk;		}		rd->rd_bufsize -= skipped;		rd->rd_offset = offset;		rd->rd_entries = dp;	}bad:	rd->rd_status = puterrno(error);	gput(vp);	return(0);}rfs_rddirfree(rd)	struct nfsrddirres *rd;{	if (rd->rd_bufallocaddr)		kmem_free(rd->rd_bufallocaddr, KM_NFS);}rfs_statfs(fh, fs, req, xprt, xpd)	fhandle_t *fh;	register struct nfsstatfs *fs;	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register struct gnode *gp;	struct fs_data *fsd;	gp = (struct gnode *)fhtovp(fh, xprt, RFS_STATFS, xpd);	if (gp == NULL) {		fs->fs_status = NFSERR_STALE;		return(ESTALE);	}	fsd = GGETFSDATA(gp->g_mp);	fs->fs_tsize = nfstsize();	fs->fsstat_bsize = FSDUNIT;	fs->fs_blocks = fsd->fd_btot;	fs->fs_bfree = fsd->fd_bfree;	fs->fs_bavail = fsd->fd_bfreen;	gput(gp);	return(0);}/*ARGSUSED*/rfs_null(argp, resp)	caddr_t *argp;	caddr_t *resp;{	/* do nothing */	return (0);}/*ARGSUSED*/rfs_error(argp, resp)	caddr_t *argp;	caddr_t *resp;{	return (EOPNOTSUPP);}intnullfree(){}/* * rfs dispatch table * Indexed by version,proc */struct rfsdisp {	int	  (*dis_proc)();	/* proc to call */	xdrproc_t dis_xdrargs;		/* xdr routine to get args */	int	  dis_argsz;		/* sizeof args */	xdrproc_t dis_xdrres;		/* xdr routine to put results */	int	  dis_ressz;		/* size of results */	int	  (*dis_resfree)();	/* frees space allocated by proc */} rfsdisptab[][RFS_NPROC]  = {	{	/*	 * VERSION 2	 * Changed rddirres to have eof at end instead of beginning	 */	/* RFS_NULL = 0 */	{rfs_null, xdr_void, 0,	    xdr_void, 0, nullfree},	/* RFS_GETATTR = 1 */	{rfs_getattr, xdr_fhandle, sizeof(fhandle_t),	    xdr_attrstat, sizeof(struct nfsattrstat), nullfree},	/* RFS_SETATTR = 2 */	{rfs_setattr, xdr_saargs, sizeof(struct nfssaargs),	    xdr_attrstat, sizeof(struct nfsattrstat), nullfree},	/* RFS_ROOT = 3 *** NO LONGER SUPPORTED *** */	{rfs_error, xdr_void, 0,	    xdr_void, 0, nullfree},	/* RFS_LOOKUP = 4 */	{rfs_lookup, xdr_diropargs, sizeof(struct nfsdiropargs),	    xdr_diropres, sizeof(struct nfsdiropres), nullfree},	/* RFS_READLINK = 5 */	{rfs_readlink, xdr_fhandle, sizeof(fhandle_t),	    xdr_rdlnres, sizeof(struct nfsrdlnres), rfs_rlfree},	/* RFS_READ = 6 */	{rfs_read, xdr_readargs, sizeof(struct nfsreadargs),	    xdr_rdresult, sizeof(struct nfsrdresult), rfs_rdfree},	/* RFS_WRITECACHE = 7 *** NO LONGER SUPPORTED *** */	{rfs_error, xdr_void, 0,	    xdr_void, 0, nullfree},	/* RFS_WRITE = 8 */	{rfs_write, xdr_writeargs, sizeof(struct nfswriteargs),	    xdr_attrstat, sizeof(struct nfsattrstat), nullfree},	/* RFS_CREATE = 9 */	{rfs_create, xdr_creatargs, sizeof(struct nfscreatargs),	    xdr_diropres, sizeof(struct nfsdiropres), nullfree},	/* RFS_REMOVE = 10 */	{rfs_remove, xdr_diropargs, sizeof(struct nfsdiropargs), 	    xdr_enum, sizeof(enum nfsstat), nullfree},	/* RFS_RENAME = 11 */	{rfs_rename, xdr_rnmargs, sizeof(struct nfsrnmargs), 	    xdr_enum, sizeof(enum nfsstat), nullfree},	/* RFS_LINK = 12 */	{rfs_link, xdr_linkargs, sizeof(struct nfslinkargs), 	    xdr_enum, sizeof(enum nfsstat), nullfree},	/* RFS_SYMLINK = 13 */	{rfs_symlink, xdr_slargs, sizeof(struct nfsslargs), 	    xdr_enum, sizeof(enum nfsstat), nullfree},	/* RFS_MKDIR = 14 */	{rfs_mkdir, xdr_creatargs, sizeof(struct nfscreatargs),	    xdr_diropres, sizeof(struct nfsdiropres), nullfree},	/* RFS_RMDIR = 15 */	{rfs_rmdir, xdr_diropargs, sizeof(struct nfsdiropargs), 	    xdr_enum, sizeof(enum nfsstat), nullfree},	/* RFS_READDIR = 16 */	{rfs_readdir, xdr_rddirargs, sizeof(struct nfsrddirargs),	    xdr_putrddirres, sizeof(struct nfsrddirres), rfs_rddirfree},	/* RFS_STATFS = 17 */	{rfs_statfs, xdr_fhandle, sizeof(fhandle_t),	    xdr_statfs, sizeof(struct nfsstatfs), nullfree},	}};struct rfsspace {	struct rfsspace *rs_next;	caddr_t		rs_dummy;};struct rfsspace *rfsfreesp = NULL;int rfssize = 0;caddr_trfsget(){	int i;	struct rfsdisp *dis;	caddr_t ret;	smp_lock(&lk_nfsargs, LK_RETRY);	if (rfssize == 0) {		for (i = 0; i < 1 + VERSIONMAX - VERSIONMIN; i++) {			for (dis = &rfsdisptab[i][0];			     dis < &rfsdisptab[i][RFS_NPROC];			     dis++) {				rfssize = MAX(rfssize, dis->dis_argsz);				rfssize = MAX(rfssize, dis->dis_ressz);			}		}	}	if (rfsfreesp) {		ret = (caddr_t)rfsfreesp;		rfsfreesp = rfsfreesp->rs_next;		smp_unlock(&lk_nfsargs);	} else {		smp_unlock(&lk_nfsargs);		kmem_alloc(ret, caddr_t, rfssize, KM_NFS);	}	return (ret);}rfsput(rs)	struct rfsspace *rs;{	smp_lock(&lk_nfsargs, LK_RETRY);	rs->rs_next = rfsfreesp;	rfsfreesp = rs;	smp_unlock(&lk_nfsargs);}/* * If nfsportmon is set, then clients are required to use * privileged ports (ports < IPPORT_RESERVED) in order to get NFS services. */int nfs_second_chance=1;int nfsportmon = 0;int nfs_cpu_count[32];int nfs_throwaways[RFS_NPROC];voidrfs_dispatch(req, xprt)	register struct svc_req *req;	register SVCXPRT *xprt;{	register struct rfsdisp *disp = NULL;	register int error = 0;	register caddr_t *args = NULL;	register caddr_t *res = NULL;	struct exportdata xpd;	struct export *ep;	fhandle_t *fh;	int which;	int vers;	struct authunix_parms *aup;	int *gp;	struct ucred *tmpcr;	struct ucred *newcr = NULL;	int dup_xid = 0;	smp_lock(&lk_nfsstat, LK_RETRY);	svstat.ncalls++;	smp_unlock(&lk_nfsstat);	nfs_cpu_count[CURRENT_CPUDATA->cpu_num]++;	which = req->rq_proc;	if (which < 0 || which >= RFS_NPROC) {		svcerr_noproc(req->rq_xprt);		error++;		goto done;	}	/* check for in-progress request in server cache. */	/* if not found, this request is added and flagged */	/* in-progress. */	if (svckudp_dupbusy(req)) {		dup_xid = 1;		nfs_dupstats.throwaways++;		++nfs_throwaways[which];		goto done;	}	vers = req->rq_vers;	if (vers < VERSIONMIN || vers > VERSIONMAX) {		svcerr_progvers(req->rq_xprt, (u_long)VERSIONMIN,		    (u_long)VERSIONMAX);		error++;		goto done;	}	vers -= VERSIONMIN;	disp = &rfsdisptab[vers][which];	/*	 * Clean up as if a system call just started	 */	u.u_error = 0;	/*	 * Allocate args struct and deserialize into it.	 */	args = (caddr_t *)rfsget();	bzero((caddr_t)args, rfssize);	if ( ! SVC_GETARGS(xprt, disp->dis_xdrargs, args)) {		svcerr_decode(xprt);		error++;		goto done;	}	/*	 * Find export information and check authentication,	 * setting the credential if everything is ok.	 */	if (which != RFS_NULL) {		/*		 * XXX: this isn't really quite correct. Instead of doing		 * this blind cast, we should extract out the fhandle for		 * each NFS call. What's more, some procedures (like rename)		 * have more than one fhandle passed in, and we should check		 * that the two fhandles point to the same exported path.		 */		fhandle_t *fh = (fhandle_t *) args;		if ((nfs_second_chance == 1) && (fh->fh_eno == 0)) {			fh->fh_eno = fh->fh_fno;			fh->fh_egen = fh->fh_fgen;		}		xpd.x_flags=0; 		/* mark it unexported. . .*/		smp_lock(&lk_gnode, LK_RETRY);		ep = exported;		while (ep != NULL) {			if ((ep->e_fsid == fh->fh_fsid) &&			    (ep->e_gnum == fh->fh_eno) &&			    (ep->e_gen == fh->fh_egen)) {				xpd.x_flags=ep->e_flags | M_EXPORTED;				xpd.x_rootmap=ep->e_rootmap;				break;			} else {				ep = ep->e_next;			}		}		smp_unlock(&lk_gnode);	}	/*	 * Check for unix style credentials	 */	if (req->rq_cred.oa_flavor != AUTH_UNIX && which != RFS_NULL) {		svcerr_weakauth(xprt);		error++;		goto done;	}	if (nfsportmon) {		/*		* Check for privileged port number		*/       	static count = 0;		if (ntohs(xprt->xp_raddr.sin_port) >= IPPORT_RESERVED) {			svcerr_weakauth(xprt);			if (count == 0) {				printf("NFS request from unprivileged port, ");				printf("source IP address = %u.%u.%u.%u\n",					xprt->xp_raddr.sin_addr.s_net,					xprt->xp_raddr.sin_addr.s_host,					xprt->xp_raddr.sin_addr.s_lh,					xprt->xp_raddr.sin_addr.s_impno);			}			count++;			count %= 256;			error++;			goto done;		}	}	/*	 * Set uid, gid, and gids to auth params	 */	if (which != RFS_NULL) {		aup = (struct authunix_parms *)req->rq_clntcred;		newcr = crget();		/*		 * root over the net gets mapped in fhtovp()		 */                newcr->cr_uid = newcr->cr_ruid = aup->aup_uid;                newcr->cr_gid = newcr->cr_rgid = aup->aup_gid;		bcopy((caddr_t)aup->aup_gids, (caddr_t)newcr->cr_groups,		    aup->aup_len * sizeof(newcr->cr_groups[0]));		for (gp = &newcr->cr_groups[aup->aup_len];		     gp < &newcr->cr_groups[NGROUPS];		     gp++) {			*gp = NOGROUP;		}		tmpcr = u.u_cred;		u.u_cred = newcr;	}	/*	 * Allocate results struct.	 */	res = (caddr_t *)rfsget();	bzero((caddr_t)res, rfssize);	smp_lock(&lk_nfsstat, LK_RETRY);	svstat.reqs[which]++;	smp_unlock(&lk_nfsstat);	/*	 * Call service routine with arg struct and results struct	 */	(*disp->dis_proc)(args, res, req, xprt, &xpd);done:	if (CURRENT_CPUDATA->cpu_hlock != NULL)		panic("nfsd holding lock");	/*	 * Free arguments struct	 */	if (disp) {		if (!SVC_FREEARGS(xprt, disp->dis_xdrargs, args))			error++;	} else		if (!SVC_FREEARGS(xprt, NULL, NULL))			error++;	if (args != NULL) {		rfsput((struct rfsspace *)args);	}	/*	 * Serialize and send results struct	 */	if (!error && !dup_xid) {		if (!svc_sendreply(xprt, disp->dis_xdrres, (caddr_t)res)) {			error++;		}	}	/*	 * Free results struct	 */	if (res != NULL) {		if ( disp->dis_resfree != nullfree ) {			(*disp->dis_resfree)(res);		}		rfsput((struct rfsspace *)res);	}	/*	 * restore original credentials	 */	if (newcr) {		u.u_cred = tmpcr;		crfree(newcr);	}	smp_lock(&lk_nfsstat, LK_RETRY);	svstat.nbadcalls += error;	smp_unlock(&lk_nfsstat);	/* mark this request not in-progress in server cache */	if (!dup_xid)		svckudp_dupdone(req);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -