svn commit: r350504 - head/sys/fs/unionfs
Konstantin Belousov
kib at FreeBSD.org
Thu Aug 1 14:40:38 UTC 2019
Author: kib
Date: Thu Aug 1 14:40:37 2019
New Revision: 350504
URL: https://svnweb.freebsd.org/changeset/base/350504
Log:
Try to decrease the number of bugs in unionfs after the VV_TEXT flag removal.
- Provide unionfs_add_writecount() which passes the writecount to the
lower or upper vnode as appropriate.
- In unionfs VOP_RECLAIM() implementation, annulate unionfs
writecounts from upper or lower vnode. It is not clear that it is
always correct to remove the all references from either lower or
upper vnode, but we currently do not track which vnode get how many
refs anyway.
Reported and tested by: t_uemura at macome.co.jp
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/fs/unionfs/union_subr.c
head/sys/fs/unionfs/union_vnops.c
Modified: head/sys/fs/unionfs/union_subr.c
==============================================================================
--- head/sys/fs/unionfs/union_subr.c Thu Aug 1 14:39:26 2019 (r350503)
+++ head/sys/fs/unionfs/union_subr.c Thu Aug 1 14:40:37 2019 (r350504)
@@ -349,6 +349,13 @@ unionfs_noderem(struct vnode *vp, struct thread *td)
vp->v_vnlock = &(vp->v_lock);
vp->v_data = NULL;
vp->v_object = NULL;
+ if (vp->v_writecount > 0) {
+ if (uvp != NULL)
+ VOP_ADD_WRITECOUNT(uvp, -vp->v_writecount);
+ else if (lvp != NULL)
+ VOP_ADD_WRITECOUNT(lvp, -vp->v_writecount);
+ } else if (vp->v_writecount < 0)
+ vp->v_writecount = 0;
VI_UNLOCK(vp);
if (lvp != NULLVP)
Modified: head/sys/fs/unionfs/union_vnops.c
==============================================================================
--- head/sys/fs/unionfs/union_vnops.c Thu Aug 1 14:39:26 2019 (r350503)
+++ head/sys/fs/unionfs/union_vnops.c Thu Aug 1 14:40:37 2019 (r350504)
@@ -2511,6 +2511,33 @@ unionfs_vptofh(struct vop_vptofh_args *ap)
return (EOPNOTSUPP);
}
+static int
+unionfs_add_writecount(struct vop_add_writecount_args *ap)
+{
+ struct vnode *tvp, *vp;
+ struct unionfs_node *unp;
+ int error;
+
+ vp = ap->a_vp;
+ unp = VTOUNIONFS(vp);
+ tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
+ VI_LOCK(vp);
+ /* text refs are bypassed to lowervp */
+ VNASSERT(vp->v_writecount >= 0, vp, ("wrong null writecount"));
+ VNASSERT(vp->v_writecount + ap->a_inc >= 0, vp,
+ ("wrong writecount inc %d", ap->a_inc));
+ if (tvp != NULL)
+ error = VOP_ADD_WRITECOUNT(tvp, ap->a_inc);
+ else if (vp->v_writecount < 0)
+ error = ETXTBSY;
+ else
+ error = 0;
+ if (error == 0)
+ vp->v_writecount += ap->a_inc;
+ VI_UNLOCK(vp);
+ return (error);
+}
+
struct vop_vector unionfs_vnodeops = {
.vop_default = &default_vnodeops,
@@ -2559,4 +2586,5 @@ struct vop_vector unionfs_vnodeops = {
.vop_whiteout = unionfs_whiteout,
.vop_write = unionfs_write,
.vop_vptofh = unionfs_vptofh,
+ .vop_add_writecount = unionfs_add_writecount,
};
More information about the svn-src-all
mailing list