Page MenuHomeFreeBSD

D33914.diff
No OneTemporary

D33914.diff

diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c
--- a/sys/fs/unionfs/union_subr.c
+++ b/sys/fs/unionfs/union_subr.c
@@ -334,12 +334,6 @@
}
}
- if ((uppervp == NULLVP || ump->um_uppervp != uppervp) ||
- (lowervp == NULLVP || ump->um_lowervp != lowervp)) {
- /* dvp will be NULLVP only in case of root vnode. */
- if (dvp == NULLVP)
- return (EINVAL);
- }
unp = malloc(sizeof(struct unionfs_node),
M_UNIONFSNODE, M_WAITOK | M_ZERO);
@@ -381,9 +375,18 @@
vp->v_type = vt;
vp->v_data = unp;
- if ((uppervp != NULLVP && ump->um_uppervp == uppervp) &&
- (lowervp != NULLVP && ump->um_lowervp == lowervp))
+ /*
+ * TODO: This is an imperfect check, as there's no guarantee that
+ * the underlying filesystems will always return vnode pointers
+ * for the root inodes that match our cached values. To reduce
+ * the likelihood of failure, for example in the case where either
+ * vnode has been forcibly doomed, we check both pointers and set
+ * VV_ROOT if either matches.
+ */
+ if (ump->um_uppervp == uppervp || ump->um_lowervp == lowervp)
vp->v_vflag |= VV_ROOT;
+ KASSERT(dvp != NULL || (vp->v_vflag & VV_ROOT) != 0,
+ ("%s: NULL dvp for non-root vp %p", __func__, vp));
vn_lock_pair(lowervp, false, uppervp, false);
error = insmntque1(vp, mp, NULL, NULL);
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -241,6 +241,8 @@
/* get root vnodes */
lowerrootvp = mp->mnt_vnodecovered;
upperrootvp = ndp->ni_vp;
+ KASSERT(lowerrootvp != NULL, ("%s: NULL lower root vp", __func__));
+ KASSERT(upperrootvp != NULL, ("%s: NULL upper root vp", __func__));
/* create unionfs_mount */
ump = malloc(sizeof(struct unionfs_mount), M_UNIONFSMNT,
@@ -289,6 +291,9 @@
mp->mnt_data = NULL;
return (error);
}
+ KASSERT(ump->um_rootvp != NULL, ("rootvp cannot be NULL"));
+ KASSERT((ump->um_rootvp->v_vflag & VV_ROOT) != 0,
+ ("%s: rootvp without VV_ROOT", __func__));
lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp,
&ump->um_lower_link);
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -1908,8 +1908,6 @@
static int
unionfs_lock(struct vop_lock1_args *ap)
{
- struct mount *mp;
- struct unionfs_mount *ump;
struct unionfs_node *unp;
struct vnode *vp;
struct vnode *uvp;
@@ -1944,13 +1942,8 @@
if ((flags & LK_INTERLOCK) == 0)
VI_LOCK(vp);
- mp = vp->v_mount;
- if (mp == NULL)
- goto unionfs_lock_null_vnode;
-
- ump = MOUNTTOUNIONFSMOUNT(mp);
unp = VTOUNIONFS(vp);
- if (ump == NULL || unp == NULL)
+ if (unp == NULL)
goto unionfs_lock_null_vnode;
lvp = unp->un_lowervp;
uvp = unp->un_uppervp;
@@ -1967,7 +1960,7 @@
* (ex. vfs_domount: mounted vnode is already locked.)
*/
if ((flags & LK_TYPE_MASK) == LK_EXCLUSIVE &&
- vp == ump->um_rootvp)
+ (vp->v_vflag & VV_ROOT) != 0)
flags |= LK_CANRECURSE;
if (lvp != NULLVP) {

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 18, 4:21 PM (21 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14700655
Default Alt Text
D33914.diff (3 KB)

Event Timeline