diff options
author | phk <phk@FreeBSD.org> | 1998-09-05 14:13:12 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1998-09-05 14:13:12 +0000 |
commit | 4630814c8bc51e668f785289086657fbd5e775f2 (patch) | |
tree | e5449931fffd8e8dd0e4d28f5b7b28dc6e36ba5c /sys/fs | |
parent | ec3c90cf78eb16d4a8906a64e2a6f76cf27b8441 (diff) | |
download | FreeBSD-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/fs')
-rw-r--r-- | sys/fs/specfs/spec_vnops.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/sys/fs/specfs/spec_vnops.c b/sys/fs/specfs/spec_vnops.c index 8a3e124..31519d3 100644 --- a/sys/fs/specfs/spec_vnops.c +++ b/sys/fs/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. */ |