>>> On 09.08.11 at 09:11, Li Dongyang <lidongyang@xxxxxxxxxx> wrote:
> 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.
Same general comments as for the frontend patch, plus ...
> 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)
static?
> +{
> + 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
These two constants are being used only internally to the driver, so
they shouldn't become part of the interface (and you then also
shouldn't merge them into a variable that is used for interface defined
flags).
Jan
>
> #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|