summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-07-16 14:04:46 +0000
committerkib <kib@FreeBSD.org>2014-07-16 14:04:46 +0000
commit32a7383c85234a8aacc33c0415ab10beec2e0da3 (patch)
treed402822e2dc2ab92fb22d185c4e7be6a3d01ed96 /sys
parent508ee54556732e7fb194230700780b603987b02a (diff)
downloadFreeBSD-src-32a7383c85234a8aacc33c0415ab10beec2e0da3.zip
FreeBSD-src-32a7383c85234a8aacc33c0415ab10beec2e0da3.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/ext2fs/ext2_vnops.c4
-rw-r--r--sys/fs/nandfs/nandfs_vnops.c3
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c4
-rw-r--r--sys/fs/nullfs/null_vnops.c10
-rw-r--r--sys/fs/tmpfs/tmpfs_vnops.c15
-rw-r--r--sys/kern/vfs_syscalls.c10
-rw-r--r--sys/ufs/ufs/ufs_vnops.c4
7 files changed, 9 insertions, 41 deletions
diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index 523e3c7..2046e33 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -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;
diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c
index 056ca90..0f26b19 100644
--- a/sys/fs/nandfs/nandfs_vnops.c
+++ b/sys/fs/nandfs/nandfs_vnops.c
@@ -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);
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 2d13b06..9570b70 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -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.
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index cf3762e..70402e3 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -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,
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index cb35a69..c11fe31 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -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
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9d5380a..1406e0f 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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,
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 3504f0e..3379b13 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -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);
OpenPOWER on IntegriCloud