[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Handle mis-aligned I/O requests in blkback driver.



ChangeSet 1.1878, 2005/05/20 17:51:49+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Handle mis-aligned I/O requests in blkback driver.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 blkback.c |   49 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 44 insertions(+), 5 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c 
b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c     2005-05-20 
13:04:43 -04:00
+++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c     2005-05-20 
13:04:43 -04:00
@@ -47,6 +47,8 @@
     atomic_t       pendcnt;
     unsigned short operation;
     int            status;
+    void          *bounce_page;
+    unsigned int   bounce_off, bounce_len;
 } pending_req_t;
 
 /*
@@ -232,6 +234,15 @@
     if ( atomic_dec_and_test(&pending_req->pendcnt) )
     {
         int pending_idx = pending_req - pending_reqs;
+        if ( unlikely(pending_req->bounce_page != NULL) )
+        {
+            memcpy((void *)(MMAP_VADDR(pending_idx, 0) +
+                            pending_req->bounce_off),
+                   (void *)((unsigned long)pending_req->bounce_page +
+                            pending_req->bounce_off),
+                   pending_req->bounce_len);
+            free_page((unsigned long)pending_req->bounce_page);
+        }
         fast_flush_area(pending_idx, pending_req->nr_pages);
         make_response(pending_req->blkif, pending_req->id,
                       pending_req->operation, pending_req->status);
@@ -452,6 +463,7 @@
     pending_req->operation = operation;
     pending_req->status    = BLKIF_RSP_OKAY;
     pending_req->nr_pages  = nr_psegs;
+    pending_req->bounce_page = NULL;
     atomic_set(&pending_req->pendcnt, nr_psegs);
     pending_cons++;
 
@@ -511,11 +523,38 @@
         bio->bi_end_io  = end_block_io_op;
         bio->bi_sector  = phys_seg[i].sector_number;
 
-        bio_add_page(
-            bio,
-            virt_to_page(MMAP_VADDR(pending_idx, i)),
-            phys_seg[i].nr_sects << 9,
-            phys_seg[i].buffer & ~PAGE_MASK);
+        /* Is the request misaligned with respect to hardware sector size? */
+        if ( ((bio->bi_sector | phys_seg[i].nr_sects) &
+              ((bdev_hardsect_size(bio->bi_bdev) >> 9) - 1)) )
+        {
+            /* We can't bounce scatter-gather requests. */
+            if ( (nr_psegs != 1) ||
+                 ((pending_req->bounce_page = (void *)
+                   __get_free_page(GFP_KERNEL)) == NULL) )
+            {
+                printk("xen_blk: Unaligned scatter-gather request!\n");
+                bio_put(bio);
+                __end_block_io_op(pending_req, 0);
+                continue;
+            }
+
+            /* Record offset and length within a bounce page. */
+            pending_req->bounce_off = (bio->bi_sector << 9) & ~PAGE_MASK;
+            pending_req->bounce_len = phys_seg[i].nr_sects << 9;
+
+            /* Submit a page-aligned I/O. */
+            bio->bi_sector &= ~((PAGE_SIZE >> 9) - 1);
+            bio_add_page(
+                bio, virt_to_page(pending_req->bounce_page), PAGE_SIZE, 0);
+        }
+        else
+        {
+            bio_add_page(
+                bio,
+                virt_to_page(MMAP_VADDR(pending_idx, i)),
+                phys_seg[i].nr_sects << 9,
+                phys_seg[i].buffer & ~PAGE_MASK);
+        }
 
         if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue )
         {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.