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

📄 nfs_vnops.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!error && (cnp->cn_flags & MAKEENTRY))		cache_enter(dvp, newvp, cnp);	FREE(cnp->cn_pnbuf, M_NAMEI);	VTONFS(dvp)->n_flag |= NMODIFIED;	VTONFS(dvp)->n_attrstamp = 0;	vrele(dvp);	return (error);}/* * nfs file create call */intnfs_create(ap)	struct vop_create_args /* {		struct vnode *a_dvp;		struct vnode **a_vpp;		struct componentname *a_cnp;		struct vattr *a_vap;	} */ *ap;{	register struct vnode *dvp = ap->a_dvp;	register struct vattr *vap = ap->a_vap;	register struct componentname *cnp = ap->a_cnp;	register struct nfsv2_sattr *sp;	register u_long *tl;	register caddr_t cp;	register long t1, t2;	caddr_t bpos, dpos, cp2;	int error = 0, isnq;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	struct vattr vattr;	if (error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_proc)) {		VOP_ABORTOP(dvp, cnp);		vput(dvp);		return (error);	}	nfsstats.rpccnt[NFSPROC_CREATE]++;	isnq = (VFSTONFS(dvp->v_mount)->nm_flag & NFSMNT_NQNFS);	nfsm_reqhead(dvp, NFSPROC_CREATE,	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR(isnq));	nfsm_fhtom(dvp);	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR(isnq));	sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);	sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid);	sp->sa_gid = txdr_unsigned(vattr.va_gid);	if (isnq) {		u_quad_t qval = 0;		txdr_hyper(&qval, &sp->sa_nqsize);		sp->sa_nqflags = 0;		sp->sa_nqrdev = -1;		txdr_nqtime(&vap->va_atime, &sp->sa_nqatime);		txdr_nqtime(&vap->va_mtime, &sp->sa_nqmtime);	} else {		sp->sa_nfssize = 0;		txdr_nfstime(&vap->va_atime, &sp->sa_nfsatime);		txdr_nfstime(&vap->va_mtime, &sp->sa_nfsmtime);	}	nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_proc, cnp->cn_cred);	nfsm_mtofh(dvp, *ap->a_vpp);	nfsm_reqdone;	if (!error && (cnp->cn_flags & MAKEENTRY))		cache_enter(dvp, *ap->a_vpp, cnp);	FREE(cnp->cn_pnbuf, M_NAMEI);	VTONFS(dvp)->n_flag |= NMODIFIED;	VTONFS(dvp)->n_attrstamp = 0;	vrele(dvp);	return (error);}/* * nfs file remove call * To try and make nfs semantics closer to ufs semantics, a file that has * other processes using the vnode is renamed instead of removed and then * removed later on the last close. * - If v_usecount > 1 *	  If a rename is not already in the works *	     call nfs_sillyrename() to set it up *     else *	  do the remove rpc */intnfs_remove(ap)	struct vop_remove_args /* {		struct vnodeop_desc *a_desc;		struct vnode * a_dvp;		struct vnode * a_vp;		struct componentname * a_cnp;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	register struct vnode *dvp = ap->a_dvp;	register struct componentname *cnp = ap->a_cnp;	register struct nfsnode *np = VTONFS(vp);	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int error = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	if (vp->v_usecount > 1) {		if (!np->n_sillyrename)			error = nfs_sillyrename(dvp, vp, cnp);	} else {		/*		 * Purge the name cache so that the chance of a lookup for		 * the name succeeding while the remove is in progress is		 * minimized. Without node locking it can still happen, such		 * that an I/O op returns ESTALE, but since you get this if		 * another host removes the file..		 */		cache_purge(vp);		/*		 * Throw away biocache buffers. Mainly to avoid		 * unnecessary delayed writes.		 */		error = nfs_vinvalbuf(vp, 0, cnp->cn_cred, cnp->cn_proc, 1);		if (error == EINTR)			return (error);		/* Do the rpc */		nfsstats.rpccnt[NFSPROC_REMOVE]++;		nfsm_reqhead(dvp, NFSPROC_REMOVE,			NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen));		nfsm_fhtom(dvp);		nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);		nfsm_request(dvp, NFSPROC_REMOVE, cnp->cn_proc, cnp->cn_cred);		nfsm_reqdone;		FREE(cnp->cn_pnbuf, M_NAMEI);		VTONFS(dvp)->n_flag |= NMODIFIED;		VTONFS(dvp)->n_attrstamp = 0;		/*		 * Kludge City: If the first reply to the remove rpc is lost..		 *   the reply to the retransmitted request will be ENOENT		 *   since the file was in fact removed		 *   Therefore, we cheat and return success.		 */		if (error == ENOENT)			error = 0;	}	np->n_attrstamp = 0;	vrele(dvp);	vrele(vp);	return (error);}/* * nfs file remove rpc called from nfs_inactive */intnfs_removeit(sp)	register struct sillyrename *sp;{	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int error = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	nfsstats.rpccnt[NFSPROC_REMOVE]++;	nfsm_reqhead(sp->s_dvp, NFSPROC_REMOVE,		NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(sp->s_namlen));	nfsm_fhtom(sp->s_dvp);	nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);	nfsm_request(sp->s_dvp, NFSPROC_REMOVE, NULL, sp->s_cred);	nfsm_reqdone;	VTONFS(sp->s_dvp)->n_flag |= NMODIFIED;	VTONFS(sp->s_dvp)->n_attrstamp = 0;	return (error);}/* * nfs file rename call */intnfs_rename(ap)	struct vop_rename_args  /* {		struct vnode *a_fdvp;		struct vnode *a_fvp;		struct componentname *a_fcnp;		struct vnode *a_tdvp;		struct vnode *a_tvp;		struct componentname *a_tcnp;	} */ *ap;{	register struct vnode *fvp = ap->a_fvp;	register struct vnode *tvp = ap->a_tvp;	register struct vnode *fdvp = ap->a_fdvp;	register struct vnode *tdvp = ap->a_tdvp;	register struct componentname *tcnp = ap->a_tcnp;	register struct componentname *fcnp = ap->a_fcnp;	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int error = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	/* Check for cross-device rename */	if ((fvp->v_mount != tdvp->v_mount) ||	    (tvp && (fvp->v_mount != tvp->v_mount))) {		error = EXDEV;		goto out;	}	nfsstats.rpccnt[NFSPROC_RENAME]++;	nfsm_reqhead(fdvp, NFSPROC_RENAME,		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(fcnp->cn_namelen)+		nfsm_rndup(fcnp->cn_namelen)); /* or fcnp->cn_cred?*/	nfsm_fhtom(fdvp);	nfsm_strtom(fcnp->cn_nameptr, fcnp->cn_namelen, NFS_MAXNAMLEN);	nfsm_fhtom(tdvp);	nfsm_strtom(tcnp->cn_nameptr, tcnp->cn_namelen, NFS_MAXNAMLEN);	nfsm_request(fdvp, NFSPROC_RENAME, tcnp->cn_proc, tcnp->cn_cred);	nfsm_reqdone;	VTONFS(fdvp)->n_flag |= NMODIFIED;	VTONFS(fdvp)->n_attrstamp = 0;	VTONFS(tdvp)->n_flag |= NMODIFIED;	VTONFS(tdvp)->n_attrstamp = 0;	if (fvp->v_type == VDIR) {		if (tvp != NULL && tvp->v_type == VDIR)			cache_purge(tdvp);		cache_purge(fdvp);	}out:	if (tdvp == tvp)		vrele(tdvp);	else		vput(tdvp);	if (tvp)		vput(tvp);	vrele(fdvp);	vrele(fvp);	/*	 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.	 */	if (error == ENOENT)		error = 0;	return (error);}/* * nfs file rename rpc called from nfs_remove() above */intnfs_renameit(sdvp, scnp, sp)	struct vnode *sdvp;	struct componentname *scnp;	register struct sillyrename *sp;{	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int error = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	nfsstats.rpccnt[NFSPROC_RENAME]++;	nfsm_reqhead(sdvp, NFSPROC_RENAME,		(NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(scnp->cn_namelen)+		nfsm_rndup(sp->s_namlen));	nfsm_fhtom(sdvp);	nfsm_strtom(scnp->cn_nameptr, scnp->cn_namelen, NFS_MAXNAMLEN);	nfsm_fhtom(sdvp);	nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);	nfsm_request(sdvp, NFSPROC_RENAME, scnp->cn_proc, scnp->cn_cred);	nfsm_reqdone;	FREE(scnp->cn_pnbuf, M_NAMEI);	VTONFS(sdvp)->n_flag |= NMODIFIED;	VTONFS(sdvp)->n_attrstamp = 0;	return (error);}/* * nfs hard link create call */intnfs_link(ap)	struct vop_link_args /* {		struct vnode *a_vp;		struct vnode *a_tdvp;		struct componentname *a_cnp;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	register struct vnode *tdvp = ap->a_tdvp;	register struct componentname *cnp = ap->a_cnp;	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int error = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	if (vp->v_mount != tdvp->v_mount) {		/*VOP_ABORTOP(vp, cnp);*/		if (tdvp == vp)			vrele(vp);		else			vput(vp);		return (EXDEV);	}	nfsstats.rpccnt[NFSPROC_LINK]++;	nfsm_reqhead(tdvp, NFSPROC_LINK,		NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen));	nfsm_fhtom(tdvp);	nfsm_fhtom(vp);	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);	nfsm_request(tdvp, NFSPROC_LINK, cnp->cn_proc, cnp->cn_cred);	nfsm_reqdone;	FREE(cnp->cn_pnbuf, M_NAMEI);	VTONFS(tdvp)->n_attrstamp = 0;	VTONFS(tdvp)->n_flag |= NMODIFIED;	VTONFS(vp)->n_attrstamp = 0;	vrele(vp);	/*	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.	 */	if (error == EEXIST)		error = 0;	return (error);}/* * nfs symbolic link create call *//* start here */intnfs_symlink(ap)	struct vop_symlink_args /* {		struct vnode *a_dvp;		struct vnode **a_vpp;		struct componentname *a_cnp;		struct vattr *a_vap;		char *a_target;	} */ *ap;{	register struct vnode *dvp = ap->a_dvp;	register struct vattr *vap = ap->a_vap;	register struct componentname *cnp = ap->a_cnp;	register struct nfsv2_sattr *sp;	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int slen, error = 0, isnq;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	nfsstats.rpccnt[NFSPROC_SYMLINK]++;	slen = strlen(ap->a_target);	isnq = (VFSTONFS(dvp->v_mount)->nm_flag & NFSMNT_NQNFS);	nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH+2*NFSX_UNSIGNED+	    nfsm_rndup(cnp->cn_namelen)+nfsm_rndup(slen)+NFSX_SATTR(isnq));	nfsm_fhtom(dvp);	nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);	nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR(isnq));	sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode);	sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid);	sp->sa_gid = txdr_unsigned(cnp->cn_cred->cr_gid);	if (isnq) {		quad_t qval = -1;		txdr_hyper(&qval, &sp->sa_nqsize);		sp->sa_nqflags = 0;		txdr_nqtime(&vap->va_atime, &sp->sa_nqatime);		txdr_nqtime(&vap->va_mtime, &sp->sa_nqmtime);	} else {		sp->sa_nfssize = -1;		txdr_nfstime(&vap->va_atime, &sp->sa_nfsatime);		txdr_nfstime(&vap->va_mtime, &sp->sa_nfsmtime);	}	nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_proc, cnp->cn_cred);	nfsm_reqdone;	FREE(cnp->cn_pnbuf, M_NAMEI);	VTONFS(dvp)->n_flag |= NMODIFIED;	VTONFS(dvp)->n_attrstamp = 0;	vrele(dvp);	/*	 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.	 */	if (error == EEXIST)		error = 0;	return (error);}/* * nfs make dir call */intnfs_mkdir(ap)	struct vop_mkdir_args /* {		struct vnode *a_dvp;		struct vnode **a_vpp;		struct componentname *a_cnp;		struct vattr *a_vap;	} */ *ap;{	register struct vnode *dvp = ap->a_dvp;	register struct vattr *vap = ap->a_vap;	register struct componentname *cnp = ap->a_cnp;	register struct vnode **vpp = ap->a_vpp;	register struct nfsv2_sattr *sp;	register u_long *tl;	register caddr_t cp;	register long t1, t2;	register int len;	caddr_t bpos, dpos, cp2;	int error = 0, firsttry = 1, isnq;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	struct vattr vattr;	if (error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_proc)) {		VOP_ABORTOP(dvp, cnp);		vput(dvp);		return (error);	}	len = cnp->cn_namelen;	isnq = (VFSTONFS(dvp->v_mount)->nm_flag & NFSMNT_NQNFS);	nfsstats.rpccnt[NFSPROC_MKDIR]++;	nfsm_reqhead(dvp, NFSPROC_MKDIR,	  NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR(isnq));	nfsm_fhtom(dvp);	nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);	nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR(isnq));	sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode);	sp->sa_uid = txdr_unsigned(cnp->cn_cred->cr_uid);	sp->sa_gid = txdr_unsigned(vattr.va_gid);	if (isnq) {		quad_t qval = -1;		txdr_hyper(&qval, &sp->sa_nqsize);		sp->sa_nqflags = 0;		txdr_nqtime(&vap->va_atime, &sp->sa_nqatime);		txdr_nqtime(&vap->va_mtime, &sp->sa_nqmtime);	} else {		sp->sa_nfssize = -1;		txdr_nfstime(&vap->va_atime, &sp->sa_nfsatime);		txdr_nfstime(&vap->va_mtime, &sp->sa_nfsmtime);	}	nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_proc, cnp->cn_cred);	nfsm_mtofh(dvp, *vpp);	nfsm_reqdone;	VTONFS(dvp)->n_flag |= NMODIFIED;	VTONFS(dvp)->n_attrstamp = 0;	/*	 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry	 * if we can succeed in looking up the directory.	 * "firsttry" is necessary since the macros may "goto nfsmout" which	 * is above the if on errors. (Ugh)	 */	if (error == EEXIST && firsttry) {		firsttry = 0;		error = 0;		nfsstats.rpccnt[NFSPROC_LOOKUP]++;		*vpp = NULL;		nfsm_reqhead(dvp, NFSPROC_LOOKUP,		    NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));		nfsm_fhtom(dvp);		nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);		nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred);		nfsm_mtofh(dvp, *vpp);		if ((*vpp)->v_type != VDIR) {			vput(*vpp);			error = EEXIST;		}		m_freem(mrep);	}	FREE(cnp->cn_pnbuf, M_NAMEI);	vrele(dvp);	return (error);}/* * nfs remove directory call */intnfs_rmdir(ap)	struct vop_rmdir_args /* {		struct vnode *a_dvp;		struct vnode *a_vp;		struct componentname *a_cnp;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	register struct vnode *dvp = ap->a_dvp;	register struct componentname *cnp = ap->a_cnp;	register u_long *tl;	register caddr_t cp;	register long t2;	caddr_t bpos, dpos;	int error = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	if (dvp == vp) {

⌨️ 快捷键说明

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