Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src/sys/fs/union Pull up following revision(s) (requested by ...
details: https://anonhg.NetBSD.org/src/rev/07b687fa347a
branches: netbsd-9
changeset: 937813:07b687fa347a
user: martin <martin%NetBSD.org@localhost>
date: Thu Aug 27 09:08:39 2020 +0000
description:
Pull up following revision(s) (requested by hannken in ticket #1062):
sys/fs/union/union.h: revision 1.30
sys/fs/union/union_subr.c: revision 1.79
sys/fs/union/union_vnops.c: revision 1.74
Operation union_readdirhook() stores the lower directory as un_uppervp.
This breaks the assumption that un_uppervp->v_mount is the upper mount.
Fix by storing the directory as un_lowervp and adapt union_readdir().
Should fix PR kern/55552: panic with union mount
diffstat:
sys/fs/union/union.h | 3 ++-
sys/fs/union/union_subr.c | 11 +++++++----
sys/fs/union/union_vnops.c | 30 +++++++++++++++++++++++-------
3 files changed, 32 insertions(+), 12 deletions(-)
diffs (119 lines):
diff -r 2aa7257a7568 -r 07b687fa347a sys/fs/union/union.h
--- a/sys/fs/union/union.h Thu Aug 27 09:05:36 2020 +0000
+++ b/sys/fs/union/union.h Thu Aug 27 09:08:39 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union.h,v 1.29 2017/07/17 09:22:36 hannken Exp $ */
+/* $NetBSD: union.h,v 1.29.10.1 2020/08/27 09:08:39 martin Exp $ */
/*
* Copyright (c) 1994 The Regents of the University of California.
@@ -130,6 +130,7 @@
char *un_path; /* v: saved component name */
int un_openl; /* v: # of opens on lowervp */
unsigned int un_cflags; /* c: cache flags */
+ bool un_hooknode; /* :: from union_readdirhook */
struct vnode **un_dircache; /* v: cached union stack */
off_t un_uppersz; /* l: size of upper object */
off_t un_lowersz; /* l: size of lower object */
diff -r 2aa7257a7568 -r 07b687fa347a sys/fs/union/union_subr.c
--- a/sys/fs/union/union_subr.c Thu Aug 27 09:05:36 2020 +0000
+++ b/sys/fs/union/union_subr.c Thu Aug 27 09:08:39 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_subr.c,v 1.77 2018/01/28 15:48:44 christos Exp $ */
+/* $NetBSD: union_subr.c,v 1.77.8.1 2020/08/27 09:08:39 martin Exp $ */
/*
* Copyright (c) 1994
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.77 2018/01/28 15:48:44 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.77.8.1 2020/08/27 09:08:39 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -479,6 +479,7 @@
un->un_dircache = 0;
un->un_openl = 0;
un->un_cflags = 0;
+ un->un_hooknode = false;
un->un_uppersz = VNOVAL;
un->un_lowersz = VNOVAL;
@@ -1065,7 +1066,7 @@
} else {
vpp = dircache;
do {
- if (*vpp++ == VTOUNION(vp)->un_uppervp)
+ if (*vpp++ == VTOUNION(vp)->un_lowervp)
break;
} while (*vpp != NULLVP);
}
@@ -1074,10 +1075,12 @@
goto out;
vref(*vpp);
- error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0);
+ error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0,
+ NULLVP, *vpp, 0);
if (!error) {
vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);
VTOUNION(vp)->un_dircache = 0;
+ VTOUNION(nvp)->un_hooknode = true;
VTOUNION(nvp)->un_dircache = dircache;
}
diff -r 2aa7257a7568 -r 07b687fa347a sys/fs/union/union_vnops.c
--- a/sys/fs/union/union_vnops.c Thu Aug 27 09:05:36 2020 +0000
+++ b/sys/fs/union/union_vnops.c Thu Aug 27 09:08:39 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_vnops.c,v 1.70 2017/05/26 14:21:01 riastradh Exp $ */
+/* $NetBSD: union_vnops.c,v 1.70.14.1 2020/08/27 09:08:39 martin Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.70 2017/05/26 14:21:01 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.70.14.1 2020/08/27 09:08:39 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1492,13 +1492,29 @@
int a_ncookies;
} */ *ap = v;
struct union_node *un = VTOUNION(ap->a_vp);
- struct vnode *uvp = un->un_uppervp;
+ struct vnode *vp;
+ int dolock, error;
- if (uvp == NULLVP)
- return (0);
+ if (un->un_hooknode) {
+ KASSERT(un->un_uppervp == NULLVP);
+ KASSERT(un->un_lowervp != NULLVP);
+ vp = un->un_lowervp;
+ dolock = 1;
+ } else {
+ vp = un->un_uppervp;
+ dolock = 0;
+ }
+ if (vp == NULLVP)
+ return 0;
- ap->a_vp = uvp;
- return (VCALL(uvp, VOFFSET(vop_readdir), ap));
+ if (dolock)
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ ap->a_vp = vp;
+ error = VCALL(vp, VOFFSET(vop_readdir), ap);
+ if (dolock)
+ VOP_UNLOCK(vp);
+
+ return error;
}
int
Home |
Main Index |
Thread Index |
Old Index