Sun Apr 24 21:35:30 2011 UTC ()
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@


(rmind)
diff -r1.9 -r1.10 src/sys/fs/nilfs/nilfs_vnops.c
diff -r1.76 -r1.77 src/sys/fs/tmpfs/tmpfs_vnops.c
diff -r1.62 -r1.63 src/sys/fs/udf/udf_vnops.c
diff -r1.422 -r1.423 src/sys/kern/vfs_syscalls.c
diff -r1.289 -r1.290 src/sys/nfs/nfs_vnops.c
diff -r1.97 -r1.98 src/sys/ufs/ext2fs/ext2fs_vnops.c
diff -r1.187 -r1.188 src/sys/ufs/ufs/ufs_vnops.c

cvs diff -r1.9 -r1.10 src/sys/fs/nilfs/nilfs_vnops.c (expand / switch to unified diff)

--- src/sys/fs/nilfs/nilfs_vnops.c 2010/11/30 10:43:03 1.9
+++ src/sys/fs/nilfs/nilfs_vnops.c 2011/04/24 21:35:29 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nilfs_vnops.c,v 1.9 2010/11/30 10:43:03 dholland Exp $ */ 1/* $NetBSD: nilfs_vnops.c,v 1.10 2011/04/24 21:35:29 rmind Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008, 2009 Reinoud Zandijk 4 * Copyright (c) 2008, 2009 Reinoud Zandijk
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -18,27 +18,27 @@ @@ -18,27 +18,27 @@
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *  26 *
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30#ifndef lint 30#ifndef lint
31__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.9 2010/11/30 10:43:03 dholland Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.10 2011/04/24 21:35:29 rmind Exp $");
32#endif /* not lint */ 32#endif /* not lint */
33 33
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/namei.h> 37#include <sys/namei.h>
38#include <sys/resourcevar.h> /* defines plimit structure in proc struct */ 38#include <sys/resourcevar.h> /* defines plimit structure in proc struct */
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/file.h> /* define FWRITE ... */ 40#include <sys/file.h> /* define FWRITE ... */
41#include <sys/stat.h> 41#include <sys/stat.h>
42#include <sys/buf.h> 42#include <sys/buf.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44#include <sys/mount.h> 44#include <sys/mount.h>
@@ -1149,35 +1149,29 @@ nilfs_mkdir(void *v) @@ -1149,35 +1149,29 @@ nilfs_mkdir(void *v)
1149 return error; 1149 return error;
1150} 1150}
1151 1151
1152/* --------------------------------------------------------------------- */ 1152/* --------------------------------------------------------------------- */
1153 1153
1154static int 1154static int
1155nilfs_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1155nilfs_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
1156{ 1156{
1157 struct nilfs_node *nilfs_node, *dir_node; 1157 struct nilfs_node *nilfs_node, *dir_node;
1158 struct vattr vap; 1158 struct vattr vap;
1159 int error; 1159 int error;
1160 1160
1161 DPRINTF(VFSCALL, ("nilfs_link called\n")); 1161 DPRINTF(VFSCALL, ("nilfs_link called\n"));
1162 error = 0; 1162 KASSERT(dvp != vp);
1163 1163 KASSERT(vp->v_type != VDIR);
1164 /* some quick checks */ 1164 KASSERT(dvp->v_mount == vp->v_mount);
1165 if (vp->v_type == VDIR) 
1166 return EPERM; /* can't link a directory */ 
1167 if (dvp->v_mount != vp->v_mount) 
1168 return EXDEV; /* can't link across devices */ 
1169 if (dvp == vp) 
1170 return EPERM; /* can't be the same */ 
1171 1165
1172 /* lock node */ 1166 /* lock node */
1173 error = vn_lock(vp, LK_EXCLUSIVE); 1167 error = vn_lock(vp, LK_EXCLUSIVE);
1174 if (error) 1168 if (error)
1175 return error; 1169 return error;
1176 1170
1177 /* get attributes */ 1171 /* get attributes */
1178 dir_node = VTOI(dvp); 1172 dir_node = VTOI(dvp);
1179 nilfs_node = VTOI(vp); 1173 nilfs_node = VTOI(vp);
1180 1174
1181 error = VOP_GETATTR(vp, &vap, FSCRED); 1175 error = VOP_GETATTR(vp, &vap, FSCRED);
1182 if (error) { 1176 if (error) {
1183 VOP_UNLOCK(vp); 1177 VOP_UNLOCK(vp);

cvs diff -r1.76 -r1.77 src/sys/fs/tmpfs/tmpfs_vnops.c (expand / switch to unified diff)

--- src/sys/fs/tmpfs/tmpfs_vnops.c 2011/01/13 13:35:12 1.76
+++ src/sys/fs/tmpfs/tmpfs_vnops.c 2011/04/24 21:35:29 1.77
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tmpfs_vnops.c,v 1.76 2011/01/13 13:35:12 pooka Exp $ */ 1/* $NetBSD: tmpfs_vnops.c,v 1.77 2011/04/24 21:35:29 rmind Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
9 * 2005 program. 9 * 2005 program.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * tmpfs vnode interface. 34 * tmpfs vnode interface.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.76 2011/01/13 13:35:12 pooka Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.77 2011/04/24 21:35:29 rmind Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/dirent.h> 41#include <sys/dirent.h>
42#include <sys/fcntl.h> 42#include <sys/fcntl.h>
43#include <sys/event.h> 43#include <sys/event.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
45#include <sys/namei.h> 45#include <sys/namei.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47#include <sys/stat.h> 47#include <sys/stat.h>
48#include <sys/uio.h> 48#include <sys/uio.h>
49#include <sys/unistd.h> 49#include <sys/unistd.h>
50#include <sys/vnode.h> 50#include <sys/vnode.h>
51#include <sys/lockf.h> 51#include <sys/lockf.h>
@@ -727,64 +727,54 @@ tmpfs_remove(void *v) @@ -727,64 +727,54 @@ tmpfs_remove(void *v)
727 727
728 error = 0; 728 error = 0;
729 729
730out: 730out:
731 vput(vp); 731 vput(vp);
732 if (dvp == vp) 732 if (dvp == vp)
733 vrele(dvp); 733 vrele(dvp);
734 else 734 else
735 vput(dvp); 735 vput(dvp);
736 736
737 return error; 737 return error;
738} 738}
739 739
740/* --------------------------------------------------------------------- */ 740/*
741 741 * tmpfs:link: create hard link.
 742 */
742int 743int
743tmpfs_link(void *v) 744tmpfs_link(void *v)
744{ 745{
745 struct vnode *dvp = ((struct vop_link_args *)v)->a_dvp; 746 struct vop_link_args /* {
746 struct vnode *vp = ((struct vop_link_args *)v)->a_vp; 747 struct vnode *a_dvp;
747 struct componentname *cnp = ((struct vop_link_args *)v)->a_cnp; 748 struct vnode *a_vp;
748 749 struct componentname *a_cnp;
749 int error; 750 } */ *ap = v;
 751 struct vnode *dvp = ap->a_dvp;
 752 struct vnode *vp = ap->a_vp;
 753 struct componentname *cnp = ap->a_cnp;;
 754 struct tmpfs_node *dnode, *node;
750 struct tmpfs_dirent *de; 755 struct tmpfs_dirent *de;
751 struct tmpfs_node *dnode; 756 int error;
752 struct tmpfs_node *node; 
753 757
 758 KASSERT(dvp != vp);
754 KASSERT(VOP_ISLOCKED(dvp)); 759 KASSERT(VOP_ISLOCKED(dvp));
755 KASSERT(dvp != vp); /* XXX When can this be false? */ 760 KASSERT(vp->v_type != VDIR);
 761 KASSERT(dvp->v_mount == vp->v_mount);
756 762
757 dnode = VP_TO_TMPFS_DIR(dvp); 763 dnode = VP_TO_TMPFS_DIR(dvp);
758 node = VP_TO_TMPFS_NODE(vp); 764 node = VP_TO_TMPFS_NODE(vp);
759 765
760 /* Lock vp because we will need to run tmpfs_update over it, which 
761 * needs the vnode to be locked. */ 
762 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 766 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
763 767
764 /* XXX: Why aren't the following two tests done by the caller? */ 
765 
766 /* Hard links of directories are forbidden. */ 
767 if (vp->v_type == VDIR) { 
768 error = EPERM; 
769 goto out; 
770 } 
771 
772 /* Cannot create cross-device links. */ 
773 if (dvp->v_mount != vp->v_mount) { 
774 error = EXDEV; 
775 goto out; 
776 } 
777 
778 /* Ensure that we do not overflow the maximum number of links imposed 768 /* Ensure that we do not overflow the maximum number of links imposed
779 * by the system. */ 769 * by the system. */
780 KASSERT(node->tn_links <= LINK_MAX); 770 KASSERT(node->tn_links <= LINK_MAX);
781 if (node->tn_links == LINK_MAX) { 771 if (node->tn_links == LINK_MAX) {
782 error = EMLINK; 772 error = EMLINK;
783 goto out; 773 goto out;
784 } 774 }
785 775
786 /* We cannot create links of files marked immutable or append-only. */ 776 /* We cannot create links of files marked immutable or append-only. */
787 if (node->tn_flags & (IMMUTABLE | APPEND)) { 777 if (node->tn_flags & (IMMUTABLE | APPEND)) {
788 error = EPERM; 778 error = EPERM;
789 goto out; 779 goto out;
790 } 780 }

cvs diff -r1.62 -r1.63 src/sys/fs/udf/udf_vnops.c (expand / switch to unified diff)

--- src/sys/fs/udf/udf_vnops.c 2011/01/02 05:09:30 1.62
+++ src/sys/fs/udf/udf_vnops.c 2011/04/24 21:35:30 1.63
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: udf_vnops.c,v 1.62 2011/01/02 05:09:30 dholland Exp $ */ 1/* $NetBSD: udf_vnops.c,v 1.63 2011/04/24 21:35:30 rmind Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006, 2008 Reinoud Zandijk 4 * Copyright (c) 2006, 2008 Reinoud Zandijk
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *  26 *
27 * Generic parts are derived from software contributed to The NetBSD Foundation 27 * Generic parts are derived from software contributed to The NetBSD Foundation
28 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 28 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
29 * 2005 program. 29 * 2005 program.
30 * 30 *
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34#ifndef lint 34#ifndef lint
35__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.62 2011/01/02 05:09:30 dholland Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.63 2011/04/24 21:35:30 rmind Exp $");
36#endif /* not lint */ 36#endif /* not lint */
37 37
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/namei.h> 41#include <sys/namei.h>
42#include <sys/resourcevar.h> /* defines plimit structure in proc struct */ 42#include <sys/resourcevar.h> /* defines plimit structure in proc struct */
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/file.h> /* define FWRITE ... */ 44#include <sys/file.h> /* define FWRITE ... */
45#include <sys/stat.h> 45#include <sys/stat.h>
46#include <sys/buf.h> 46#include <sys/buf.h>
47#include <sys/proc.h> 47#include <sys/proc.h>
48#include <sys/mount.h> 48#include <sys/mount.h>
@@ -1471,35 +1471,29 @@ udf_mkdir(void *v) @@ -1471,35 +1471,29 @@ udf_mkdir(void *v)
1471 return error; 1471 return error;
1472} 1472}
1473 1473
1474/* --------------------------------------------------------------------- */ 1474/* --------------------------------------------------------------------- */
1475 1475
1476static int 1476static int
1477udf_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1477udf_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
1478{ 1478{
1479 struct udf_node *udf_node, *dir_node; 1479 struct udf_node *udf_node, *dir_node;
1480 struct vattr vap; 1480 struct vattr vap;
1481 int error; 1481 int error;
1482 1482
1483 DPRINTF(CALL, ("udf_link called\n")); 1483 DPRINTF(CALL, ("udf_link called\n"));
1484 error = 0; 1484 KASSERT(dvp != vp);
1485 1485 KASSERT(vp->v_type != VDIR);
1486 /* some quick checks */ 1486 KASSERT(dvp->v_mount == vp->v_mount);
1487 if (vp->v_type == VDIR) 
1488 return EPERM; /* can't link a directory */ 
1489 if (dvp->v_mount != vp->v_mount) 
1490 return EXDEV; /* can't link across devices */ 
1491 if (dvp == vp) 
1492 return EPERM; /* can't be the same */ 
1493 1487
1494 /* lock node */ 1488 /* lock node */
1495 error = vn_lock(vp, LK_EXCLUSIVE); 1489 error = vn_lock(vp, LK_EXCLUSIVE);
1496 if (error) 1490 if (error)
1497 return error; 1491 return error;
1498 1492
1499 /* get attributes */ 1493 /* get attributes */
1500 dir_node = VTOI(dvp); 1494 dir_node = VTOI(dvp);
1501 udf_node = VTOI(vp); 1495 udf_node = VTOI(vp);
1502 1496
1503 error = VOP_GETATTR(vp, &vap, FSCRED); 1497 error = VOP_GETATTR(vp, &vap, FSCRED);
1504 if (error) { 1498 if (error) {
1505 VOP_UNLOCK(vp); 1499 VOP_UNLOCK(vp);

cvs diff -r1.422 -r1.423 src/sys/kern/vfs_syscalls.c (expand / switch to unified diff)

--- src/sys/kern/vfs_syscalls.c 2011/04/10 15:45:33 1.422
+++ src/sys/kern/vfs_syscalls.c 2011/04/24 21:35:29 1.423
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $ */ 1/* $NetBSD: vfs_syscalls.c,v 1.423 2011/04/24 21:35:29 rmind Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -60,27 +60,27 @@ @@ -60,27 +60,27 @@
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)vfs_syscalls.c 8.42 (Berkeley) 7/31/95 65 * @(#)vfs_syscalls.c 8.42 (Berkeley) 7/31/95
66 */ 66 */
67 67
68/* 68/*
69 * Virtual File System System Calls 69 * Virtual File System System Calls
70 */ 70 */
71 71
72#include <sys/cdefs.h> 72#include <sys/cdefs.h>
73__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.422 2011/04/10 15:45:33 christos Exp $"); 73__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.423 2011/04/24 21:35:29 rmind Exp $");
74 74
75#ifdef _KERNEL_OPT 75#ifdef _KERNEL_OPT
76#include "opt_fileassoc.h" 76#include "opt_fileassoc.h"
77#include "veriexec.h" 77#include "veriexec.h"
78#endif 78#endif
79 79
80#include <sys/param.h> 80#include <sys/param.h>
81#include <sys/systm.h> 81#include <sys/systm.h>
82#include <sys/namei.h> 82#include <sys/namei.h>
83#include <sys/filedesc.h> 83#include <sys/filedesc.h>
84#include <sys/kernel.h> 84#include <sys/kernel.h>
85#include <sys/file.h> 85#include <sys/file.h>
86#include <sys/stat.h> 86#include <sys/stat.h>
@@ -1757,29 +1757,32 @@ sys_link(struct lwp *l, const struct sys @@ -1757,29 +1757,32 @@ sys_link(struct lwp *l, const struct sys
1757 if (error != 0) 1757 if (error != 0)
1758 return (error); 1758 return (error);
1759 error = pathbuf_copyin(SCARG(uap, link), &linkpb); 1759 error = pathbuf_copyin(SCARG(uap, link), &linkpb);
1760 if (error) { 1760 if (error) {
1761 goto out1; 1761 goto out1;
1762 } 1762 }
1763 NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb); 1763 NDINIT(&nd, CREATE, LOCKPARENT | TRYEMULROOT, linkpb);
1764 if ((error = namei(&nd)) != 0) 1764 if ((error = namei(&nd)) != 0)
1765 goto out2; 1765 goto out2;
1766 if (nd.ni_vp) { 1766 if (nd.ni_vp) {
1767 error = EEXIST; 1767 error = EEXIST;
1768 goto abortop; 1768 goto abortop;
1769 } 1769 }
1770 /* 1770 /* Prevent hard links on directories. */
1771 * Prevent cross-mount operation. 1771 if (vp->v_type == VDIR) {
1772 */ 1772 error = EPERM;
 1773 goto abortop;
 1774 }
 1775 /* Prevent cross-mount operation. */
1773 if (nd.ni_dvp->v_mount != vp->v_mount) { 1776 if (nd.ni_dvp->v_mount != vp->v_mount) {
1774 error = EXDEV; 1777 error = EXDEV;
1775 goto abortop; 1778 goto abortop;
1776 } 1779 }
1777 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1780 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1778out2: 1781out2:
1779 pathbuf_destroy(linkpb); 1782 pathbuf_destroy(linkpb);
1780out1: 1783out1:
1781 vrele(vp); 1784 vrele(vp);
1782 return (error); 1785 return (error);
1783abortop: 1786abortop:
1784 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1787 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1785 if (nd.ni_dvp == nd.ni_vp) 1788 if (nd.ni_dvp == nd.ni_vp)

cvs diff -r1.289 -r1.290 src/sys/nfs/nfs_vnops.c (expand / switch to unified diff)

--- src/sys/nfs/nfs_vnops.c 2010/12/14 16:58:58 1.289
+++ src/sys/nfs/nfs_vnops.c 2011/04/24 21:35:30 1.290
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nfs_vnops.c,v 1.289 2010/12/14 16:58:58 cegger Exp $ */ 1/* $NetBSD: nfs_vnops.c,v 1.290 2011/04/24 21:35:30 rmind Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph. 8 * Rick Macklem at The University of Guelph.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * @(#)nfs_vnops.c 8.19 (Berkeley) 7/31/95 34 * @(#)nfs_vnops.c 8.19 (Berkeley) 7/31/95
35 */ 35 */
36 36
37/* 37/*
38 * vnode op calls for Sun NFS version 2 and 3 38 * vnode op calls for Sun NFS version 2 and 3
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.289 2010/12/14 16:58:58 cegger Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.290 2011/04/24 21:35:30 rmind Exp $");
43 43
44#ifdef _KERNEL_OPT 44#ifdef _KERNEL_OPT
45#include "opt_nfs.h" 45#include "opt_nfs.h"
46#include "opt_uvmhist.h" 46#include "opt_uvmhist.h"
47#endif 47#endif
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/proc.h> 50#include <sys/proc.h>
51#include <sys/kernel.h> 51#include <sys/kernel.h>
52#include <sys/systm.h> 52#include <sys/systm.h>
53#include <sys/resourcevar.h> 53#include <sys/resourcevar.h>
54#include <sys/mount.h> 54#include <sys/mount.h>
55#include <sys/buf.h> 55#include <sys/buf.h>
@@ -2040,54 +2040,47 @@ nfs_linkrpc(struct vnode *dvp, struct vn @@ -2040,54 +2040,47 @@ nfs_linkrpc(struct vnode *dvp, struct vn
2040int 2040int
2041nfs_link(void *v) 2041nfs_link(void *v)
2042{ 2042{
2043 struct vop_link_args /* { 2043 struct vop_link_args /* {
2044 struct vnode *a_dvp; 2044 struct vnode *a_dvp;
2045 struct vnode *a_vp; 2045 struct vnode *a_vp;
2046 struct componentname *a_cnp; 2046 struct componentname *a_cnp;
2047 } */ *ap = v; 2047 } */ *ap = v;
2048 struct vnode *vp = ap->a_vp; 2048 struct vnode *vp = ap->a_vp;
2049 struct vnode *dvp = ap->a_dvp; 2049 struct vnode *dvp = ap->a_dvp;
2050 struct componentname *cnp = ap->a_cnp; 2050 struct componentname *cnp = ap->a_cnp;
2051 int error = 0; 2051 int error = 0;
2052 2052
2053 if (dvp->v_mount != vp->v_mount) { 2053 error = vn_lock(vp, LK_EXCLUSIVE);
 2054 if (error != 0) {
2054 VOP_ABORTOP(dvp, cnp); 2055 VOP_ABORTOP(dvp, cnp);
2055 vput(dvp); 2056 vput(dvp);
2056 return (EXDEV); 2057 return error;
2057 } 
2058 if (dvp != vp) { 
2059 error = vn_lock(vp, LK_EXCLUSIVE); 
2060 if (error != 0) { 
2061 VOP_ABORTOP(dvp, cnp); 
2062 vput(dvp); 
2063 return error; 
2064 } 
2065 } 2058 }
2066 2059
2067 /* 2060 /*
2068 * Push all writes to the server, so that the attribute cache 2061 * Push all writes to the server, so that the attribute cache
2069 * doesn't get "out of sync" with the server. 2062 * doesn't get "out of sync" with the server.
2070 * XXX There should be a better way! 2063 * XXX There should be a better way!
2071 */ 2064 */
2072 VOP_FSYNC(vp, cnp->cn_cred, FSYNC_WAIT, 0, 0); 2065 VOP_FSYNC(vp, cnp->cn_cred, FSYNC_WAIT, 0, 0);
2073 2066
2074 error = nfs_linkrpc(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen, 2067 error = nfs_linkrpc(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
2075 cnp->cn_cred, curlwp); 2068 cnp->cn_cred, curlwp);
2076 2069
2077 if (error == 0) 2070 if (error == 0) {
2078 cache_purge1(dvp, cnp, 0); 2071 cache_purge1(dvp, cnp, 0);
2079 if (dvp != vp) 2072 }
2080 VOP_UNLOCK(vp); 2073 VOP_UNLOCK(vp);
2081 VN_KNOTE(vp, NOTE_LINK); 2074 VN_KNOTE(vp, NOTE_LINK);
2082 VN_KNOTE(dvp, NOTE_WRITE); 2075 VN_KNOTE(dvp, NOTE_WRITE);
2083 vput(dvp); 2076 vput(dvp);
2084 return (error); 2077 return (error);
2085} 2078}
2086 2079
2087/* 2080/*
2088 * nfs symbolic link create call 2081 * nfs symbolic link create call
2089 */ 2082 */
2090int 2083int
2091nfs_symlink(void *v) 2084nfs_symlink(void *v)
2092{ 2085{
2093 struct vop_symlink_args /* { 2086 struct vop_symlink_args /* {

cvs diff -r1.97 -r1.98 src/sys/ufs/ext2fs/ext2fs_vnops.c (expand / switch to unified diff)

--- src/sys/ufs/ext2fs/ext2fs_vnops.c 2011/01/02 05:09:32 1.97
+++ src/sys/ufs/ext2fs/ext2fs_vnops.c 2011/04/24 21:35:30 1.98
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ext2fs_vnops.c,v 1.97 2011/01/02 05:09:32 dholland Exp $ */ 1/* $NetBSD: ext2fs_vnops.c,v 1.98 2011/04/24 21:35:30 rmind Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1986, 1989, 1993 4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc. 6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed 7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph 8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc. 10 * the permission of UNIX System Laboratories, Inc.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -55,27 +55,27 @@ @@ -55,27 +55,27 @@
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 * 62 *
63 * @(#)ufs_vnops.c 8.14 (Berkeley) 10/26/94 63 * @(#)ufs_vnops.c 8.14 (Berkeley) 10/26/94
64 * Modified for ext2fs by Manuel Bouyer. 64 * Modified for ext2fs by Manuel Bouyer.
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.97 2011/01/02 05:09:32 dholland Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.98 2011/04/24 21:35:30 rmind Exp $");
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/systm.h> 71#include <sys/systm.h>
72#include <sys/resourcevar.h> 72#include <sys/resourcevar.h>
73#include <sys/kernel.h> 73#include <sys/kernel.h>
74#include <sys/file.h> 74#include <sys/file.h>
75#include <sys/stat.h> 75#include <sys/stat.h>
76#include <sys/buf.h> 76#include <sys/buf.h>
77#include <sys/proc.h> 77#include <sys/proc.h>
78#include <sys/mount.h> 78#include <sys/mount.h>
79#include <sys/namei.h> 79#include <sys/namei.h>
80#include <sys/vnode.h> 80#include <sys/vnode.h>
81#include <sys/lockf.h> 81#include <sys/lockf.h>
@@ -542,79 +542,73 @@ ext2fs_remove(void *v) @@ -542,79 +542,73 @@ ext2fs_remove(void *v)
542 } 542 }
543 543
544 VN_KNOTE(vp, NOTE_DELETE); 544 VN_KNOTE(vp, NOTE_DELETE);
545 VN_KNOTE(dvp, NOTE_WRITE); 545 VN_KNOTE(dvp, NOTE_WRITE);
546 if (dvp == vp) 546 if (dvp == vp)
547 vrele(vp); 547 vrele(vp);
548 else 548 else
549 vput(vp); 549 vput(vp);
550 vput(dvp); 550 vput(dvp);
551 return (error); 551 return (error);
552} 552}
553 553
554/* 554/*
555 * link vnode call 555 * ext2fs_link: create hard link.
556 */ 556 */
557int 557int
558ext2fs_link(void *v) 558ext2fs_link(void *v)
559{ 559{
560 struct vop_link_args /* { 560 struct vop_link_args /* {
561 struct vnode *a_dvp; 561 struct vnode *a_dvp;
562 struct vnode *a_vp; 562 struct vnode *a_vp;
563 struct componentname *a_cnp; 563 struct componentname *a_cnp;
564 } */ *ap = v; 564 } */ *ap = v;
565 struct vnode *dvp = ap->a_dvp; 565 struct vnode *dvp = ap->a_dvp;
566 struct vnode *vp = ap->a_vp; 566 struct vnode *vp = ap->a_vp;
567 struct componentname *cnp = ap->a_cnp; 567 struct componentname *cnp = ap->a_cnp;
568 struct inode *ip; 568 struct inode *ip;
569 int error; 569 int error;
570 570
571 if (vp->v_type == VDIR) { 571 KASSERT(dvp != vp);
572 VOP_ABORTOP(dvp, cnp); 572 KASSERT(vp->v_type != VDIR);
573 error = EISDIR; 573 KASSERT(dvp->v_mount == vp->v_mount);
574 goto out2; 574
575 } 575 error = vn_lock(vp, LK_EXCLUSIVE);
576 if (dvp->v_mount != vp->v_mount) { 576 if (error) {
577 VOP_ABORTOP(dvp, cnp); 
578 error = EXDEV; 
579 goto out2; 
580 } 
581 if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) { 
582 VOP_ABORTOP(dvp, cnp); 577 VOP_ABORTOP(dvp, cnp);
583 goto out2; 578 goto out2;
584 } 579 }
585 ip = VTOI(vp); 580 ip = VTOI(vp);
586 if ((nlink_t)ip->i_e2fs_nlink >= LINK_MAX) { 581 if ((nlink_t)ip->i_e2fs_nlink >= LINK_MAX) {
587 VOP_ABORTOP(dvp, cnp); 582 VOP_ABORTOP(dvp, cnp);
588 error = EMLINK; 583 error = EMLINK;
589 goto out1; 584 goto out1;
590 } 585 }
591 if (ip->i_e2fs_flags & (EXT2_IMMUTABLE | EXT2_APPEND)) { 586 if (ip->i_e2fs_flags & (EXT2_IMMUTABLE | EXT2_APPEND)) {
592 VOP_ABORTOP(dvp, cnp); 587 VOP_ABORTOP(dvp, cnp);
593 error = EPERM; 588 error = EPERM;
594 goto out1; 589 goto out1;
595 } 590 }
596 ip->i_e2fs_nlink++; 591 ip->i_e2fs_nlink++;
597 ip->i_flag |= IN_CHANGE; 592 ip->i_flag |= IN_CHANGE;
598 error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT); 593 error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
599 if (!error) 594 if (!error)
600 error = ext2fs_direnter(ip, dvp, cnp); 595 error = ext2fs_direnter(ip, dvp, cnp);
601 if (error) { 596 if (error) {
602 ip->i_e2fs_nlink--; 597 ip->i_e2fs_nlink--;
603 ip->i_flag |= IN_CHANGE; 598 ip->i_flag |= IN_CHANGE;
604 } 599 }
605out1: 600out1:
606 if (dvp != vp) 601 VOP_UNLOCK(vp);
607 VOP_UNLOCK(vp); 
608out2: 602out2:
609 VN_KNOTE(vp, NOTE_LINK); 603 VN_KNOTE(vp, NOTE_LINK);
610 VN_KNOTE(dvp, NOTE_WRITE); 604 VN_KNOTE(dvp, NOTE_WRITE);
611 vput(dvp); 605 vput(dvp);
612 return (error); 606 return (error);
613} 607}
614 608
615/* 609/*
616 * Rename system call. 610 * Rename system call.
617 * rename("foo", "bar"); 611 * rename("foo", "bar");
618 * is essentially 612 * is essentially
619 * unlink("bar"); 613 * unlink("bar");
620 * link("foo", "bar"); 614 * link("foo", "bar");

cvs diff -r1.187 -r1.188 src/sys/ufs/ufs/ufs_vnops.c (expand / switch to unified diff)

--- src/sys/ufs/ufs/ufs_vnops.c 2011/03/06 17:08:39 1.187
+++ src/sys/ufs/ufs/ufs_vnops.c 2011/04/24 21:35:30 1.188
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ufs_vnops.c,v 1.187 2011/03/06 17:08:39 bouyer Exp $ */ 1/* $NetBSD: ufs_vnops.c,v 1.188 2011/04/24 21:35:30 rmind Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc. 8 * by Wasabi Systems, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -56,27 +56,27 @@ @@ -56,27 +56,27 @@
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)ufs_vnops.c 8.28 (Berkeley) 7/31/95 65 * @(#)ufs_vnops.c 8.28 (Berkeley) 7/31/95
66 */ 66 */
67 67
68#include <sys/cdefs.h> 68#include <sys/cdefs.h>
69__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.187 2011/03/06 17:08:39 bouyer Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.188 2011/04/24 21:35:30 rmind Exp $");
70 70
71#if defined(_KERNEL_OPT) 71#if defined(_KERNEL_OPT)
72#include "opt_ffs.h" 72#include "opt_ffs.h"
73#include "opt_quota.h" 73#include "opt_quota.h"
74#endif 74#endif
75 75
76#include <sys/param.h> 76#include <sys/param.h>
77#include <sys/systm.h> 77#include <sys/systm.h>
78#include <sys/namei.h> 78#include <sys/namei.h>
79#include <sys/resourcevar.h> 79#include <sys/resourcevar.h>
80#include <sys/kernel.h> 80#include <sys/kernel.h>
81#include <sys/file.h> 81#include <sys/file.h>
82#include <sys/stat.h> 82#include <sys/stat.h>
@@ -776,58 +776,50 @@ ufs_remove(void *v) @@ -776,58 +776,50 @@ ufs_remove(void *v)
776 } 776 }
777 VN_KNOTE(vp, NOTE_DELETE); 777 VN_KNOTE(vp, NOTE_DELETE);
778 VN_KNOTE(dvp, NOTE_WRITE); 778 VN_KNOTE(dvp, NOTE_WRITE);
779 if (dvp == vp) 779 if (dvp == vp)
780 vrele(vp); 780 vrele(vp);
781 else 781 else
782 vput(vp); 782 vput(vp);
783 vput(dvp); 783 vput(dvp);
784 fstrans_done(dvp->v_mount); 784 fstrans_done(dvp->v_mount);
785 return (error); 785 return (error);
786} 786}
787 787
788/* 788/*
789 * link vnode call 789 * ufs_link: create hard link.
790 */ 790 */
791int 791int
792ufs_link(void *v) 792ufs_link(void *v)
793{ 793{
794 struct vop_link_args /* { 794 struct vop_link_args /* {
795 struct vnode *a_dvp; 795 struct vnode *a_dvp;
796 struct vnode *a_vp; 796 struct vnode *a_vp;
797 struct componentname *a_cnp; 797 struct componentname *a_cnp;
798 } */ *ap = v; 798 } */ *ap = v;
799 struct vnode *vp, *dvp; 799 struct vnode *dvp = ap->a_dvp;
800 struct componentname *cnp; 800 struct vnode *vp = ap->a_vp;
801 struct inode *ip; 801 struct componentname *cnp = ap->a_cnp;
802 struct direct *newdir; 802 struct inode *ip;
803 int error; 803 struct direct *newdir;
 804 int error;
804 805
805 dvp = ap->a_dvp; 806 KASSERT(dvp != vp);
806 vp = ap->a_vp; 807 KASSERT(vp->v_type != VDIR);
807 cnp = ap->a_cnp; 808 KASSERT(dvp->v_mount == vp->v_mount);
808 809
809 fstrans_start(dvp->v_mount, FSTRANS_SHARED); 810 fstrans_start(dvp->v_mount, FSTRANS_SHARED);
810 if (vp->v_type == VDIR) { 811 error = vn_lock(vp, LK_EXCLUSIVE);
811 VOP_ABORTOP(dvp, cnp); 812 if (error) {
812 error = EPERM; 
813 goto out2; 
814 } 
815 if (dvp->v_mount != vp->v_mount) { 
816 VOP_ABORTOP(dvp, cnp); 
817 error = EXDEV; 
818 goto out2; 
819 } 
820 if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) { 
821 VOP_ABORTOP(dvp, cnp); 813 VOP_ABORTOP(dvp, cnp);
822 goto out2; 814 goto out2;
823 } 815 }
824 ip = VTOI(vp); 816 ip = VTOI(vp);
825 if ((nlink_t)ip->i_nlink >= LINK_MAX) { 817 if ((nlink_t)ip->i_nlink >= LINK_MAX) {
826 VOP_ABORTOP(dvp, cnp); 818 VOP_ABORTOP(dvp, cnp);
827 error = EMLINK; 819 error = EMLINK;
828 goto out1; 820 goto out1;
829 } 821 }
830 if (ip->i_flags & (IMMUTABLE | APPEND)) { 822 if (ip->i_flags & (IMMUTABLE | APPEND)) {
831 VOP_ABORTOP(dvp, cnp); 823 VOP_ABORTOP(dvp, cnp);
832 error = EPERM; 824 error = EPERM;
833 goto out1; 825 goto out1;
@@ -845,28 +837,27 @@ ufs_link(void *v) @@ -845,28 +837,27 @@ ufs_link(void *v)
845 newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK); 837 newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK);
846 ufs_makedirentry(ip, cnp, newdir); 838 ufs_makedirentry(ip, cnp, newdir);
847 error = ufs_direnter(dvp, vp, newdir, cnp, NULL); 839 error = ufs_direnter(dvp, vp, newdir, cnp, NULL);
848 pool_cache_put(ufs_direct_cache, newdir); 840 pool_cache_put(ufs_direct_cache, newdir);
849 } 841 }
850 if (error) { 842 if (error) {
851 ip->i_nlink--; 843 ip->i_nlink--;
852 DIP_ASSIGN(ip, nlink, ip->i_nlink); 844 DIP_ASSIGN(ip, nlink, ip->i_nlink);
853 ip->i_flag |= IN_CHANGE; 845 ip->i_flag |= IN_CHANGE;
854 UFS_WAPBL_UPDATE(vp, NULL, NULL, UPDATE_DIROP); 846 UFS_WAPBL_UPDATE(vp, NULL, NULL, UPDATE_DIROP);
855 } 847 }
856 UFS_WAPBL_END(vp->v_mount); 848 UFS_WAPBL_END(vp->v_mount);
857 out1: 849 out1:
858 if (dvp != vp) 850 VOP_UNLOCK(vp);
859 VOP_UNLOCK(vp); 
860 out2: 851 out2:
861 VN_KNOTE(vp, NOTE_LINK); 852 VN_KNOTE(vp, NOTE_LINK);
862 VN_KNOTE(dvp, NOTE_WRITE); 853 VN_KNOTE(dvp, NOTE_WRITE);
863 vput(dvp); 854 vput(dvp);
864 fstrans_done(dvp->v_mount); 855 fstrans_done(dvp->v_mount);
865 return (error); 856 return (error);
866} 857}
867 858
868/* 859/*
869 * whiteout vnode call 860 * whiteout vnode call
870 */ 861 */
871int 862int
872ufs_whiteout(void *v) 863ufs_whiteout(void *v)