[Nbd] [CFT][PATCH 4/4] nbd: map DISCARD requests to a new nbd request type
- To: nbd-general@...72...
- Cc: Paul Clements <Paul.Clements@...124...>
- Subject: [Nbd] [CFT][PATCH 4/4] nbd: map DISCARD requests to a new nbd request type
- From: Paolo Bonzini <pbonzini@...696...>
- Date: Tue, 13 Sep 2011 13:09:53 +0200
- Message-id: <1315912193-25959-5-git-send-email-pbonzini@...696...>
- In-reply-to: <1315912193-25959-1-git-send-email-pbonzini@...696...>
- References: <1315912193-25959-1-git-send-email-pbonzini@...696...>
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 <Paul.Clements@...124...>
Cc: <nbd-general@...72...>
Reviewed-by: Paul Clements <Paul.Clements@...124...>
Signed-off-by: Paolo Bonzini <pbonzini@...696...>
---
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
Reply to: