Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/union VOP_GETATTR() needs a shared lock at least.
details: https://anonhg.NetBSD.org/src/rev/ce79b5d0aeb9
branches: trunk
changeset: 770467:ce79b5d0aeb9
user: hannken <hannken%NetBSD.org@localhost>
date: Tue Oct 18 09:22:53 2011 +0000
description:
VOP_GETATTR() needs a shared lock at least.
diffstat:
sys/fs/union/union_subr.c | 24 +++++++++++++-----------
sys/fs/union/union_vnops.c | 16 ++++++----------
2 files changed, 19 insertions(+), 21 deletions(-)
diffs (103 lines):
diff -r a76f85a24d16 -r ce79b5d0aeb9 sys/fs/union/union_subr.c
--- a/sys/fs/union/union_subr.c Tue Oct 18 05:16:02 2011 +0000
+++ b/sys/fs/union/union_subr.c Tue Oct 18 09:22:53 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_subr.c,v 1.50 2011/08/23 07:39:37 hannken Exp $ */
+/* $NetBSD: union_subr.c,v 1.51 2011/10/18 09:22:53 hannken Exp $ */
/*
* Copyright (c) 1994
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.50 2011/08/23 07:39:37 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.51 2011/10/18 09:22:53 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -472,9 +472,13 @@
if (uppervp != NULLVP)
if (VOP_GETATTR(uppervp, &va, FSCRED) == 0)
uppersz = va.va_size;
- if (lowervp != NULLVP)
- if (VOP_GETATTR(lowervp, &va, FSCRED) == 0)
+ if (lowervp != NULLVP) {
+ vn_lock(lowervp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(lowervp, &va, FSCRED);
+ VOP_UNLOCK(lowervp);
+ if (error == 0)
lowersz = va.va_size;
+ }
hash = UNION_HASH(uppervp, lowervp);
/*
@@ -1213,18 +1217,16 @@
if (vp->v_op != union_vnodeop_p)
return (0);
- if ((lvp = union_dircache(vp, l)) == NULLVP)
- return (0);
-
/*
* If the directory is opaque,
* then don't show lower entries
*/
error = VOP_GETATTR(vp, &va, fp->f_cred);
- if (error || (va.va_flags & OPAQUE)) {
- vput(lvp);
- return (error);
- }
+ if (error || (va.va_flags & OPAQUE))
+ return error;
+
+ if ((lvp = union_dircache(vp, l)) == NULLVP)
+ return (0);
error = VOP_OPEN(lvp, FREAD, fp->f_cred);
if (error) {
diff -r a76f85a24d16 -r ce79b5d0aeb9 sys/fs/union/union_vnops.c
--- a/sys/fs/union/union_vnops.c Tue Oct 18 05:16:02 2011 +0000
+++ b/sys/fs/union/union_vnops.c Tue Oct 18 09:22:53 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_vnops.c,v 1.46 2011/08/23 07:39:37 hannken Exp $ */
+/* $NetBSD: union_vnops.c,v 1.47 2011/10/18 09:22:53 hannken Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.46 2011/08/23 07:39:37 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.47 2011/10/18 09:22:53 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -830,14 +830,6 @@
vp = un->un_uppervp;
if (vp != NULLVP) {
- /*
- * It's not clear whether VOP_GETATTR is to be
- * called with the vnode locked or not. stat() calls
- * it with (vp) locked, and fstat calls it with
- * (vp) unlocked.
- * In the mean time, compensate here by checking
- * the union_node's lock flag.
- */
if (un->un_flags & UN_LOCKED)
FIXUP(un);
@@ -858,7 +850,11 @@
}
if (vp != NULLVP) {
+ if (vp == un->un_lowervp)
+ vn_lock(vp, LK_SHARED | LK_RETRY);
error = VOP_GETATTR(vp, vap, ap->a_cred);
+ if (vp == un->un_lowervp)
+ VOP_UNLOCK(vp);
if (error)
return (error);
union_newsize(ap->a_vp, VNOVAL, vap->va_size);
Home |
Main Index |
Thread Index |
Old Index