[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/2] make blkback driver handle trim request
now blkback driver can handle the trim request from guest, we will forward the request to phy if it's really a device has trim, or we'll punch a hole on the image file. Signed-off-by: Li Dongyang <lidongyang@xxxxxxxxxx> --- drivers/xen/blkback/blkback.c | 77 ++++++++++++++++++++++++++++++++++++++ drivers/xen/blkback/common.h | 2 +- drivers/xen/blkback/xenbus.c | 57 ++++++++++++++++++++++++++++ include/xen/interface/io/blkif.h | 2 + 4 files changed, 137 insertions(+), 1 deletions(-) diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c index bb588e2..11aa09d 100644 --- a/drivers/xen/blkback/blkback.c +++ b/drivers/xen/blkback/blkback.c @@ -40,6 +40,9 @@ #include <linux/freezer.h> #include <linux/list.h> #include <linux/delay.h> +#include <linux/loop.h> +#include <linux/falloc.h> +#include <linux/fs.h> #include <xen/balloon.h> #include <xen/evtchn.h> #include <xen/gnttab.h> @@ -112,6 +115,9 @@ static int do_block_io_op(blkif_t *blkif); static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req, pending_req_t *pending_req); +static void dispatch_trim(blkif_t *blkif, + blkif_request_trim_t *req, + pending_req_t *pending_req); static void make_response(blkif_t *blkif, u64 id, unsigned short op, int st); @@ -369,6 +375,9 @@ static int do_block_io_op(blkif_t *blkif) blkif->st_wr_req++; dispatch_rw_block_io(blkif, &req, pending_req); break; + case BLKIF_OP_TRIM: + dispatch_trim(blkif, (blkif_request_trim_t *)&req, pending_req); + break; case BLKIF_OP_PACKET: DPRINTK("error: block operation BLKIF_OP_PACKET not implemented\n"); blkif->st_pk_req++; @@ -395,6 +404,74 @@ static int do_block_io_op(blkif_t *blkif) return more_to_do; } +static void dispatch_trim(blkif_t *blkif, + blkif_request_trim_t *req, + pending_req_t *pending_req) +{ + struct phys_req preq; + struct block_device *bdev = blkif->vbd.bdev; + int status = BLKIF_RSP_OKAY; + int err = 0; + + preq.dev = req->handle; + preq.sector_number = req->sector_number; + preq.nr_sects = req->nr_sectors; + + blkif_get(blkif); + if (blkif->vbd.type & VDISK_PHY_BACKEND) { + /* backend is a phy device, just forward the trim request */ + if (vbd_translate(&preq, blkif, WRITE) != 0) { + DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", + "discard", + preq.sector_number, + preq.sector_number + preq.nr_sects, preq.dev); + status = BLKIF_RSP_ERROR; + goto fail_response; + } + err = blkdev_issue_discard(bdev, + req->sector_number, + req->nr_sectors, + GFP_KERNEL, 0); + } else if (blkif->vbd.type & VDISK_FILE_BACKEND) { + /* backend is a file, punch a hole in the file */ + struct loop_device *lo = bdev->bd_disk->private_data; + struct file *file = lo->lo_backing_file; + struct inode *inode = file->f_path.dentry->d_inode; + if (vbd_translate(&preq, blkif, WRITE) != 0) { + DPRINTK("access denied: %s of [%llu,%llu] on dev=%04x\n", + "discard", + preq.sector_number, + preq.sector_number + preq.nr_sects, preq.dev); + status = BLKIF_RSP_ERROR; + goto fail_response; + } + if (inode->i_op->fallocate) { + err = inode->i_op->fallocate(inode, + FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, + req->sector_number << 9, + req->nr_sectors << 9); + } else + err = -EOPNOTSUPP; + } else { + status = BLKIF_RSP_EOPNOTSUPP; + goto fail_response; + } + + if (err == -EOPNOTSUPP) { + DPRINTK("blkback: discard op failed, not supported\n"); + status = BLKIF_RSP_EOPNOTSUPP; + } else if (err) + status = BLKIF_RSP_ERROR; + +fail_response: + make_response(blkif, req->id, req->operation, status); + blkif_put(blkif); + free_req(pending_req); + if (status) + msleep(1); /* back off a bit */ + return; +} + static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req, pending_req_t *pending_req) diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h index 7ac10df..8423fd9 100644 --- a/drivers/xen/blkback/common.h +++ b/drivers/xen/blkback/common.h @@ -126,7 +126,7 @@ unsigned long vbd_secsize(struct vbd *vbd); struct phys_req { unsigned short dev; - unsigned short nr_sects; + blkif_sector_t nr_sects; struct block_device *bdev; blkif_sector_t sector_number; }; diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index 639146c..d379fc8 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -219,6 +219,59 @@ int blkback_barrier(struct xenbus_transaction xbt, return err; } +int blkback_discard(struct xenbus_transaction xbt, struct backend_info *be) +{ + struct xenbus_device *dev = be->dev; + struct vbd *vbd = &be->blkif->vbd; + char *type; + int err; + int state = 0; + + type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL); + if (!IS_ERR(type)) { + if (strcmp(type, "file") == 0) + state = 1; + vbd->type |= VDISK_FILE_BACKEND; + if (strcmp(type, "phy") == 0) { + struct block_device *bdev = be->blkif->vbd.bdev; + struct request_queue *q = bdev_get_queue(bdev); + if (blk_queue_discard(q)) { + err = xenbus_printf(xbt, dev->nodename, + "discard_granularity", "%u", + q->limits.discard_granularity); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard_granularity"); + goto kfree; + } + err = xenbus_printf(xbt, dev->nodename, + "discard_alignment", "%u", + q->limits.discard_alignment); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard_alignment"); + goto kfree; + } + state = 1; + vbd->type |= VDISK_PHY_BACKEND; + } + } + } else { + err = PTR_ERR(type); + xenbus_dev_fatal(dev, err, "reading type"); + goto out; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-discard", + "%d", state); + if (err) + xenbus_dev_fatal(dev, err, "writing feature-discard"); +kfree: + kfree(type); +out: + return err; +} + /** * Entry point to this code when a new device is created. Allocate the basic * structures, and watch the store waiting for the hotplug scripts to tell us @@ -444,6 +497,10 @@ again: if (err) goto abort; + err = blkback_discard(xbt, be); + if (err) + goto abort; + err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", vbd_size(&be->blkif->vbd)); if (err) { diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index e239060..aa483cc 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h @@ -172,5 +172,7 @@ DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); #define VDISK_CDROM 0x1 #define VDISK_REMOVABLE 0x2 #define VDISK_READONLY 0x4 +#define VDISK_FILE_BACKEND 0x8 +#define VDISK_PHY_BACKEND 0x10 #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */ -- 1.7.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |