Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/udf Fix locking in udf_link(). XXX: udf_symlink is pr...
details: https://anonhg.NetBSD.org/src/rev/a87308285a1b
branches: trunk
changeset: 364579:a87308285a1b
user: christos <christos%NetBSD.org@localhost>
date: Wed Mar 30 13:23:59 2022 +0000
description:
Fix locking in udf_link(). XXX: udf_symlink is prolly similarly broken.
diffstat:
sys/fs/udf/udf_vnops.c | 79 +++++++++++++++++++++++--------------------------
1 files changed, 37 insertions(+), 42 deletions(-)
diffs (110 lines):
diff -r 3882ffab6c23 -r a87308285a1b sys/fs/udf/udf_vnops.c
--- a/sys/fs/udf/udf_vnops.c Wed Mar 30 12:45:58 2022 +0000
+++ b/sys/fs/udf/udf_vnops.c Wed Mar 30 13:23:59 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vnops.c,v 1.120 2022/03/27 16:24:58 christos Exp $ */
+/* $NetBSD: udf_vnops.c,v 1.121 2022/03/30 13:23:59 christos 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.120 2022/03/27 16:24:58 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.121 2022/03/30 13:23:59 christos Exp $");
#endif /* not lint */
@@ -1542,43 +1542,6 @@
/* --------------------------------------------------------------------- */
-static int
-udf_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
-{
- struct udf_node *udf_node, *dir_node;
- struct vattr vap;
- int error;
-
- DPRINTF(CALL, ("udf_link called\n"));
- KASSERT(dvp != vp);
- KASSERT(vp->v_type != VDIR);
- KASSERT(dvp->v_mount == vp->v_mount);
-
- /* get attributes */
- dir_node = VTOI(dvp);
- udf_node = VTOI(vp);
-
- error = VOP_GETATTR(vp, &vap, FSCRED);
- if (error)
- goto out;
-
- /* check link count overflow */
- if (vap.va_nlink >= (1<<16)-1) { /* uint16_t */
- error = EMLINK;
- goto out;
- }
- error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp,
- dvp, 0);
- if (error)
- goto out;
-
- error = udf_dir_attach(dir_node->ump, dir_node, udf_node, &vap, cnp);
-out:
- if (error)
- VOP_UNLOCK(vp);
- return error;
-}
-
int
udf_link(void *v)
{
@@ -1590,12 +1553,44 @@
struct vnode *dvp = ap->a_dvp;
struct vnode *vp = ap->a_vp;
struct componentname *cnp = ap->a_cnp;
- int error;
+ struct udf_node *udf_node, *dir_node;
+ struct vattr vap;
+ int error, abrt = 1;
+
+ DPRINTF(CALL, ("udf_link called\n"));
+ KASSERT(dvp != vp);
+ KASSERT(vp->v_type != VDIR);
+ KASSERT(dvp->v_mount == vp->v_mount);
+
+ /* get attributes */
+ dir_node = VTOI(dvp);
+ udf_node = VTOI(vp);
+
+ if ((error = vn_lock(vp, LK_EXCLUSIVE))) {
+ DPRINTF("lock failed. %p\n", vp);
+ goto out;
+ }
- error = udf_do_link(dvp, vp, cnp);
+ error = VOP_GETATTR(vp, &vap, FSCRED);
if (error)
+ goto out1;
+
+ /* check link count overflow */
+ if (vap.va_nlink >= (1<<16)-1) { /* uint16_t */
+ error = EMLINK;
+ goto out1;
+ }
+ error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp,
+ dvp, 0);
+ if (error)
+ goto out1;
+ abrt = 0;
+ error = udf_dir_attach(dir_node->ump, dir_node, udf_node, &vap, cnp);
+out1:
+ VOP_UNLOCK(vp);
+out:
+ if (abrt)
VOP_ABORTOP(dvp, cnp);
-
return error;
}
Home |
Main Index |
Thread Index |
Old Index