Page MenuHomeFreeBSD

D57824.id.diff
No OneTemporary

D57824.id.diff

diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -81,7 +81,6 @@
static int vop_stdgetpages_async(struct vop_getpages_async_args *ap);
static int vop_stdread_pgcache(struct vop_read_pgcache_args *ap);
static int vop_stdstat(struct vop_stat_args *ap);
-static int vop_stdvput_pair(struct vop_vput_pair_args *ap);
static int vop_stdgetlowvnode(struct vop_getlowvnode_args *ap);
/*
@@ -1623,16 +1622,34 @@
return (EJUSTRETURN);
}
-static int
+/*
+ * vput(dvp). If unlock_vp is true, vput(vp). Both dvp and vp must
+ * be locked. This is VOP because some filesystems might need to do
+ * additional actions on dvp when unlocked, and need to be aware of
+ * any other locked vnodes. Also as the consequence, vp might become
+ * doomed even if unlock_vp is false.
+ *
+ * Special case: dvp == vp. If unlock_vp is true, vunref(vp);
+ * vput(vp), else vunref(vp). In other words, the VOP assumes that
+ * two references on the vnode.
+ */
+int
vop_stdvput_pair(struct vop_vput_pair_args *ap)
{
struct vnode *dvp, *vp, **vpp;
dvp = ap->a_dvp;
vpp = ap->a_vpp;
- vput(dvp);
- if (vpp != NULL && ap->a_unlock_vp && (vp = *vpp) != NULL)
- vput(vp);
+ vp = vpp != NULL ? *vpp : NULL;
+ if (dvp != vp) {
+ vput(dvp);
+ if (vp != NULL && ap->a_unlock_vp)
+ vput(vp);
+ } else {
+ vunref(vp);
+ if (ap->a_unlock_vp)
+ vput(vp);
+ }
return (0);
}
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -907,6 +907,7 @@
int vop_stdpoll(struct vop_poll_args *);
int vop_stdvptocnp(struct vop_vptocnp_args *ap);
int vop_stdvptofh(struct vop_vptofh_args *ap);
+int vop_stdvput_pair(struct vop_vput_pair_args *ap);
int vop_stdunp_bind(struct vop_unp_bind_args *ap);
int vop_stdunp_connect(struct vop_unp_connect_args *ap);
int vop_stdunp_detach(struct vop_unp_detach_args *ap);
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -2006,16 +2006,14 @@
vpp = ap->a_vpp;
vp = vpp != NULL ? *vpp : NULL;
- if ((dp->i_flag & (IN_NEEDSYNC | IN_ENDOFF)) == 0) {
- vput(dvp);
- if (vp != NULL && ap->a_unlock_vp)
- vput(vp);
- return (0);
- }
+ if ((dp->i_flag & (IN_NEEDSYNC | IN_ENDOFF)) == 0)
+ return (vop_stdvput_pair(ap));
mp = dvp->v_mount;
if (vp != NULL) {
- if (ap->a_unlock_vp) {
+ if (dvp == vp) {
+ vunref(vp);
+ } else if (ap->a_unlock_vp) {
vput(vp);
} else {
MPASS(vp->v_type != VNON);
@@ -2055,6 +2053,12 @@
} while (error == ERELOOKUP);
}
+ if (vp == dvp) {
+ if (ap->a_unlock_vp)
+ vput(dvp);
+ return (0);
+ }
+
vput(dvp);
if (vp == NULL || ap->a_unlock_vp)

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 27, 4:46 PM (22 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34378033
Default Alt Text
D57824.id.diff (2 KB)

Event Timeline