svn commit: r268764 - in head/sys: fs/ext2fs fs/nandfs fs/nfsclient fs/nullfs fs/tmpfs kern ufs/ufs

Konstantin Belousov kib at FreeBSD.org
Wed Jul 16 14:04:48 UTC 2014


Author: kib
Date: Wed Jul 16 14:04:46 2014
New Revision: 268764
URL: http://svnweb.freebsd.org/changeset/base/268764

Log:
  Check for the cross-device cross-link attempt in the VFS, instead of
  forcing filesystem VOP_LINK() methods to repeat the code.  In
  tmpfs_link(), remove redundand check for the type of the source,
  already done by VFS.
  
  Note that NFS server already performs this check before calling
  VOP_LINK().
  
  Tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/fs/ext2fs/ext2_vnops.c
  head/sys/fs/nandfs/nandfs_vnops.c
  head/sys/fs/nfsclient/nfs_clvnops.c
  head/sys/fs/nullfs/null_vnops.c
  head/sys/fs/tmpfs/tmpfs_vnops.c
  head/sys/kern/vfs_syscalls.c
  head/sys/ufs/ufs/ufs_vnops.c

Modified: head/sys/fs/ext2fs/ext2_vnops.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_vnops.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/fs/ext2fs/ext2_vnops.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -666,10 +666,6 @@ ext2_link(struct vop_link_args *ap)
 	if ((cnp->cn_flags & HASBUF) == 0)
 		panic("ext2_link: no name");
 #endif
-	if (tdvp->v_mount != vp->v_mount) {
-		error = EXDEV;
-		goto out;
-	}
 	ip = VTOI(vp);
 	if ((nlink_t)ip->i_nlink >= EXT2_LINK_MAX) {
 		error = EMLINK;

Modified: head/sys/fs/nandfs/nandfs_vnops.c
==============================================================================
--- head/sys/fs/nandfs/nandfs_vnops.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/fs/nandfs/nandfs_vnops.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -1355,9 +1355,6 @@ nandfs_link(struct vop_link_args *ap)
 	struct nandfs_inode *inode = &node->nn_inode;
 	int error;
 
-	if (tdvp->v_mount != vp->v_mount)
-		return (EXDEV);
-
 	if (inode->i_links_count >= LINK_MAX)
 		return (EMLINK);
 

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/fs/nfsclient/nfs_clvnops.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -1976,10 +1976,6 @@ nfs_link(struct vop_link_args *ap)
 	struct nfsvattr nfsva, dnfsva;
 	int error = 0, attrflag, dattrflag;
 
-	if (vp->v_mount != tdvp->v_mount) {
-		return (EXDEV);
-	}
-
 	/*
 	 * Push all writes to the server, so that the attribute cache
 	 * doesn't get "out of sync" with the server.

Modified: head/sys/fs/nullfs/null_vnops.c
==============================================================================
--- head/sys/fs/nullfs/null_vnops.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/fs/nullfs/null_vnops.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -858,15 +858,6 @@ null_vptocnp(struct vop_vptocnp_args *ap
 	return (error);
 }
 
-static int
-null_link(struct vop_link_args *ap)
-{
-
-	if (ap->a_tdvp->v_mount != ap->a_vp->v_mount)
-		return (EXDEV);
-	return (null_bypass((struct vop_generic_args *)ap));
-}
-
 /*
  * Global vfs data structures
  */
@@ -880,7 +871,6 @@ struct vop_vector null_vnodeops = {
 	.vop_getwritemount =	null_getwritemount,
 	.vop_inactive =		null_inactive,
 	.vop_islocked =		vop_stdislocked,
-	.vop_link =		null_link,
 	.vop_lock1 =		null_lock,
 	.vop_lookup =		null_lookup,
 	.vop_open =		null_open,

Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -571,21 +571,6 @@ tmpfs_link(struct vop_link_args *v)
 	MPASS(VOP_ISLOCKED(dvp));
 	MPASS(cnp->cn_flags & HASBUF);
 	MPASS(dvp != vp); /* XXX When can this be false? */
-
-	/* XXX: Why aren't the following two tests done by the caller? */
-
-	/* Hard links of directories are forbidden. */
-	if (vp->v_type == VDIR) {
-		error = EPERM;
-		goto out;
-	}
-
-	/* Cannot create cross-device links. */
-	if (dvp->v_mount != vp->v_mount) {
-		error = EXDEV;
-		goto out;
-	}
-
 	node = VP_TO_TMPFS_NODE(vp);
 
 	/* Ensure that we do not overflow the maximum number of links imposed

Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/kern/vfs_syscalls.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -1578,7 +1578,15 @@ again:
 			vrele(nd.ni_vp);
 			error = EEXIST;
 		} else if ((error = vn_lock(vp, LK_EXCLUSIVE)) == 0) {
-			error = can_hardlink(vp, td->td_ucred);
+			/*
+			 * Check for cross-device links.  No need to
+			 * recheck vp->v_type, since it cannot change
+			 * for non-doomed vnode.
+			 */
+			if (nd.ni_dvp->v_mount != vp->v_mount)
+				error = EXDEV;
+			else
+				error = can_hardlink(vp, td->td_ucred);
 			if (error == 0)
 #ifdef MAC
 				error = mac_vnode_check_link(td->td_ucred,

Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c	Wed Jul 16 13:52:05 2014	(r268763)
+++ head/sys/ufs/ufs/ufs_vnops.c	Wed Jul 16 14:04:46 2014	(r268764)
@@ -968,10 +968,6 @@ ufs_link(ap)
 	if ((cnp->cn_flags & HASBUF) == 0)
 		panic("ufs_link: no name");
 #endif
-	if (tdvp->v_mount != vp->v_mount) {
-		error = EXDEV;
-		goto out;
-	}
 	if (VTOI(tdvp)->i_effnlink < 2)
 		panic("ufs_link: Bad link count %d on parent",
 		    VTOI(tdvp)->i_effnlink);


More information about the svn-src-head mailing list