svn commit: r237930 - head/sys/geom/mirror

Gleb Smirnoff glebius at FreeBSD.org
Sun Jul 1 15:43:53 UTC 2012


Author: glebius
Date: Sun Jul  1 15:43:52 2012
New Revision: 237930
URL: http://svn.freebsd.org/changeset/base/237930

Log:
  Make geom_mirror more friendly to SSDs. To properly support TRIM,
  we need to pass BIO_DELETE requests down to providers that support
  it. Also, we need to announce our support for BIO_DELETE to upper
  consumer. This requires:
  
  - In g_mirror_start() return true for "GEOM::candelete" request.
  - In g_mirror_init_disk() probe below provider for "GEOM::candelete"
    attribute, and mark disk with a flag if it does support BIO_DELETE.
  - In g_mirror_register_request() distribute BIO_DELETE requests only
    to those disks, that do support it.
  
  Note that we announce "GEOM::candelete" as true unconditionally of
  whether we have TRIM-capable media down below or not. This is made
  intentionally, because upper consumer (usually UFS) requests the
  attribite only once at mount time. And if user ever migrates his
  mirror from HDDs to SSDs, then he/she would get TRIM working without
  remounting filesystem.
  
  Reviewed by:	pjd

Modified:
  head/sys/geom/mirror/g_mirror.c
  head/sys/geom/mirror/g_mirror.h

Modified: head/sys/geom/mirror/g_mirror.c
==============================================================================
--- head/sys/geom/mirror/g_mirror.c	Sun Jul  1 15:30:43 2012	(r237929)
+++ head/sys/geom/mirror/g_mirror.c	Sun Jul  1 15:43:52 2012	(r237930)
@@ -440,7 +440,7 @@ g_mirror_init_disk(struct g_mirror_softc
     struct g_mirror_metadata *md, int *errorp)
 {
 	struct g_mirror_disk *disk;
-	int error;
+	int i, error;
 
 	disk = malloc(sizeof(*disk), M_MIRROR, M_NOWAIT | M_ZERO);
 	if (disk == NULL) {
@@ -455,6 +455,11 @@ g_mirror_init_disk(struct g_mirror_softc
 	disk->d_state = G_MIRROR_DISK_STATE_NONE;
 	disk->d_priority = md->md_priority;
 	disk->d_flags = md->md_dflags;
+	error = g_getattr("GEOM::candelete", disk->d_consumer, &i);
+	if (error != 0)
+		goto fail;
+	if (i)
+		disk->d_flags |= G_MIRROR_DISK_FLAG_CANDELETE;
 	if (md->md_provider[0] != '\0')
 		disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
 	disk->d_sync.ds_consumer = NULL;
@@ -1085,7 +1090,9 @@ g_mirror_start(struct bio *bp)
 		g_mirror_flush(sc, bp);
 		return;
 	case BIO_GETATTR:
-		if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
+		if (g_handleattr_int(bp, "GEOM::candelete", 1))
+			return;
+		else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
 			g_mirror_kernel_dump(bp);
 			return;
 		}
@@ -1632,6 +1639,9 @@ g_mirror_register_request(struct bio *bp
 			default:
 				continue;
 			}
+			if (bp->bio_cmd == BIO_DELETE &&
+			    (disk->d_flags & G_MIRROR_DISK_FLAG_CANDELETE) == 0)
+				continue;
 			cbp = g_clone_bio(bp);
 			if (cbp == NULL) {
 				for (cbp = bioq_first(&queue); cbp != NULL;

Modified: head/sys/geom/mirror/g_mirror.h
==============================================================================
--- head/sys/geom/mirror/g_mirror.h	Sun Jul  1 15:30:43 2012	(r237929)
+++ head/sys/geom/mirror/g_mirror.h	Sun Jul  1 15:43:52 2012	(r237930)
@@ -59,10 +59,12 @@
 #define	G_MIRROR_DISK_FLAG_INACTIVE		0x0000000000000008ULL
 #define	G_MIRROR_DISK_FLAG_HARDCODED		0x0000000000000010ULL
 #define	G_MIRROR_DISK_FLAG_BROKEN		0x0000000000000020ULL
+#define	G_MIRROR_DISK_FLAG_CANDELETE		0x0000000000000040ULL
 #define	G_MIRROR_DISK_FLAG_MASK		(G_MIRROR_DISK_FLAG_DIRTY |	\
 					 G_MIRROR_DISK_FLAG_SYNCHRONIZING | \
 					 G_MIRROR_DISK_FLAG_FORCE_SYNC | \
-					 G_MIRROR_DISK_FLAG_INACTIVE)
+					 G_MIRROR_DISK_FLAG_INACTIVE | \
+					 G_MIRROR_DISK_FLAG_CANDELETE)
 
 #define	G_MIRROR_DEVICE_FLAG_NOAUTOSYNC	0x0000000000000001ULL
 #define	G_MIRROR_DEVICE_FLAG_NOFAILSYNC	0x0000000000000002ULL


More information about the svn-src-all mailing list