diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2020-08-16 21:05:56 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2020-08-16 21:05:56 +0000 |
| commit | 685cb01a18595e8e7cb15f3ea225ac1dd13bd319 (patch) | |
| tree | 1427047a9afda35df9b344cee9c39de0c7ec9a35 /sys/fs/nullfs/null_subr.c | |
| parent | fbca789fc328487a1be438f5235e4c0ad0eb849b (diff) | |
Notes
Diffstat (limited to 'sys/fs/nullfs/null_subr.c')
| -rw-r--r-- | sys/fs/nullfs/null_subr.c | 21 |
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); } |
