When the feature is enabled, set QUEUE_FLAG_DISCARD and transmit those as NBD_CMD_TRIM requests.
I used "trim" instead of "discard" to avoid confusion with the existing NBD_CMD_DISC that is used for disconnect. Cc: Paul Clements <[email protected]> Cc: <[email protected]> Reviewed-by: Paul Clements <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> --- drivers/block/nbd.c | 14 +++++++++++++- include/linux/nbd.h | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 930b4df..8094bd8 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -104,6 +104,7 @@ static const char *nbdcmd_to_ascii(int cmd) case NBD_CMD_WRITE: return "write"; case NBD_CMD_DISC: return "disconnect"; case NBD_CMD_FLUSH: return "flush"; + case NBD_CMD_TRIM: return "trim (discard)"; } return "invalid"; } @@ -470,12 +471,16 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req) nbd_cmd(req) = NBD_CMD_READ; if (rq_data_dir(req) == WRITE) { - nbd_cmd(req) = NBD_CMD_WRITE; if (lo->flags & NBD_FLAG_READ_ONLY) { printk(KERN_ERR "%s: Write on read-only\n", lo->disk->disk_name); goto error_out; } + if ((req->cmd_flags & REQ_DISCARD)) { + WARN_ON(!(lo->flags & NBD_FLAG_HAS_TRIM)); + nbd_cmd(req) = NBD_CMD_TRIM; + } else + nbd_cmd(req) = NBD_CMD_WRITE; } if (req->cmd_flags & REQ_FLUSH) { @@ -699,6 +704,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, return -EINVAL; mutex_unlock(&lo->tx_lock); + if (lo->flags & NBD_FLAG_HAS_TRIM) + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, lo->disk->queue); + else + queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, lo->disk->queue); if (lo->flags & NBD_FLAG_ROTATIONAL) queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, lo->disk->queue); else @@ -824,6 +833,9 @@ static int __init nbd_init(void) * unless the relevant flag bit is set */ blk_queue_flush(disk->queue, REQ_FLUSH | REQ_FUA); + disk->queue->limits.discard_granularity = 512; + disk->queue->limits.max_discard_sectors = UINT_MAX; + disk->queue->limits.discard_zeroes_data = 0; } if (register_blkdev(NBD_MAJOR, "nbd")) { diff --git a/include/linux/nbd.h b/include/linux/nbd.h index 5037b0b..52eae2f 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h @@ -33,7 +33,8 @@ enum { NBD_CMD_READ = 0, NBD_CMD_WRITE = 1, NBD_CMD_DISC = 2, - NBD_CMD_FLUSH = 3 + NBD_CMD_FLUSH = 3, + NBD_CMD_TRIM = 4 }; #define NBD_CMD_MASK_COMMAND 0x0000ffff @@ -45,6 +46,7 @@ enum { #define NBD_FLAG_SEND_FLUSH (1 << 2) /* Send FLUSH */ #define NBD_FLAG_SEND_FUA (1 << 3) /* Send FUA (Force Unit Access) */ #define NBD_FLAG_ROTATIONAL (1 << 4) /* Use elevator algorithm - rotational media */ +#define NBD_FLAG_HAS_TRIM (1 << 5) /* Send TRIM (discard) */ #define nbd_cmd(req) ((req)->cmd[0]) -- 1.7.6 ------------------------------------------------------------------------------ BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA Learn about the latest advances in developing for the BlackBerry® mobile platform with sessions, labs & more. See new tools and technologies. Register for BlackBerry® DevCon today! http://p.sf.net/sfu/rim-devcon-copy1 _______________________________________________ Nbd-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nbd-general
