WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH 2/2] make blkback driver handle trim request

>>> 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