Re: [Qemu-devel] [PATCH 06/12] nbd: support NBD_CMD_TRIM in the server

2011-09-14 Thread Paolo Bonzini

On 09/14/2011 05:44 PM, Christoph Hellwig wrote:

Map it to bdrv_discard.  The server can now expose NBD_FLAG_SEND_TRIM.


Note that discard support without a way to communicate the alignment/size
requirements,


Yep, especially because alignment can be as small as 512 for sparse raw, 
and as high as 65536 for qcow2...



and without the discard_zeroes_data flag is pretty much
useless.


... but right now in QEMU it is most useful with qcow2, so 
!discard_zeroes_data is pretty much the best you can do.


In general, QEMU's block layer does not really do much to pass 
information on discard features, which is why I didn't think much about 
these bits.  I'm interested in making NBD as featureful as the QEMU 
block layer, but beyond that not much. :)


Still you're obviously right, I'll talk to upstream.

Paolo



Re: [Qemu-devel] [PATCH 06/12] nbd: support NBD_CMD_TRIM in the server

2011-09-14 Thread Christoph Hellwig
On Thu, Sep 08, 2011 at 05:24:59PM +0200, Paolo Bonzini wrote:
> Map it to bdrv_discard.  The server can now expose NBD_FLAG_SEND_TRIM.

Note that discard support without a way to communicate the alignment/size
requirements, and without the discard_zeroes_data flag is pretty much
useless.  Can you work with the upstream developers to make sure it's
actually useful?




Re: [Qemu-devel] [PATCH 06/12] nbd: support NBD_CMD_TRIM in the server

2011-09-13 Thread Paolo Bonzini

On 09/13/2011 03:58 PM, Kevin Wolf wrote:

>  +case NBD_CMD_TRIM:
>  +TRACE("Request type is TRIM");
>  +bdrv_discard(bs, (request.from + dev_offset) / 512,
>  + request.len / 512);


Errors are completely ignored? Does the NBD protocol not allow to return
an error?


Actually it does, will fix.

Paolo



Re: [Qemu-devel] [PATCH 06/12] nbd: support NBD_CMD_TRIM in the server

2011-09-13 Thread Kevin Wolf
Am 08.09.2011 17:24, schrieb Paolo Bonzini:
> Map it to bdrv_discard.  The server can now expose NBD_FLAG_SEND_TRIM.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  block/nbd.c |   31 +++
>  nbd.c   |9 -
>  2 files changed, 39 insertions(+), 1 deletions(-)
> 
> diff --git a/block/nbd.c b/block/nbd.c
> index 5a7812c..964caa8 100644
> --- a/block/nbd.c
> +++ b/block/nbd.c
> @@ -275,6 +275,36 @@ static int nbd_flush(BlockDriverState *bs)
>  return 0;
>  }
>  
> +static int nbd_discard(BlockDriverState *bs, int64_t sector_num,
> +   int nb_sectors)
> +{
> +BDRVNBDState *s = bs->opaque;
> +struct nbd_request request;
> +struct nbd_reply reply;
> +
> +if (!(s->nbdflags & NBD_FLAG_SEND_TRIM)) {
> +return 0;
> +}
> +request.type = NBD_CMD_TRIM;
> +request.handle = (uint64_t)(intptr_t)bs;
> +request.from = sector_num * 512;;
> +request.len = nb_sectors * 512;
> +
> +if (nbd_send_request(s->sock, &request) == -1)
> +return -errno;
> +
> +if (nbd_receive_reply(s->sock, &reply) == -1)
> +return -errno;
> +
> +if (reply.error !=0)
> +return -reply.error;
> +
> +if (reply.handle != request.handle)
> +return -EIO;
> +
> +return 0;
> +}
> +
>  static void nbd_close(BlockDriverState *bs)
>  {
>  BDRVNBDState *s = bs->opaque;
> @@ -299,6 +329,7 @@ static BlockDriver bdrv_nbd = {
>  .bdrv_write  = nbd_write,
>  .bdrv_close  = nbd_close,
>  .bdrv_flush  = nbd_flush,
> +.bdrv_discard= nbd_discard,
>  .bdrv_getlength  = nbd_getlength,
>  .protocol_name   = "nbd",
>  };
> diff --git a/nbd.c b/nbd.c
> index b65fb4a..f089904 100644
> --- a/nbd.c
> +++ b/nbd.c
> @@ -194,7 +194,7 @@ int nbd_negotiate(int csock, off_t size, uint32_t flags)
>  cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
>  cpu_to_be64w((uint64_t*)(buf + 16), size);
>  cpu_to_be32w((uint32_t*)(buf + 24),
> - flags | NBD_FLAG_HAS_FLAGS |
> + flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
>   NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
>  memset(buf + 28, 0, 124);
>  
> @@ -703,6 +703,13 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t 
> size, uint64_t dev_offset,
>  if (nbd_send_reply(csock, &reply) == -1)
>  return -1;
>  break;
> +case NBD_CMD_TRIM:
> +TRACE("Request type is TRIM");
> +bdrv_discard(bs, (request.from + dev_offset) / 512,
> + request.len / 512);

Errors are completely ignored? Does the NBD protocol not allow to return
an error?

Kevin



[Qemu-devel] [PATCH 06/12] nbd: support NBD_CMD_TRIM in the server

2011-09-08 Thread Paolo Bonzini
Map it to bdrv_discard.  The server can now expose NBD_FLAG_SEND_TRIM.

Signed-off-by: Paolo Bonzini 
---
 block/nbd.c |   31 +++
 nbd.c   |9 -
 2 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 5a7812c..964caa8 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -275,6 +275,36 @@ static int nbd_flush(BlockDriverState *bs)
 return 0;
 }
 
+static int nbd_discard(BlockDriverState *bs, int64_t sector_num,
+   int nb_sectors)
+{
+BDRVNBDState *s = bs->opaque;
+struct nbd_request request;
+struct nbd_reply reply;
+
+if (!(s->nbdflags & NBD_FLAG_SEND_TRIM)) {
+return 0;
+}
+request.type = NBD_CMD_TRIM;
+request.handle = (uint64_t)(intptr_t)bs;
+request.from = sector_num * 512;;
+request.len = nb_sectors * 512;
+
+if (nbd_send_request(s->sock, &request) == -1)
+return -errno;
+
+if (nbd_receive_reply(s->sock, &reply) == -1)
+return -errno;
+
+if (reply.error !=0)
+return -reply.error;
+
+if (reply.handle != request.handle)
+return -EIO;
+
+return 0;
+}
+
 static void nbd_close(BlockDriverState *bs)
 {
 BDRVNBDState *s = bs->opaque;
@@ -299,6 +329,7 @@ static BlockDriver bdrv_nbd = {
 .bdrv_write= nbd_write,
 .bdrv_close= nbd_close,
 .bdrv_flush= nbd_flush,
+.bdrv_discard  = nbd_discard,
 .bdrv_getlength= nbd_getlength,
 .protocol_name = "nbd",
 };
diff --git a/nbd.c b/nbd.c
index b65fb4a..f089904 100644
--- a/nbd.c
+++ b/nbd.c
@@ -194,7 +194,7 @@ int nbd_negotiate(int csock, off_t size, uint32_t flags)
 cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
 cpu_to_be64w((uint64_t*)(buf + 16), size);
 cpu_to_be32w((uint32_t*)(buf + 24),
- flags | NBD_FLAG_HAS_FLAGS |
+ flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
  NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
 memset(buf + 28, 0, 124);
 
@@ -703,6 +703,13 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, 
uint64_t dev_offset,
 if (nbd_send_reply(csock, &reply) == -1)
 return -1;
 break;
+case NBD_CMD_TRIM:
+TRACE("Request type is TRIM");
+bdrv_discard(bs, (request.from + dev_offset) / 512,
+ request.len / 512);
+if (nbd_send_reply(csock, &reply) == -1)
+return -1;
+break;
 default:
 LOG("invalid request type (%u) received", request.type);
 errno = EINVAL;
-- 
1.7.6