Subject: Re: mount_mfs (with mount_null) won't reclaim space
To: Jeremy C. Reed <reed@reedmedia.net>
From: enami tsugutomo <enami@but-b.or.jp>
List: tech-kern
Date: 03/17/2002 13:06:04
"Jeremy C. Reed" <reed@reedmedia.net> writes:

> Or can someone provide a patch to workaround the nullfs not reclaiming
> free space problem for 1.5.3_ALPHA?

I've just cooked the patch for -release branch.  This includes
actually two workaround (reclaiming storage is delayed and device
close routine won't called due to layerfs cache).

enami.

Index: genfs/layer.h
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/genfs/layer.h,v
retrieving revision 1.3
diff -u -r1.3 layer.h
--- genfs/layer.h	2000/03/30 02:19:16	1.3
+++ genfs/layer.h	2002/03/17 02:58:56
@@ -120,6 +120,7 @@
 };
 
 #define	LAYERFS_RESFLAGS	0x00000fff	/* flags reserved for layerfs */
+#define	LAYERFS_REMOVED		0x00000001	/* file is removed */
 
 /*
  * The following macros handle upperfs-specific locking. They are needed
Index: genfs/layer_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/genfs/layer_extern.h,v
retrieving revision 1.3
diff -u -r1.3 layer_extern.h
--- genfs/layer_extern.h	2000/03/16 18:08:24	1.3
+++ genfs/layer_extern.h	2002/03/17 02:58:56
@@ -117,3 +117,4 @@
 int	layer_setattr __P((void *));
 int	layer_access __P((void *));
 int	layer_open __P((void *));
+int	layer_remove __P((void *));
Index: genfs/layer_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/genfs/layer_vnops.c,v
retrieving revision 1.3.4.1
diff -u -r1.3.4.1 layer_vnops.c
--- genfs/layer_vnops.c	2000/12/14 23:36:11	1.3.4.1
+++ genfs/layer_vnops.c	2002/03/17 02:58:56
@@ -589,6 +589,30 @@
 	return LAYERFS_DO_BYPASS(vp, ap);
 }
 
+int
+layer_remove(v)
+     void *v;
+{
+	struct vop_remove_args /* {
+		const struct vnodeop_desc *a_desc;
+		struct vnode *a_dvp;
+		struct vnode *a_vp;
+		struct componentname *a_cnp;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct layer_node *xp = VTOLAYER(vp);
+	int error;
+
+	VREF(vp);
+	if ((error = LAYERFS_DO_BYPASS(vp, ap)) != 0)
+		goto out;
+
+	xp->layer_flags |= LAYERFS_REMOVED;
+ out:
+	vrele(vp);
+	return (error);
+}
+
 /*
  * We need to process our own vnode lock and then clear the
  * interlock flag as it applies only to our vnode, not the
@@ -737,6 +761,8 @@
 		struct vnode *a_vp;
 		struct proc *a_p;
 	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct layer_node *xp = VTOLAYER(vp);
 
 	/*
 	 * Do nothing (and _don't_ bypass).
@@ -749,8 +775,18 @@
 	 * with capabilities (v_id)
 	 * like they do in the name lookup cache code.
 	 * That's too much work for now.
+	 */
+	VOP_UNLOCK(vp, 0);
+
+	/*
+	 * ..., but don't cache the device node.  Otherwise, device
+	 * close routine won't be called.  Also, don't bother to keep
+	 * removed files.
 	 */
-	VOP_UNLOCK(ap->a_vp, 0);
+	if (vp->v_type == VBLK || vp->v_type == VCHR ||
+	    (xp->layer_flags & LAYERFS_REMOVED) != 0)
+		vgone(vp);
+
 	return (0);
 }
 
Index: nullfs/null_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/nullfs/null_vnops.c,v
retrieving revision 1.17
diff -u -r1.17 null_vnops.c
--- nullfs/null_vnops.c	2000/03/13 23:52:41	1.17
+++ nullfs/null_vnops.c	2002/03/17 02:58:57
@@ -231,6 +231,7 @@
 	{ &vop_setattr_desc,  layer_setattr },
 	{ &vop_getattr_desc,  layer_getattr },
 	{ &vop_access_desc,   layer_access },
+	{ &vop_remove_desc,   layer_remove },
 	{ &vop_lock_desc,     layer_lock },
 	{ &vop_unlock_desc,   layer_unlock },
 	{ &vop_islocked_desc, layer_islocked },