Module Name: src
Committed By: christos
Date: Wed Mar 30 13:24:00 UTC 2022
Modified Files:
src/sys/fs/udf: udf_vnops.c
Log Message:
Fix locking in udf_link(). XXX: udf_symlink is prolly similarly broken.
To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/fs/udf/udf_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/udf/udf_vnops.c
diff -u src/sys/fs/udf/udf_vnops.c:1.120 src/sys/fs/udf/udf_vnops.c:1.121
--- src/sys/fs/udf/udf_vnops.c:1.120 Sun Mar 27 12:24:58 2022
+++ src/sys/fs/udf/udf_vnops.c Wed Mar 30 09:23:59 2022
@@ -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,12 +1542,20 @@ udf_mkdir(void *v)
/* --------------------------------------------------------------------- */
-static int
-udf_do_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
+int
+udf_link(void *v)
{
+ struct vop_link_v2_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 udf_node *udf_node, *dir_node;
struct vattr vap;
- int error;
+ int error, abrt = 1;
DPRINTF(CALL, ("udf_link called\n"));
KASSERT(dvp != vp);
@@ -1558,44 +1566,31 @@ udf_do_link(struct vnode *dvp, struct vn
dir_node = VTOI(dvp);
udf_node = VTOI(vp);
+ if ((error = vn_lock(vp, LK_EXCLUSIVE))) {
+ DPRINTF("lock failed. %p\n", vp);
+ goto out;
+ }
+
error = VOP_GETATTR(vp, &vap, FSCRED);
if (error)
- goto out;
+ goto out1;
/* check link count overflow */
if (vap.va_nlink >= (1<<16)-1) { /* uint16_t */
error = EMLINK;
- goto out;
+ goto out1;
}
error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp,
dvp, 0);
if (error)
- goto out;
-
+ goto out1;
+ abrt = 0;
error = udf_dir_attach(dir_node->ump, dir_node, udf_node, &vap, cnp);
+out1:
+ VOP_UNLOCK(vp);
out:
- if (error)
- VOP_UNLOCK(vp);
- return error;
-}
-
-int
-udf_link(void *v)
-{
- struct vop_link_v2_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;
- int error;
-
- error = udf_do_link(dvp, vp, cnp);
- if (error)
+ if (abrt)
VOP_ABORTOP(dvp, cnp);
-
return error;
}