summaryrefslogtreecommitdiffstats
path: root/sys/fs/nullfs/null_vnops.c
diff options
context:
space:
mode:
authorsemenu <semenu@FreeBSD.org>2002-06-13 21:49:09 +0000
committersemenu <semenu@FreeBSD.org>2002-06-13 21:49:09 +0000
commit50d99cdfecd92f5323a18aa791a5b1cb9d8b7191 (patch)
tree6951958eefa7c3d066580c5bb379863dacb57268 /sys/fs/nullfs/null_vnops.c
parente930b35ecdd23d857aaa5efd37d78e7bfc0b3966 (diff)
downloadFreeBSD-src-50d99cdfecd92f5323a18aa791a5b1cb9d8b7191.zip
FreeBSD-src-50d99cdfecd92f5323a18aa791a5b1cb9d8b7191.tar.gz
Fix a race during null node creation between relookuping the hash and
adding vnode to hash. The fix is to use atomic hash-lookup-and-add-if- not-found operation. The odd thing is that this race can't happen actually because the lowervp vnode is locked exclusively now during the whole process of null node creation. This must be thought as a step toward shared lookups. Also remove vp->v_mount checks when looking for a match in the hash, as this is the vestige. Also add comments and cosmetic changes.
Diffstat (limited to 'sys/fs/nullfs/null_vnops.c')
-rw-r--r--sys/fs/nullfs/null_vnops.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index f3201e2..2b141be 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -346,7 +346,7 @@ null_bypass(ap)
vppp = VOPARG_OFFSETTO(struct vnode***,
descp->vdesc_vpp_offset,ap);
if (*vppp)
- error = null_node_create(old_vps[0]->v_mount, **vppp, *vppp);
+ error = null_nodeget(old_vps[0]->v_mount, **vppp, *vppp);
}
out:
@@ -400,9 +400,12 @@ null_lookup(ap)
VREF(dvp);
vrele(lvp);
} else {
- error = null_node_create(dvp->v_mount, lvp, &vp);
- if (error == 0)
- *ap->a_vpp = vp;
+ error = null_nodeget(dvp->v_mount, lvp, &vp);
+ if (error) {
+ /* XXX Cleanup needed... */
+ panic("null_nodeget failed");
+ }
+ *ap->a_vpp = vp;
}
}
return (error);
@@ -706,6 +709,11 @@ null_islocked(ap)
* There is no way to tell that someone issued remove/rmdir operation
* on the underlying filesystem. For now we just have to release lowevrp
* as soon as possible.
+ *
+ * Note, we can't release any resources nor remove vnode from hash before
+ * appropriate VXLOCK stuff is is done because other process can find this
+ * vnode in hash during inactivation and may be sitting in vget() and waiting
+ * for null_inactive to unlock vnode. Thus we will do all those in VOP_RECLAIM.
*/
static int
null_inactive(ap)
@@ -729,8 +737,7 @@ null_inactive(ap)
}
/*
- * We can free memory in null_inactive, but we do this
- * here. (Possible to guard vp->v_data to point somewhere)
+ * Now, the VXLOCK is in force and we're free to destroy the null vnode.
*/
static int
null_reclaim(ap)
OpenPOWER on IntegriCloud