[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