TRIM support for UFS?
Kostik Belousov
kostikbel at gmail.com
Wed Dec 8 21:49:15 UTC 2010
On Wed, Dec 08, 2010 at 09:07:56AM -0800, Julian Elischer wrote:
>
> From: Kirk McKusick <mckusick at chez.mckusick.com>
> Date: Wed, 21 May 2008 13:19:18 -0700
> To: Poul-Henning Kamp <phk at critter.freebsd.dk>
> Subject: UFS and BIO_DELETE
> X-URL: http://WWW.McKusick.COM/
> Reply-To: Kirk McKusick <mckusick at McKusick.COM>
>
> I enclose below my proposed patch to add BIO_DELETE to UFS
> (goes at the end of ffs_blkfree). As I have no way to test
> it, I am wondering if you could let me know if it works.
>
> Also, I am thinking of only enabling it for filesystems mounted
> with a new flag requesting the behavior since the geteblk is a
> rather expensive call for the usual no-op case.
>
> I did look at just allocating a `struct bio' as a local variable
> and using that, but it looked like I needed to also come up with a
> `producer' and/or `consumer' if I wanted to pass it to GEOM directly,
> so in the end I went with this more expensive solution. If there
> is an easy way to just pass a bio structure to GEOM, I would much
> prefer that approach.
>
> ~Kirk
>
>
> *** ffs_alloc.c Wed May 21 20:11:04 2008
> --- ffs_alloc.c.new Wed May 21 20:10:50 2008
> ***************
> *** 1945,1950 ****
> --- 1945,1962 ----
> ACTIVECLEAR(fs, cg);
> UFS_UNLOCK(ump);
> bdwrite(bp);
> + /*
> + * Request that the block be cleared.
> + */
> + bp = geteblk(size);
> + bp->b_iocmd = BIO_DELETE;
> + bp->b_vp = devvp;
> + bp->b_blkno = fsbtodb(fs, bno);
> + bp->b_offset = dbtob(bp->b_blkno);
> + bp->b_iooffset = bp->b_offset;
> + bp->b_bcount = size;
> + BUF_KERNPROC(bp);
> + BO_STRATEGY(&devvp->v_bufobj, bp);
> }
>
> #ifdef INVARIANTS
>
The UFS devvp contains the pointer to struct g_consumer in
devpp->v_bufobj->bo_private, so g_alloc_bio() and g_io_request() can be
used to start BIO_DELETE command without fake bufer allocation.
g_io_strategy() may be used as the sample.
But, I have a question about the patch. The bitmap block in ffs_blkfree()
is handled with delayed write, by bdwrite() call. I think that it is
quite possible for BIO_DELETE to be executed before the bitmap block
is written and on-disk bit is set in bitmap. Would not this allow
for the blocks to be deleted before the bitmap is updated,
and potentially before on-disk pointers are cleared that points to
the blocks ? SU just rolls back the unfinished dependencies on write,
but BIO_DELETE cannot.
Also, shouldn't the BIO_DELETE only be issued for real devices,
and not the snapshots ?
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index b740bbb..4ff57ae 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -83,6 +83,8 @@ __FBSDID("$FreeBSD$");
#include <security/audit/audit.h>
+#include <geom/geom.h>
+
#include <ufs/ufs/dir.h>
#include <ufs/ufs/extattr.h>
#include <ufs/ufs/quota.h>
@@ -1850,6 +1852,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, dephd)
u_int cg;
u_int8_t *blksfree;
struct cdev *dev;
+ struct bio *bip;
cg = dtog(fs, bno);
if (devvp->v_type == VREG) {
@@ -1962,6 +1965,16 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, dephd)
softdep_setup_blkfree(UFSTOVFS(ump), bp, bno,
numfrags(fs, size), dephd);
bdwrite(bp);
+
+ if (devvp->v_type != VREG) {
+ bip = g_alloc_bio();
+ bip->bio_cmd = BIO_DELETE;
+ bip->bio_offset = dbtob(fsbtodb(fs, bno));
+ bip->bio_done = g_destroy_bio;
+ bip->bio_length = size;
+ g_io_request(bip,
+ (struct g_consumer *)devvp->v_bufobj.bo_private);
+ }
}
#ifdef INVARIANTS
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-fs/attachments/20101208/f64e8906/attachment.pgp
More information about the freebsd-fs
mailing list