Author: mav
Date: Wed Oct 16 09:33:23 2013
New Revision: 256610
URL: http://svnweb.freebsd.org/changeset/base/256610

Log:
  MFprojects/camlock r256445:
  Add unmapped I/O support to GEOM RAID.

Modified:
  head/sys/geom/raid/g_raid.c
  head/sys/geom/raid/g_raid.h
  head/sys/geom/raid/tr_concat.c
  head/sys/geom/raid/tr_raid0.c
  head/sys/geom/raid/tr_raid1.c
  head/sys/geom/raid/tr_raid1e.c
  head/sys/geom/raid/tr_raid5.c

Modified: head/sys/geom/raid/g_raid.c
==============================================================================
--- head/sys/geom/raid/g_raid.c Wed Oct 16 09:27:51 2013        (r256609)
+++ head/sys/geom/raid/g_raid.c Wed Oct 16 09:33:23 2013        (r256610)
@@ -993,20 +993,15 @@ g_raid_tr_flush_common(struct g_raid_tr_
                cbp->bio_caller1 = sd;
                bioq_insert_tail(&queue, cbp);
        }
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);
@@ -1639,11 +1634,13 @@ static void
 g_raid_launch_provider(struct g_raid_volume *vol)
 {
        struct g_raid_disk *disk;
+       struct g_raid_subdisk *sd;
        struct g_raid_softc *sc;
        struct g_provider *pp;
        char name[G_RAID_MAX_VOLUMENAME];
        char   announce_buf[80], buf1[32];
        off_t off;
+       int i;
 
        sc = vol->v_softc;
        sx_assert(&sc->sc_lock, SX_LOCKED);
@@ -1673,6 +1670,17 @@ g_raid_launch_provider(struct g_raid_vol
         }
 
        pp = g_new_providerf(sc->sc_geom, "%s", name);
+       if (vol->v_tr->tro_class->trc_accept_unmapped) {
+               pp->flags |= G_PF_ACCEPT_UNMAPPED;
+               for (i = 0; i < vol->v_disks_count; i++) {
+                       sd = &vol->v_subdisks[i];
+                       if (sd->sd_state == G_RAID_SUBDISK_S_NONE)
+                               continue;
+                       if ((sd->sd_disk->d_consumer->provider->flags &
+                           G_PF_ACCEPT_UNMAPPED) == 0)
+                               pp->flags &= ~G_PF_ACCEPT_UNMAPPED;
+               }
+       }
        pp->private = vol;
        pp->mediasize = vol->v_mediasize;
        pp->sectorsize = vol->v_sectorsize;

Modified: head/sys/geom/raid/g_raid.h
==============================================================================
--- head/sys/geom/raid/g_raid.h Wed Oct 16 09:27:51 2013        (r256609)
+++ head/sys/geom/raid/g_raid.h Wed Oct 16 09:33:23 2013        (r256610)
@@ -376,6 +376,7 @@ struct g_raid_tr_class {
        KOBJ_CLASS_FIELDS;
        int              trc_enable;
        int              trc_priority;
+       int              trc_accept_unmapped;
        LIST_ENTRY(g_raid_tr_class) trc_list;
 };
 

Modified: head/sys/geom/raid/tr_concat.c
==============================================================================
--- head/sys/geom/raid/tr_concat.c      Wed Oct 16 09:27:51 2013        
(r256609)
+++ head/sys/geom/raid/tr_concat.c      Wed Oct 16 09:33:23 2013        
(r256610)
@@ -74,7 +74,8 @@ static struct g_raid_tr_class g_raid_tr_
        g_raid_tr_concat_methods,
        sizeof(struct g_raid_tr_concat_object),
        .trc_enable = 1,
-       .trc_priority = 50
+       .trc_priority = 50,
+       .trc_accept_unmapped = 1
 };
 
 static int
@@ -227,7 +228,10 @@ g_raid_tr_iostart_concat(struct g_raid_t
 
        offset = bp->bio_offset;
        remain = bp->bio_length;
-       addr = bp->bio_data;
+       if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+               addr = NULL;
+       else
+               addr = bp->bio_data;
        no = 0;
        while (no < vol->v_disks_count &&
            offset >= vol->v_subdisks[no].sd_size) {
@@ -244,8 +248,16 @@ g_raid_tr_iostart_concat(struct g_raid_t
                if (cbp == NULL)
                        goto failure;
                cbp->bio_offset = offset;
-               cbp->bio_data = addr;
                cbp->bio_length = length;
+               if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+                   bp->bio_cmd != BIO_DELETE) {
+                       cbp->bio_ma_offset += (uintptr_t)addr;
+                       cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+                       cbp->bio_ma_offset %= PAGE_SIZE;
+                       cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+                           cbp->bio_length) / PAGE_SIZE;
+               } else
+                       cbp->bio_data = addr;
                cbp->bio_caller1 = sd;
                bioq_insert_tail(&queue, cbp);
                remain -= length;
@@ -257,20 +269,15 @@ g_raid_tr_iostart_concat(struct g_raid_t
                    ("Request ends after volume end (%ju, %ju)",
                        bp->bio_offset, bp->bio_length));
        } while (remain > 0);
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);

Modified: head/sys/geom/raid/tr_raid0.c
==============================================================================
--- head/sys/geom/raid/tr_raid0.c       Wed Oct 16 09:27:51 2013        
(r256609)
+++ head/sys/geom/raid/tr_raid0.c       Wed Oct 16 09:33:23 2013        
(r256610)
@@ -74,7 +74,8 @@ static struct g_raid_tr_class g_raid_tr_
        g_raid_tr_raid0_methods,
        sizeof(struct g_raid_tr_raid0_object),
        .trc_enable = 1,
-       .trc_priority = 100
+       .trc_priority = 100,
+       .trc_accept_unmapped = 1
 };
 
 static int
@@ -204,7 +205,10 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
                g_raid_tr_flush_common(tr, bp);
                return;
        }
-       addr = bp->bio_data;
+       if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+               addr = NULL;
+       else
+               addr = bp->bio_data;
        strip_size = vol->v_strip_size;
 
        /* Stripe number. */
@@ -225,8 +229,16 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
                if (cbp == NULL)
                        goto failure;
                cbp->bio_offset = offset + start;
-               cbp->bio_data = addr;
                cbp->bio_length = length;
+               if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+                   bp->bio_cmd != BIO_DELETE) {
+                       cbp->bio_ma_offset += (uintptr_t)addr;
+                       cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+                       cbp->bio_ma_offset %= PAGE_SIZE;
+                       cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+                           cbp->bio_length) / PAGE_SIZE;
+               } else
+                       cbp->bio_data = addr;
                cbp->bio_caller1 = &vol->v_subdisks[no];
                bioq_insert_tail(&queue, cbp);
                if (++no >= vol->v_disks_count) {
@@ -238,20 +250,15 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
                        addr += length;
                start = 0;
        } while (remain > 0);
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);

Modified: head/sys/geom/raid/tr_raid1.c
==============================================================================
--- head/sys/geom/raid/tr_raid1.c       Wed Oct 16 09:27:51 2013        
(r256609)
+++ head/sys/geom/raid/tr_raid1.c       Wed Oct 16 09:33:23 2013        
(r256610)
@@ -130,7 +130,8 @@ static struct g_raid_tr_class g_raid_tr_
        g_raid_tr_raid1_methods,
        sizeof(struct g_raid_tr_raid1_object),
        .trc_enable = 1,
-       .trc_priority = 100
+       .trc_priority = 100,
+       .trc_accept_unmapped = 1
 };
 
 static void g_raid_tr_raid1_rebuild_abort(struct g_raid_tr_object *tr);
@@ -594,20 +595,15 @@ g_raid_tr_iostart_raid1_write(struct g_r
                cbp->bio_caller1 = sd;
                bioq_insert_tail(&queue, cbp);
        }
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);

Modified: head/sys/geom/raid/tr_raid1e.c
==============================================================================
--- head/sys/geom/raid/tr_raid1e.c      Wed Oct 16 09:27:51 2013        
(r256609)
+++ head/sys/geom/raid/tr_raid1e.c      Wed Oct 16 09:33:23 2013        
(r256610)
@@ -134,7 +134,8 @@ static struct g_raid_tr_class g_raid_tr_
        g_raid_tr_raid1e_methods,
        sizeof(struct g_raid_tr_raid1e_object),
        .trc_enable = 1,
-       .trc_priority = 200
+       .trc_priority = 200,
+       .trc_accept_unmapped = 1
 };
 
 static void g_raid_tr_raid1e_rebuild_abort(struct g_raid_tr_object *tr);
@@ -701,7 +702,10 @@ g_raid_tr_iostart_raid1e_read(struct g_r
        int best;
 
        vol = tr->tro_volume;
-       addr = bp->bio_data;
+       if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+               addr = NULL;
+       else
+               addr = bp->bio_data;
        strip_size = vol->v_strip_size;
        V2P(vol, bp->bio_offset, &no, &offset, &start);
        remain = bp->bio_length;
@@ -721,8 +725,15 @@ g_raid_tr_iostart_raid1e_read(struct g_r
                if (cbp == NULL)
                        goto failure;
                cbp->bio_offset = offset + start;
-               cbp->bio_data = addr;
                cbp->bio_length = length;
+               if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+                       cbp->bio_ma_offset += (uintptr_t)addr;
+                       cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+                       cbp->bio_ma_offset %= PAGE_SIZE;
+                       cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+                           cbp->bio_length) / PAGE_SIZE;
+               } else
+                       cbp->bio_data = addr;
                cbp->bio_caller1 = &vol->v_subdisks[no];
                bioq_insert_tail(&queue, cbp);
                no += N - best;
@@ -734,20 +745,15 @@ g_raid_tr_iostart_raid1e_read(struct g_r
                addr += length;
                start = 0;
        }
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);
@@ -766,7 +772,10 @@ g_raid_tr_iostart_raid1e_write(struct g_
        int i;
 
        vol = tr->tro_volume;
-       addr = bp->bio_data;
+       if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+               addr = NULL;
+       else
+               addr = bp->bio_data;
        strip_size = vol->v_strip_size;
        V2P(vol, bp->bio_offset, &no, &offset, &start);
        remain = bp->bio_length;
@@ -791,8 +800,16 @@ g_raid_tr_iostart_raid1e_write(struct g_
                        if (cbp == NULL)
                                goto failure;
                        cbp->bio_offset = offset + start;
-                       cbp->bio_data = addr;
                        cbp->bio_length = length;
+                       if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+                           bp->bio_cmd != BIO_DELETE) {
+                               cbp->bio_ma_offset += (uintptr_t)addr;
+                               cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+                               cbp->bio_ma_offset %= PAGE_SIZE;
+                               cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+                                   cbp->bio_length) / PAGE_SIZE;
+                       } else
+                               cbp->bio_data = addr;
                        cbp->bio_caller1 = sd;
                        bioq_insert_tail(&queue, cbp);
 nextdisk:
@@ -806,20 +823,15 @@ nextdisk:
                        addr += length;
                start = 0;
        }
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);
@@ -1030,6 +1042,9 @@ rebuild_round_done:
                        cbp->bio_offset = offset + start;
                        cbp->bio_length = bp->bio_length;
                        cbp->bio_data = bp->bio_data;
+                       cbp->bio_ma = bp->bio_ma;
+                       cbp->bio_ma_offset = bp->bio_ma_offset;
+                       cbp->bio_ma_n = bp->bio_ma_n;
                        g_destroy_bio(bp);
                        nsd = &vol->v_subdisks[disk];
                        G_RAID_LOGREQ(2, cbp, "Retrying read from %d",

Modified: head/sys/geom/raid/tr_raid5.c
==============================================================================
--- head/sys/geom/raid/tr_raid5.c       Wed Oct 16 09:27:51 2013        
(r256609)
+++ head/sys/geom/raid/tr_raid5.c       Wed Oct 16 09:33:23 2013        
(r256610)
@@ -324,20 +324,15 @@ g_raid_tr_iostart_raid5_read(struct g_ra
                addr += length;
                start = 0;
        } while (remain > 0);
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL) {
                sd = cbp->bio_caller1;
                cbp->bio_caller1 = NULL;
                g_raid_subdisk_iostart(sd, cbp);
        }
        return;
 failure:
-       for (cbp = bioq_first(&queue); cbp != NULL;
-           cbp = bioq_first(&queue)) {
-               bioq_remove(&queue, cbp);
+       while ((cbp = bioq_takefirst(&queue)) != NULL)
                g_destroy_bio(cbp);
-       }
        if (bp->bio_error == 0)
                bp->bio_error = ENOMEM;
        g_raid_iodone(bp, bp->bio_error);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to