aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason A. Harmening <jah@FreeBSD.org>2023-03-26 01:30:25 +0000
committerJason A. Harmening <jah@FreeBSD.org>2023-05-07 23:30:43 +0000
commit08091729851294fe302548af3c57c51aa12692fb (patch)
tree00d80eb4f617e1f4e1c63ad9f8d3acbfc106688b
parent95950880ade0b850b186aa60fc6606ed0ab30873 (diff)
downloadsrc-08091729851294fe302548af3c57c51aa12692fb.tar.gz
src-08091729851294fe302548af3c57c51aa12692fb.zip
unionfs: fixes to unionfs_nodeget() error handling
If either the lower or upper vnode is found to be doomed after locking it, the newly-created unionfs node won't be associated with it and its lock will be dropped. In that case, clear the uppervp and lowervp locals as necessary to avoid further use of the vnode in unionfs_nodeget(). If the upper vnode is doomed but the lower vnode remains valid, additionally reset the unionfs node's v_vnlock field to point to the lower vnode lock. Reviewed by: kib, markj Tested by: pho Differential Revision: https://reviews.freebsd.org/D39767
-rw-r--r--sys/fs/unionfs/union_subr.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c
index 264d37634949..702b10bb6204 100644
--- a/sys/fs/unionfs/union_subr.c
+++ b/sys/fs/unionfs/union_subr.c
@@ -397,13 +397,15 @@ unionfs_nodeget(struct mount *mp, struct vnode *uppervp,
}
if (lowervp != NULL && VN_IS_DOOMED(lowervp)) {
vput(lowervp);
- unp->un_lowervp = NULL;
+ unp->un_lowervp = lowervp = NULL;
}
if (uppervp != NULL && VN_IS_DOOMED(uppervp)) {
vput(uppervp);
- unp->un_uppervp = NULL;
+ unp->un_uppervp = uppervp = NULL;
+ if (lowervp != NULLVP)
+ vp->v_vnlock = lowervp->v_vnlock;
}
- if (unp->un_lowervp == NULL && unp->un_uppervp == NULL) {
+ if (lowervp == NULL && uppervp == NULL) {
unionfs_nodeget_cleanup(vp, unp);
return (ENOENT);
}