[Devel] [PATCH RHEL7 COMMIT] ploop: handle discard requests via fallocate

Konstantin Khorenko khorenko at virtuozzo.com
Thu Feb 15 17:34:47 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-693.17.1.vz7.43.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.17.1.vz7.43.5
------>
commit cdbc91de0913009e15ad3af00003fb9c5755c710
Author: Andrei Vagin <avagin at openvz.org>
Date:   Thu Feb 15 17:34:47 2018 +0300

    ploop: handle discard requests via fallocate
    
    Currently ploop can be compacted, but in this case discard requests are
    hanled with help of a userspace tool.
    
    This patch adds a native support for discard requests with a few
    restrictions.
    
    Currrenty this works only for raw images on a fuse file system due to
    these reasons:
    * Only the fuse file system allows to execute fallocate asynchroniously.
    * pio_direct (ext4) requires that all blocks in image were allocated
      and initalized.
    * The ploop1 format requires more changes to hanlde an index table.
    
    Signed-off-by: Andrei Vagin <avagin at openvz.org>
---
 drivers/block/ploop/dev.c        | 18 ++++++++++++++----
 drivers/block/ploop/fmt_ploop1.c |  2 ++
 drivers/block/ploop/io_direct.c  |  1 +
 drivers/block/ploop/io_kaio.c    |  8 +++++++-
 include/linux/ploop/ploop.h      |  1 +
 5 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 12fde0064f51..6c0b3c0252c0 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -517,7 +517,8 @@ ploop_bio_queue(struct ploop_device * plo, struct bio * bio,
 	    ploop_pb_check_and_clear_bit(plo->pbd, preq->req_cluster))
 		ploop_set_blockable(plo, preq);
 
-	if (unlikely(bio->bi_rw & REQ_DISCARD)) {
+	if (test_bit(PLOOP_S_DISCARD, &plo->state) &&
+	    unlikely(bio->bi_rw & REQ_DISCARD)) {
 		int clu_size = 1 << plo->cluster_log;
 		int i = (clu_size - 1) & bio->bi_sector;
 		int err = 0;
@@ -570,13 +571,13 @@ ploop_bio_queue(struct ploop_device * plo, struct bio * bio,
 
 	__TRACE("A %p %u\n", preq, preq->req_cluster);
 
-	if (unlikely(bio->bi_rw & REQ_DISCARD))
+	if (unlikely(preq->state & (1 << PLOOP_REQ_DISCARD)))
 		plo->bio_discard_qlen--;
 	else
 		plo->bio_qlen--;
 	ploop_entry_add(plo, preq);
 
-	if (bio->bi_size && !(bio->bi_rw & REQ_DISCARD))
+	if (bio->bi_size && !(preq->state & (1 << PLOOP_REQ_DISCARD)))
 		insert_entry_tree(plo, preq, drop_list);
 
 	trace_bio_queue(preq);
@@ -1487,7 +1488,7 @@ void ploop_complete_io_state(struct ploop_request * preq)
 
 	spin_lock_irqsave(&plo->lock, flags);
 	__TRACE("C %p %u\n", preq, preq->req_cluster);
-	if (preq->error)
+	if (preq->error && !(preq->req_rw & REQ_DISCARD))
 		set_bit(PLOOP_S_ABORT, &plo->state);
 
 	list_add_tail(&preq->list, &plo->ready_queue);
@@ -2570,6 +2571,15 @@ static void ploop_req_state_process(struct ploop_request * preq)
 			break;
 		}
 
+		if ((preq->req_rw & REQ_DISCARD) &&
+		    !test_bit(PLOOP_REQ_DISCARD, &preq->state) &&
+		    test_bit(PLOOP_S_NO_FALLOC_DISCARD, &plo->state)) {
+			preq->eng_state = PLOOP_E_COMPLETE;
+			preq->error = -EOPNOTSUPP;
+			ploop_complete_io_state(preq);
+			return;
+		}
+
 		ploop_entry_request(preq);
 		break;
 
diff --git a/drivers/block/ploop/fmt_ploop1.c b/drivers/block/ploop/fmt_ploop1.c
index 0034216fc3e8..c2be627b924d 100644
--- a/drivers/block/ploop/fmt_ploop1.c
+++ b/drivers/block/ploop/fmt_ploop1.c
@@ -189,6 +189,8 @@ ploop1_open(struct ploop_delta * delta)
 	    ((u64)ph->bd_size + ph->l1_off) << 9)
 		delta->flags |= PLOOP_FMT_PREALLOCATED;
 
+	set_bit(PLOOP_S_NO_FALLOC_DISCARD, &delta->plo->state);
+
 	return 0;
 
 out_err:
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 9fd2d8f67df9..6ea98901b7d4 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -1032,6 +1032,7 @@ dio_init(struct ploop_io * io)
 	init_timer(&io->fsync_timer);
 	io->fsync_timer.function = fsync_timeout;
 	io->fsync_timer.data = (unsigned long)io;
+	set_bit(PLOOP_S_NO_FALLOC_DISCARD, &io->plo->state);
 
 	return 0;
 }
diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index c7f3bc93bf57..22037f143151 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -167,7 +167,9 @@ static int kaio_kernel_submit(struct file *file, struct kaio_req *kreq,
 	if (!iocb)
 		return -ENOMEM;
 
-	if (rw & REQ_WRITE)
+	if (rw & REQ_DISCARD)
+		op = IOCB_CMD_UNMAP_ITER;
+	else if (rw & REQ_WRITE)
 		op = IOCB_CMD_WRITE_ITER;
 	else
 		op = IOCB_CMD_READ_ITER;
@@ -207,6 +209,10 @@ static size_t kaio_kreq_pack(struct kaio_req *kreq, int *nr_segs,
 
 	BUG_ON(b->bi_idx);
 
+	if (b->bi_vcnt == 0) { /* REQ_DISCARD */
+		*nr_segs = 0;
+		return size;
+	}
 	while (1) {
 		int nr = min_t(int, kreq_nr_max, b->bi_vcnt - idx);
 		BUG_ON(!nr);
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index f13b7caa4128..fd683f79956d 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -53,6 +53,7 @@ enum {
 	PLOOP_S_ENOSPC_EVENT,	/* ENOSPC event happened but but was not
 				 * consumed by userspace yet */
 	PLOOP_S_CONGESTED,	/* Too many bios submitted to us */
+	PLOOP_S_NO_FALLOC_DISCARD, /* Unable to handle discard requests by fallocate */
 	PLOOP_S_DISCARD,	/* ploop is ready to handle discard request */
 	PLOOP_S_DISCARD_LOADED,	/* A discard request was handled and
 				   free blocks loaded */


More information about the Devel mailing list