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

📄 nfs_server.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * is always allowed to read it.	 */	if (u.u_uid != vp->g_uid) {		error = VOP_ACCESS(vp, VREAD, u.u_cred);		if (error) {			/*			 * Exec is the same as read over the net because			 * of demand loading.			 */			error = VOP_ACCESS(vp, VEXEC, u.u_cred);		}		if (error) {			goto bad;		}	}	/*	 * Check whether we can do this with bread, which would	 * save the copy through the uio.	 */	fsbsize = ((struct gnode *)vp)->g_mp->m_fs_data->fd_otsize;	offset = ra->ra_offset % fsbsize;	/*	 * Don't call VOP_BREAD unless UFS file system.	 * VOP_BREAD is tailored to UFS.	 */	if ((((struct gnode *)vp)->g_mp->m_fstype == GT_ULTRIX) && 	    (offset + ra->ra_count <= fsbsize) && (offset % 4 == 0)) {		if (ra->ra_offset >= vp->g_size) {			rr->rr_count = 0;			gattr_to_nattr(vp, &rr->rr_attr);			rr->rr_attr.na_blocksize = fsbsize;			error = 0;			goto done;		}		error = VOP_BREAD(vp, ra->ra_offset / fsbsize, &bp);		if (error == 0) {			rr->rr_data = bp->b_un.b_addr + offset;			rr->rr_count = min(			    (u_int)(vp->g_size - ra->ra_offset),			    (u_int)ra->ra_count);			rr->rr_bp = bp;			rr->rr_vp = vp;			gref(vp);			gattr_to_nattr(vp, &rr->rr_attr);			rr->rr_attr.na_blocksize = fsbsize;			goto done;		} else {			printf("nfs read: failed, errno %d\n", error);		}	}	rr->rr_bp = (struct buf *) 0;				/*	 * Allocate space for data.  This will be freed by xdr_rdresult	 * when it is called with x_op = XDR_FREE.	 */	kmem_alloc(rr->rr_data, char *, ra->ra_count, KM_NFS);	rr->rr_bufallocaddr = rr->rr_data;	rr->rr_bufallocsize = ra->ra_count;	/*	 * Set up io vector	 */	iov.iov_base = rr->rr_data;	iov.iov_len = ra->ra_count;	uio.uio_iov = &iov;	uio.uio_iovcnt = 1;	uio.uio_segflg = UIO_SYSSPACE;	uio.uio_offset = ra->ra_offset;	uio.uio_resid = ra->ra_count;	/*	 * for now we assume no append mode and ignore	 * totcount (read ahead)	 */	error = VOP_RDWR(vp, &uio, UIO_READ, IO_SYNC, u.u_cred);	if (error) {		goto bad;	}	gattr_to_nattr(vp, &rr->rr_attr);	rr->rr_attr.na_blocksize = fsbsize;	rr->rr_count = ra->ra_count - uio.uio_resid;bad:	if (error && rr->rr_data != NULL) {		kmem_free(rr->rr_bufallocaddr, KM_NFS);		rr->rr_data = NULL;		rr->rr_count = 0;	}done:	rr->rr_status = puterrno(error);	gput(vp);	return(0);}/* * Free data allocated by rfs_read. */rfs_rdfree(rr)	struct nfsrdresult *rr;{	if (rr->rr_bp == 0 && rr->rr_data) {		kmem_free(rr->rr_bufallocaddr, KM_NFS);	}}/* * Write data to file. * Returns attributes of a file after writing some data to it. */intrfs_write(wa, ns, req, xprt, xpd)	struct nfswriteargs *wa;	struct nfsattrstat *ns;	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	register struct vnode *vp;	struct vattr va;	struct iovec iov;	struct uio uio;	struct timeval duptime;	int dupmark;	vp = fhtovp(&wa->wa_fhandle, xprt, RFS_WRITE, xpd);	if (vp == NULL) {		ns->ns_status = NFSERR_STALE;		return(ESTALE);	}	if (rdonly(vp, xpd)) {		error = EROFS;	} else {		if (svckudp_dup(req, &duptime, &dupmark) &&			duptime.tv_sec == vp->g_mtime.tv_sec &&			duptime.tv_usec == vp->g_mtime.tv_usec) {			++nfs_dupstats.writes;		}		else {			if (u.u_uid != vp->g_uid) {				/*				 * This is a kludge to allow writes of				 * files created with read only permission.				 * The owner of the file				 * is always allowed to write it.				 */				error = VOP_ACCESS(vp, VWRITE, u.u_cred);			}			if (!error) {				iov.iov_base = wa->wa_data;				iov.iov_len = wa->wa_count;				uio.uio_iov = &iov;				uio.uio_iovcnt = 1;				uio.uio_segflg = UIO_SYSSPACE;				uio.uio_offset = wa->wa_offset;				uio.uio_resid = wa->wa_count;				/*				 * for now we assume no append mode				 */				error = VOP_RDWR(vp, &uio, UIO_WRITE,					IO_SYNC, u.u_cred);			}		}		if (!error) {			/*			 * Get attributes again so we send the latest mod			 * time to the client side for his cache.			 */			error = VOP_GETATTR(vp, &va, u.u_cred);		}		if (error) {			svckudp_dupsave(req, *timepick, DUP_FAIL);		} else {			vattr_to_nattr(&va, &ns->ns_attr);			svckudp_dupsave(req, vp->g_mtime, DUP_DONE);		}	}	ns->ns_status = puterrno(error);	gput(vp);	return(0);}/* * Create a file. * Creates a file with given attributes and returns those attributes * and an fhandle for the new file. */intrfs_create(args, dr, req, xprt, xpd)	struct nfscreatargs *args;	struct  nfsdiropres *dr;	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	struct vattr va;	struct vnode *vp;	register struct vnode *dvp;	struct timeval duptime;	int dupmark;	sattr_to_vattr(&args->ca_sa, &va);        /*         * This is a completely gross hack to make mknod         * work over the wire until we can wack the protocol         */#define IFMT            0170000         /* type of file */#define IFCHR           0020000         /* character special */#define IFBLK           0060000         /* block special */#define IFSOCK          0140000         /* socket */        if ((va.va_mode & IFMT) == IFCHR) {                va.va_type = VCHR;                if (va.va_size == (u_long)NFS_FIFO_DEV) {                        va.va_type = VFIFO; /* xtra kludge for namedpipe */			va.va_mode = (va.va_mode & ~GFMT) | GFPORT;		} else                         va.va_rdev = (dev_t)va.va_size;                va.va_size = 0;         } else if ((va.va_mode & IFMT) == IFBLK) {                va.va_type = VBLK;                va.va_rdev = (dev_t)va.va_size;                va.va_size = 0;         } else if ((va.va_mode & IFMT) == IFSOCK) {                va.va_type = VSOCK;        } else {                va.va_type = VREG;		va.va_mode = (va.va_mode & ~GFMT) | GFREG;        } 	/*	 * XXX Should get exclusive flag and use it.	 */	dvp = fhtovp(&args->ca_da.da_fhandle, xprt, RFS_CREATE, xpd);	if (dvp == NULL) {		dr->dr_status = NFSERR_STALE;		return(ESTALE);	}	if (rdonly(dvp, xpd)) {		gfs_unlock(dvp);		error = EROFS;	} else {		if (svckudp_dup(req, &duptime, &dupmark) &&		    duptime.tv_sec == dvp->g_ctime.tv_sec &&		    duptime.tv_usec == dvp->g_ctime.tv_usec) {			++nfs_dupstats.creates;			error = VOP_LOOKUP(dvp, args->ca_da.da_name,				&vp, u.u_cred);			if (!error) {				gfs_lock(vp);			}			gfs_unlock(dvp);		}		else {			error = VOP_CREATE(dvp, args->ca_da.da_name,				&va, NONEXCL, VWRITE, &vp, u.u_cred);		}		if (!error) {			error = VOP_GETATTR(vp, &va, u.u_cred);			if (!error) {				vattr_to_nattr(&va, &dr->dr_attr);				error = makefh(&dr->dr_fhandle, vp, 					       args->ca_da.da_fhandle.fh_eno, 					       args->ca_da.da_fhandle.fh_egen);			}			gput(vp);		}		if (error) {			svckudp_dupsave(req, *timepick, DUP_FAIL);		} else {			svckudp_dupsave(req, dvp->g_ctime, DUP_DONE);		}	}	dr->dr_status = puterrno(error);	grele(dvp);	return(0);}/* * Remove a file. * Remove named file from parent directory. */intrfs_remove(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_REMOVE, 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.removes;			gfs_unlock(vp);		}		else			error = VOP_REMOVE(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);}/* * rename a file * Give a file (from) a new name (to). */intrfs_rename(args, status, req, xprt, xpd)	struct nfsrnmargs *args;	enum nfsstat *status; 	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	register struct vnode *fromvp;	register struct vnode *tovp;	struct timeval duptime;	int dupmark;	fromvp = fhtovp(&args->rna_from.da_fhandle, xprt, RFS_RENAME, xpd);	if (fromvp == NULL) {		*status = NFSERR_STALE;		return(ESTALE);	}	if (rdonly(fromvp, xpd)) {		error = EROFS;		gfs_unlock(fromvp);		goto fromerr;	}	if ((args->rna_from.da_fhandle.fh_fsid ==	     args->rna_to.da_fhandle.fh_fsid) &&	    (args->rna_from.da_fhandle.fh_fno ==	     args->rna_to.da_fhandle.fh_fno) &&	    (args->rna_from.da_fhandle.fh_fgen ==	     args->rna_to.da_fhandle.fh_fgen))		tovp=fromvp;	else		tovp = fhtovp(&args->rna_to.da_fhandle, xprt, RFS_RENAME, xpd);	if (tovp == NULL) {		*status = NFSERR_STALE;		gput(fromvp);		return(ESTALE);	}	if (rdonly(tovp, xpd)) {		gfs_unlock(fromvp);		gfs_unlock(tovp);		error = EROFS;	} else {		if (svckudp_dup(req, &duptime, &dupmark) &&			duptime.tv_sec == fromvp->g_ctime.tv_sec &&			duptime.tv_usec == fromvp->g_ctime.tv_usec) {			++nfs_dupstats.renames;			if (tovp != fromvp)				gfs_unlock(tovp);			gfs_unlock(fromvp);		} else			error = VOP_RENAME(fromvp, args->rna_from.da_name,			    tovp, args->rna_to.da_name, u.u_cred);		if (error) {			svckudp_dupsave(req, *timepick, DUP_FAIL);		} else {			svckudp_dupsave(req, fromvp->g_ctime, DUP_DONE);		}	}	if (tovp != fromvp)	    grele(tovp);fromerr:	grele(fromvp);	*status = puterrno(error); 	return(0);} /* * Link to a file. * Create a file (to) which is a hard link to the given file (from). */intrfs_link(args, status, req, xprt, xpd)	struct nfslinkargs *args;	enum nfsstat *status;  	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	register struct vnode *fromvp;	register struct vnode *tovp;	struct timeval duptime, savectime;	int dupmark;	tovp = fhtovp(&args->la_to.da_fhandle, xprt, RFS_LINK, xpd);	if (tovp == NULL) {		*status = NFSERR_STALE;		return(ESTALE);	}	gfs_unlock(tovp);	fromvp = fhtovp(&args->la_from, xprt, RFS_LINK, xpd);	if (fromvp == NULL) {		grele(tovp);		*status = NFSERR_STALE;		return(ESTALE);	}	if (rdonly(tovp, xpd)) {		gput(fromvp);		grele(tovp);		error = EROFS;	} else {		if (svckudp_dup(req, &duptime, &dupmark) &&			duptime.tv_sec == fromvp->g_ctime.tv_sec &&			duptime.tv_usec == fromvp->g_ctime.tv_usec) {			++nfs_dupstats.links;			savectime = fromvp->g_ctime;			gput(fromvp);			grele(tovp);		} else			error = vop_link(fromvp, tovp, args->la_to.da_name,					 &savectime, u.u_cred);		if (error) {			svckudp_dupsave(req, *timepick, DUP_FAIL);		} else {			svckudp_dupsave(req, savectime, DUP_DONE);		}	}	*status = puterrno(error);	return(0);}  /* * Symbolicly link to a file. * Create a file (to) with the given attributes which is a symbolic link * to the given path name (to). */intrfs_symlink(args, status, req, xprt, xpd)	struct nfsslargs *args;	enum nfsstat *status;   	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{		  	register int error = 0;	struct vattr va;	register struct vnode *vp;	struct timeval duptime;	int dupmark;	sattr_to_vattr(&args->sla_sa, &va);	va.va_type = VLNK;	vp = fhtovp(&args->sla_from.da_fhandle, xprt, RFS_SYMLINK, 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.symlinks;			gfs_unlock(vp);		}		else			error = VOP_SYMLINK(vp, args->sla_from.da_name,					    &va, args->sla_tnm, 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);}    /* * Make a directory. * Create a directory with the given name, parent directory, and attributes. * Returns a file handle and attributes for the new directory. */intrfs_mkdir(args, dr, req, xprt, xpd)	struct nfscreatargs *args;	struct  nfsdiropres *dr;	struct svc_req *req;	SVCXPRT *xprt;	struct exportdata *xpd;{	register int error = 0;	struct vattr va;	struct vnode *dvp;	register struct vnode *vp;	struct timeval duptime;	int dupmark;	sattr_to_vattr(&args->ca_sa, &va);	va.va_type = VDIR;	/*	 * Should get exclusive flag and pass it on here	 */	vp = fhtovp(&args->ca_da.da_fhandle, xprt, RFS_MKDIR, xpd);	if (vp == NULL) {		dr->dr_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.mkdirs;			error = VOP_LOOKUP(vp, args->ca_da.da_name, &dvp,				u.u_cred);			if (!error) {				error = VOP_GETATTR(dvp, &va, u.u_cred);			}			gfs_unlock(vp);		}		else {			error = VOP_MKDIR(vp, args->ca_da.da_name, &va,				&dvp, u.u_cred);		}		if (!error) {			vattr_to_nattr(&va, &dr->dr_attr);			gfs_lock(dvp);			error = makefh(&dr->dr_fhandle, dvp, 				       args->ca_da.da_fhandle.fh_eno,				       args->ca_da.da_fhandle.fh_egen);			gput(dvp);		}		if (error) {			svckudp_dupsave(req, *timepick, DUP_FAIL);		} else {			svckudp_dupsave(req, vp->g_ctime, DUP_DONE);		}

⌨️ 快捷键说明

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