aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nullfs/null_subr.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-08-16 21:05:56 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-08-16 21:05:56 +0000
commit685cb01a18595e8e7cb15f3ea225ac1dd13bd319 (patch)
tree1427047a9afda35df9b344cee9c39de0c7ec9a35 /sys/fs/nullfs/null_subr.c
parentfbca789fc328487a1be438f5235e4c0ad0eb849b (diff)
Notes
Diffstat (limited to 'sys/fs/nullfs/null_subr.c')
-rw-r--r--sys/fs/nullfs/null_subr.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c
index 125b623cb638..80f6943ac7c3 100644
--- a/sys/fs/nullfs/null_subr.c
+++ b/sys/fs/nullfs/null_subr.c
@@ -259,12 +259,33 @@ null_nodeget(mp, lowervp, vpp)
vp->v_vflag |= VV_ROOT;
/*
+ * We might miss the case where lower vnode sets VIRF_PGREAD
+ * some time after construction, which is typical case.
+ * null_open rechecks.
+ */
+ if ((lowervp->v_irflag & VIRF_PGREAD) != 0) {
+ MPASS(lowervp->v_object != NULL);
+ if ((vp->v_irflag & VIRF_PGREAD) == 0) {
+ if (vp->v_object == NULL)
+ vp->v_object = lowervp->v_object;
+ else
+ MPASS(vp->v_object == lowervp->v_object);
+ VI_LOCK(vp);
+ vp->v_irflag |= VIRF_PGREAD;
+ VI_UNLOCK(vp);
+ } else {
+ MPASS(vp->v_object != NULL);
+ }
+ }
+
+ /*
* Atomically insert our new node into the hash or vget existing
* if someone else has beaten us to it.
*/
*vpp = null_hashins(mp, xp);
if (*vpp != NULL) {
vrele(lowervp);
+ vp->v_object = NULL; /* in case VIRF_PGREAD set it */
null_destroy_proto(vp, xp);
return (0);
}