Author: glebius
Date: Sun Jul 15 19:52:23 2012
New Revision: 238500
URL: http://svn.freebsd.org/changeset/base/238500

Log:
  Merge r237929, r237930 from head:
  
    ------------------------------------------------------------------------
    r237929 | glebius | 2012-07-01 19:30:43 +0400 (вс, 01 июл 2012) | 6 lines
  
    In g_mirror_regular_request() upon successful delivery treat
    BIO_DELETE requests same way as BIO_WRITE removing them from
    queue. This fixes panic with BIO_DELETE operations on geom_mirror.
  
    Reviewed by:    pjd
  
    ------------------------------------------------------------------------
    r237930 | glebius | 2012-07-01 19:43:52 +0400 (вс, 01 июл 2012) | 20 lines
  
    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
  
  Approved by:  re (kib)

Modified:
  stable/9/sys/geom/mirror/g_mirror.c
  stable/9/sys/geom/mirror/g_mirror.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/geom/mirror/g_mirror.c
==============================================================================
--- stable/9/sys/geom/mirror/g_mirror.c Sun Jul 15 19:32:02 2012        
(r238499)
+++ stable/9/sys/geom/mirror/g_mirror.c Sun Jul 15 19:52:23 2012        
(r238500)
@@ -439,7 +439,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) {
@@ -454,6 +454,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;
@@ -890,7 +895,8 @@ g_mirror_regular_request(struct bio *bp)
                if (pbp->bio_children == pbp->bio_inbed) {
                        G_MIRROR_LOGREQ(3, pbp, "Request delivered.");
                        pbp->bio_completed = pbp->bio_length;
-                       if (pbp->bio_cmd == BIO_WRITE) {
+                       if (pbp->bio_cmd == BIO_WRITE ||
+                           pbp->bio_cmd == BIO_DELETE) {
                                bioq_remove(&sc->sc_inflight, pbp);
                                /* Release delayed sync requests if possible. */
                                g_mirror_sync_release(sc);
@@ -1083,7 +1089,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;
                }
@@ -1630,6 +1638,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: stable/9/sys/geom/mirror/g_mirror.h
==============================================================================
--- stable/9/sys/geom/mirror/g_mirror.h Sun Jul 15 19:32:02 2012        
(r238499)
+++ stable/9/sys/geom/mirror/g_mirror.h Sun Jul 15 19:52:23 2012        
(r238500)
@@ -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
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to