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

[Xen-devel] [PATCH] [RFC] qemu-upstream: add discard support for xen_disk



Implement discard support for xen_disk. It makes use of the existing
discard code in qemu.

The discard support is enabled unconditionally. But it would be worth to
have a knob to disable it in case the backing file was intentionally
created non-sparse to avoid fragmentation.
How could this be knob be passed from domU.cfg:disk=[] to the actual
qemu process?

blkfront_setup_discard should check for "qdisk" instead of (, or in
addition to?) "file" to actually make use of this new feature.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
---
 hw/block/xen_blkif.h | 12 ++++++++++++
 hw/block/xen_disk.c  | 16 ++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/hw/block/xen_blkif.h b/hw/block/xen_blkif.h
index c0f4136..711b692 100644
--- a/hw/block/xen_blkif.h
+++ b/hw/block/xen_blkif.h
@@ -79,6 +79,12 @@ static inline void blkif_get_x86_32_req(blkif_request_t 
*dst, blkif_x86_32_reque
        dst->handle = src->handle;
        dst->id = src->id;
        dst->sector_number = src->sector_number;
+       if (src->operation == BLKIF_OP_DISCARD) {
+               struct blkif_request_discard *s = (void *)src;
+               struct blkif_request_discard *d = (void *)dst;
+               d->nr_sectors = s->nr_sectors;
+               return;
+       }
        if (n > src->nr_segments)
                n = src->nr_segments;
        for (i = 0; i < n; i++)
@@ -94,6 +100,12 @@ static inline void blkif_get_x86_64_req(blkif_request_t 
*dst, blkif_x86_64_reque
        dst->handle = src->handle;
        dst->id = src->id;
        dst->sector_number = src->sector_number;
+       if (src->operation == BLKIF_OP_DISCARD) {
+               struct blkif_request_discard *s = (void *)src;
+               struct blkif_request_discard *d = (void *)dst;
+               d->nr_sectors = s->nr_sectors;
+               return;
+       }
        if (n > src->nr_segments)
                n = src->nr_segments;
        for (i = 0; i < n; i++)
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 03e30d7..555c2d6 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -68,6 +68,8 @@ struct ioreq {
     int                 presync;
     int                 postsync;
     uint8_t             mapped;
+    int64_t             sector_num;
+    int                 nb_sectors;
 
     /* grant mapping */
     uint32_t            domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
@@ -232,6 +234,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
+    struct blkif_request_discard *discard_req = (void *)&ioreq->req;
     uintptr_t mem;
     size_t len;
     int i;
@@ -244,6 +247,10 @@ static int ioreq_parse(struct ioreq *ioreq)
     case BLKIF_OP_READ:
         ioreq->prot = PROT_WRITE; /* to memory */
         break;
+    case BLKIF_OP_DISCARD:
+        ioreq->sector_num = discard_req->sector_number;
+        ioreq->nb_sectors = discard_req->nr_sectors;
+        return 0;
     case BLKIF_OP_FLUSH_DISKCACHE:
         ioreq->presync = 1;
         if (!ioreq->req.nr_segments) {
@@ -521,6 +528,13 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
                         &ioreq->v, ioreq->v.size / BLOCK_SIZE,
                         qemu_aio_complete, ioreq);
         break;
+    case BLKIF_OP_DISCARD:
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->nb_sectors * 
BLOCK_SIZE, BDRV_ACCT_WRITE);
+        ioreq->aio_inflight++;
+        bdrv_aio_discard(blkdev->bs,
+                        ioreq->sector_num, ioreq->nb_sectors,
+                        qemu_aio_complete, ioreq);
+        break;
     default:
         /* unknown operation (shouldn't happen -- parse catches this) */
         goto err;
@@ -764,6 +778,7 @@ static int blk_init(struct XenDevice *xendev)
      */
     xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1);
     xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
+    xenstore_write_be_int(&blkdev->xendev, "feature-discard", 1);
     xenstore_write_be_int(&blkdev->xendev, "info", info);
 
     g_free(directiosafe);
@@ -801,6 +816,7 @@ static int blk_connect(struct XenDevice *xendev)
         qflags |= BDRV_O_RDWR;
         readonly = false;
     }
+    qflags |= BDRV_O_UNMAP;
 
     /* init qemu block driver */
     index = (blkdev->xendev.dev - 202 * 256) / 16;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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