summaryrefslogtreecommitdiffstats
path: root/sys/miscfs
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-09-05 14:13:12 +0000
committerphk <phk@FreeBSD.org>1998-09-05 14:13:12 +0000
commit4630814c8bc51e668f785289086657fbd5e775f2 (patch)
treee5449931fffd8e8dd0e4d28f5b7b28dc6e36ba5c /sys/miscfs
parentec3c90cf78eb16d4a8906a64e2a6f76cf27b8441 (diff)
downloadFreeBSD-src-4630814c8bc51e668f785289086657fbd5e775f2.zip
FreeBSD-src-4630814c8bc51e668f785289086657fbd5e775f2.tar.gz
Add a new vnode op, VOP_FREEBLKS(), which filesystems can use to inform
device drivers about sectors no longer in use. Device-drivers receive the call through d_strategy, if they have D_CANFREE in d_flags. This allows flash based devices to erase the sectors and avoid pointlessly carrying them around in compactions. Reviewed by: Kirk Mckusick, bde Sponsored by: M-Systems (www.m-sys.com)
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/specfs/spec_vnops.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index 8a3e124..31519d3 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95
- * $Id: spec_vnops.c,v 1.71 1998/08/25 17:48:54 phk Exp $
+ * $Id: spec_vnops.c,v 1.72 1998/09/04 08:06:56 dfr Exp $
*/
#include <sys/param.h>
@@ -61,6 +61,7 @@ static int spec_advlock __P((struct vop_advlock_args *));
static int spec_badop __P((void));
static int spec_bmap __P((struct vop_bmap_args *));
static int spec_close __P((struct vop_close_args *));
+static void spec_freeblks __P((struct vop_freeblks_args *));
static int spec_fsync __P((struct vop_fsync_args *));
static int spec_getattr __P((struct vop_getattr_args *));
static int spec_getpages __P((struct vop_getpages_args *));
@@ -109,6 +110,7 @@ static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_strategy_desc, (vop_t *) spec_strategy },
{ &vop_symlink_desc, (vop_t *) spec_badop },
{ &vop_write_desc, (vop_t *) spec_write },
+ { &vop_freeblks_desc, (vop_t *) spec_freeblks },
{ NULL, NULL }
};
static struct vnodeopv_desc spec_vnodeop_opv_desc =
@@ -540,6 +542,29 @@ spec_strategy(ap)
return (0);
}
+static void
+spec_freeblks(ap)
+ struct vop_freeblks_args /* {
+ struct vnode *a_vp;
+ daddr_t a_addr;
+ daddr_t a_length;
+ } */ *ap;
+{
+ struct cdevsw *bsw;
+ struct buf *bp;
+
+ bsw = bdevsw[major(ap->a_vp->v_rdev)];
+ if ((bsw->d_flags & D_CANFREE) == 0)
+ return;
+ bp = geteblk(ap->a_length);
+ bp->b_flags |= B_FREEBUF | B_BUSY;
+ bp->b_dev = ap->a_vp->v_rdev;
+ bp->b_blkno = ap->a_addr;
+ bp->b_offset = dbtob(ap->a_addr);
+ bp->b_bcount = ap->a_length;
+ (*bsw->d_strategy)(bp);
+}
+
/*
* This is a noop, simply returning what one has been given.
*/
OpenPOWER on IntegriCloud