From owner-svn-src-all@FreeBSD.ORG Wed Jul 16 14:04:48 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 17254858; Wed, 16 Jul 2014 14:04:48 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EB2FA2C6F; Wed, 16 Jul 2014 14:04:47 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6GE4lgb003839; Wed, 16 Jul 2014 14:04:47 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6GE4kow003832; Wed, 16 Jul 2014 14:04:46 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201407161404.s6GE4kow003832@svn.freebsd.org> From: Konstantin Belousov Date: Wed, 16 Jul 2014 14:04:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268764 - in head/sys: fs/ext2fs fs/nandfs fs/nfsclient fs/nullfs fs/tmpfs kern ufs/ufs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jul 2014 14:04:48 -0000 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);