Module Name:    src
Committed By:   rmind
Date:           Sun Apr 24 21:35:30 UTC 2011

Modified Files:
        src/sys/fs/nilfs: nilfs_vnops.c
        src/sys/fs/tmpfs: tmpfs_vnops.c
        src/sys/fs/udf: udf_vnops.c
        src/sys/kern: vfs_syscalls.c
        src/sys/nfs: nfs_vnops.c
        src/sys/ufs/ext2fs: ext2fs_vnops.c
        src/sys/ufs/ufs: ufs_vnops.c

Log Message:
sys_link: prevent hard links on directories (cross-mount operations are
already prevented).  File systems are no longer responsible to check this.
Clean up and add asserts (note that dvp == vp cannot happen in vop_link).

OK dholland@


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/fs/nilfs/nilfs_vnops.c
cvs rdiff -u -r1.76 -r1.77 src/sys/fs/tmpfs/tmpfs_vnops.c
cvs rdiff -u -r1.62 -r1.63 src/sys/fs/udf/udf_vnops.c
cvs rdiff -u -r1.422 -r1.423 src/sys/kern/vfs_syscalls.c
cvs rdiff -u -r1.289 -r1.290 src/sys/nfs/nfs_vnops.c
cvs rdiff -u -r1.97 -r1.98 src/sys/ufs/ext2fs/ext2fs_vnops.c
cvs rdiff -u -r1.187 -r1.188 src/sys/ufs/ufs/ufs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/nilfs/nilfs_vnops.c
diff -u src/sys/fs/nilfs/nilfs_vnops.c:1.9 src/sys/fs/nilfs/nilfs_vnops.c:1.10
--- src/sys/fs/nilfs/nilfs_vnops.c:1.9	Tue Nov 30 10:43:03 2010
+++ src/sys/fs/nilfs/nilfs_vnops.c	Sun Apr 24 21:35:29 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: nilfs_vnops.c,v 1.9 2010/11/30 10:43:03 dholland Exp $ */
+/* $NetBSD: nilfs_vnops.c,v 1.10 2011/04/24 21:35:29 rmind Exp $ */
 
 /*
  * Copyright (c) 2008, 2009 Reinoud Zandijk
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.9 2010/11/30 10:43:03 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.10 2011/04/24 21:35:29 rmind Exp $");
 #endif /* not lint */
 
 
@@ -1159,15 +1159,9 @@
 	int error;
 
 	DPRINTF(VFSCALL, ("nilfs_link called\n"));
-	error = 0;
-
-	/* some quick checks */
-	if (vp->v_type == VDIR)
-		return EPERM;		/* can't link a directory */
-	if (dvp->v_mount != vp->v_mount)
-		return EXDEV;		/* can't link across devices */
-	if (dvp == vp)
-		return EPERM;		/* can't be the same */
+	KASSERT(dvp != vp);
+	KASSERT(vp->v_type != VDIR);
+	KASSERT(dvp->v_mount == vp->v_mount);
 
 	/* lock node */
 	error = vn_lock(vp, LK_EXCLUSIVE);

Index: src/sys/fs/tmpfs/tmpfs_vnops.c
diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.76 src/sys/fs/tmpfs/tmpfs_vnops.c:1.77
--- src/sys/fs/tmpfs/tmpfs_vnops.c:1.76	Thu Jan 13 13:35:12 2011
+++ src/sys/fs/tmpfs/tmpfs_vnops.c	Sun Apr 24 21:35:29 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: tmpfs_vnops.c,v 1.76 2011/01/13 13:35:12 pooka Exp $	*/
+/*	$NetBSD: tmpfs_vnops.c,v 1.77 2011/04/24 21:35:29 rmind Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.76 2011/01/13 13:35:12 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.77 2011/04/24 21:35:29 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -737,44 +737,34 @@
 	return error;
 }
 
-/* --------------------------------------------------------------------- */
-
+/*
+ * tmpfs:link: create hard link.
+ */
 int
 tmpfs_link(void *v)
 {
-	struct vnode *dvp = ((struct vop_link_args *)v)->a_dvp;
-	struct vnode *vp = ((struct vop_link_args *)v)->a_vp;
-	struct componentname *cnp = ((struct vop_link_args *)v)->a_cnp;
-
-	int error;
+	struct vop_link_args /* {
+		struct vnode *a_dvp;
+		struct vnode *a_vp;
+		struct componentname *a_cnp;
+	} */ *ap = v;
+	struct vnode *dvp = ap->a_dvp;
+	struct vnode *vp = ap->a_vp;
+	struct componentname *cnp = ap->a_cnp;;
+	struct tmpfs_node *dnode, *node;
 	struct tmpfs_dirent *de;
-	struct tmpfs_node *dnode;
-	struct tmpfs_node *node;
+	int error;
 
+	KASSERT(dvp != vp);
 	KASSERT(VOP_ISLOCKED(dvp));
-	KASSERT(dvp != vp); /* XXX When can this be false? */
+	KASSERT(vp->v_type != VDIR);
+	KASSERT(dvp->v_mount == vp->v_mount);
 
 	dnode = VP_TO_TMPFS_DIR(dvp);
 	node = VP_TO_TMPFS_NODE(vp);
 
-	/* Lock vp because we will need to run tmpfs_update over it, which
-	 * needs the vnode to be locked. */
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 
-	/* 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;
-	}
-
 	/* Ensure that we do not overflow the maximum number of links imposed
 	 * by the system. */
 	KASSERT(node->tn_links <= LINK_MAX);

Index: src/sys/fs/udf/udf_vnops.c
diff -u src/sys/fs/udf/udf_vnops.c:1.62 src/sys/fs/udf/udf_vnops.c:1.63
--- src/sys/fs/udf/udf_vnops.c:1.62	Sun Jan  2 05:09:30 2011
+++ src/sys/fs/udf/udf_vnops.c	Sun Apr 24 21:35:30 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.62 2011/01/02 05:09:30 dholland Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.63 2011/04/24 21:35:30 rmind Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.62 2011/01/02 05:09:30 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.63 2011/04/24 21:35:30 rmind Exp $");
 #endif /* not lint */
 
 
@@ -1481,15 +1481,9 @@
 	int error;
 
 	DPRINTF(CALL, ("udf_link called\n"));
-	error = 0;
-
-	/* some quick checks */
-	if (vp->v_type == VDIR)
-		return EPERM;		/* can't link a directory */
-	if (dvp->v_mount != vp->v_mount)
-		return EXDEV;		/* can't link across devices */
-	if (dvp == vp)
-		return EPERM;		/* can't be the same */
+	KASSERT(dvp != vp);
+	KASSERT(vp->v_type != VDIR);
+	KASSERT(dvp->v_mount == vp->v_mount);
 
 	/* lock node */
 	error = vn_lock(vp, LK_EXCLUSIVE);

Index: src/sys/kern/vfs_syscalls.c
diff -u src/sys/kern/vfs_syscalls.c:1.422 src/sys/kern/vfs_syscalls.c:1.423
--- src/sys/kern/vfs_syscalls.c:1.422	Sun Apr 10 15:45:33 2011
+++ src/sys/kern/vfs_syscalls.c	Sun Apr 24 21:35:29 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $	*/
+/*	$NetBSD: vfs_syscalls.c,v 1.423 2011/04/24 21:35:29 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.423 2011/04/24 21:35:29 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_fileassoc.h"
@@ -1767,9 +1767,12 @@
 		error = EEXIST;
 		goto abortop;
 	}
-	/*
-	 * Prevent cross-mount operation.
-	 */
+	/* Prevent hard links on directories. */
+	if (vp->v_type == VDIR) {
+		error = EPERM;
+		goto abortop;
+	}
+	/* Prevent cross-mount operation. */
 	if (nd.ni_dvp->v_mount != vp->v_mount) {
 		error = EXDEV;
 		goto abortop;

Index: src/sys/nfs/nfs_vnops.c
diff -u src/sys/nfs/nfs_vnops.c:1.289 src/sys/nfs/nfs_vnops.c:1.290
--- src/sys/nfs/nfs_vnops.c:1.289	Tue Dec 14 16:58:58 2010
+++ src/sys/nfs/nfs_vnops.c	Sun Apr 24 21:35:30 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_vnops.c,v 1.289 2010/12/14 16:58:58 cegger Exp $	*/
+/*	$NetBSD: nfs_vnops.c,v 1.290 2011/04/24 21:35:30 rmind Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.289 2010/12/14 16:58:58 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.290 2011/04/24 21:35:30 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_nfs.h"
@@ -2050,18 +2050,11 @@
 	struct componentname *cnp = ap->a_cnp;
 	int error = 0;
 
-	if (dvp->v_mount != vp->v_mount) {
+	error = vn_lock(vp, LK_EXCLUSIVE);
+	if (error != 0) {
 		VOP_ABORTOP(dvp, cnp);
 		vput(dvp);
-		return (EXDEV);
-	}
-	if (dvp != vp) {
-		error = vn_lock(vp, LK_EXCLUSIVE);
-		if (error != 0) {
-			VOP_ABORTOP(dvp, cnp);
-			vput(dvp);
-			return error;
-		}
+		return error;
 	}
 
 	/*
@@ -2074,10 +2067,10 @@
 	error = nfs_linkrpc(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
 	    cnp->cn_cred, curlwp);
 
-	if (error == 0)
+	if (error == 0) {
 		cache_purge1(dvp, cnp, 0);
-	if (dvp != vp)
-		VOP_UNLOCK(vp);
+	}
+	VOP_UNLOCK(vp);
 	VN_KNOTE(vp, NOTE_LINK);
 	VN_KNOTE(dvp, NOTE_WRITE);
 	vput(dvp);

Index: src/sys/ufs/ext2fs/ext2fs_vnops.c
diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.97 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.98
--- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.97	Sun Jan  2 05:09:32 2011
+++ src/sys/ufs/ext2fs/ext2fs_vnops.c	Sun Apr 24 21:35:30 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_vnops.c,v 1.97 2011/01/02 05:09:32 dholland Exp $	*/
+/*	$NetBSD: ext2fs_vnops.c,v 1.98 2011/04/24 21:35:30 rmind Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.97 2011/01/02 05:09:32 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.98 2011/04/24 21:35:30 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -552,7 +552,7 @@
 }
 
 /*
- * link vnode call
+ * ext2fs_link: create hard link.
  */
 int
 ext2fs_link(void *v)
@@ -568,17 +568,12 @@
 	struct inode *ip;
 	int error;
 
-	if (vp->v_type == VDIR) {
-		VOP_ABORTOP(dvp, cnp);
-		error = EISDIR;
-		goto out2;
-	}
-	if (dvp->v_mount != vp->v_mount) {
-		VOP_ABORTOP(dvp, cnp);
-		error = EXDEV;
-		goto out2;
-	}
-	if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
+	KASSERT(dvp != vp);
+	KASSERT(vp->v_type != VDIR);
+	KASSERT(dvp->v_mount == vp->v_mount);
+
+	error = vn_lock(vp, LK_EXCLUSIVE);
+	if (error) {
 		VOP_ABORTOP(dvp, cnp);
 		goto out2;
 	}
@@ -603,8 +598,7 @@
 		ip->i_flag |= IN_CHANGE;
 	}
 out1:
-	if (dvp != vp)
-		VOP_UNLOCK(vp);
+	VOP_UNLOCK(vp);
 out2:
 	VN_KNOTE(vp, NOTE_LINK);
 	VN_KNOTE(dvp, NOTE_WRITE);

Index: src/sys/ufs/ufs/ufs_vnops.c
diff -u src/sys/ufs/ufs/ufs_vnops.c:1.187 src/sys/ufs/ufs/ufs_vnops.c:1.188
--- src/sys/ufs/ufs/ufs_vnops.c:1.187	Sun Mar  6 17:08:39 2011
+++ src/sys/ufs/ufs/ufs_vnops.c	Sun Apr 24 21:35:30 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_vnops.c,v 1.187 2011/03/06 17:08:39 bouyer Exp $	*/
+/*	$NetBSD: ufs_vnops.c,v 1.188 2011/04/24 21:35:30 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.187 2011/03/06 17:08:39 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.188 2011/04/24 21:35:30 rmind Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -786,7 +786,7 @@
 }
 
 /*
- * link vnode call
+ * ufs_link: create hard link.
  */
 int
 ufs_link(void *v)
@@ -796,28 +796,20 @@
 		struct vnode *a_vp;
 		struct componentname *a_cnp;
 	} */ *ap = v;
-	struct vnode		*vp, *dvp;
-	struct componentname	*cnp;
-	struct inode		*ip;
-	struct direct		*newdir;
-	int			error;
+	struct vnode *dvp = ap->a_dvp;
+	struct vnode *vp = ap->a_vp;
+	struct componentname *cnp = ap->a_cnp;
+	struct inode *ip;
+	struct direct *newdir;
+	int error;
 
-	dvp = ap->a_dvp;
-	vp = ap->a_vp;
-	cnp = ap->a_cnp;
+	KASSERT(dvp != vp);
+	KASSERT(vp->v_type != VDIR);
+	KASSERT(dvp->v_mount == vp->v_mount);
 
 	fstrans_start(dvp->v_mount, FSTRANS_SHARED);
-	if (vp->v_type == VDIR) {
-		VOP_ABORTOP(dvp, cnp);
-		error = EPERM;
-		goto out2;
-	}
-	if (dvp->v_mount != vp->v_mount) {
-		VOP_ABORTOP(dvp, cnp);
-		error = EXDEV;
-		goto out2;
-	}
-	if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
+	error = vn_lock(vp, LK_EXCLUSIVE);
+	if (error) {
 		VOP_ABORTOP(dvp, cnp);
 		goto out2;
 	}
@@ -855,8 +847,7 @@
 	}
 	UFS_WAPBL_END(vp->v_mount);
  out1:
-	if (dvp != vp)
-		VOP_UNLOCK(vp);
+	VOP_UNLOCK(vp);
  out2:
 	VN_KNOTE(vp, NOTE_LINK);
 	VN_KNOTE(dvp, NOTE_WRITE);

Reply via email to