[Devel] [PATCH 4/4] ploop: give aligned regions into fuse fallocate()

Andrei Vagin avagin at openvz.org
Thu Feb 15 04:36:07 MSK 2018


[This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing at http://aka.ms/LearnAboutSpoofing]

fuse fallocate() can have requirements about granularity and alignment
for regions. For exmple, vstorage requires that all regions have to
be aligned onto 4096.

A block device has optimal values of granularity and alignment for
discard requests, but it has to handle unaligned requests too.

Each block device has the discard_zeroes_data attribute, which say
whether a block device returns zero for discarded block or not.

If we set it to 1, unaligned parts has to be filled in with zeros,
otherwise we can ignore them.

Signed-off-by: Andrei Vagin <avagin at openvz.org>
---
 drivers/block/ploop/io_kaio.c | 79 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 543f98b..2e48d13 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -246,6 +246,79 @@ static size_t kaio_kreq_pack(struct kaio_req *kreq, int *nr_segs,
        return copy;
 }

+static int kaio_fill_zero_submit(struct file *file,
+                       struct ploop_request *preq, loff_t off, size_t size)
+{
+       struct page *zero_page = ZERO_PAGE(0);
+       int nr_segs = 1, err = -ENOMEM;
+       struct kaio_req *kreq;
+
+       BUG_ON(size > PAGE_SIZE);
+
+       if (size == 0)
+               return 0;
+
+       kreq = kaio_kreq_alloc(preq, &nr_segs);
+       if (!kreq) {
+               PLOOP_REQ_SET_ERROR(preq, -ENOMEM);
+               return err;
+       }
+
+       kreq->bvecs[0].bv_page = zero_page;
+       kreq->bvecs[0].bv_len = size;
+       kreq->bvecs[0].bv_offset = 0;
+       atomic_inc(&preq->io_count);
+
+       err = kaio_kernel_submit(file, kreq, 1, size, off, REQ_WRITE);
+       if (err) {
+               PLOOP_REQ_SET_ERROR(preq, err);
+               ploop_complete_io_request(preq);
+               kfree(kreq);
+               return err;
+       }
+
+       return 0;
+}
+
+static int preprocess_discard_req(struct file *file, struct ploop_request *preq,
+                                       loff_t *poff, size_t *psize)
+{
+       unsigned int alignment, granularity, zeroes_data;
+       loff_t off = *poff, off_align;
+       size_t size = *psize;
+
+       alignment   = preq->plo->queue->limits.discard_alignment;
+       granularity = preq->plo->queue->limits.discard_granularity;
+       zeroes_data = preq->plo->queue->limits.discard_zeroes_data;
+
+       if (alignment) {
+               off_align = round_up(off, alignment);
+
+               if (zeroes_data &&
+                   kaio_fill_zero_submit(file, preq,
+                                               off, off_align - off))
+                       return -1;
+
+               size -= (off_align - off);
+               off = off_align;
+       }
+
+       if (granularity) {
+               size_t size_align;
+
+               size_align = round_down(size, granularity);
+               if (zeroes_data &&
+                   kaio_fill_zero_submit(file, preq,
+                               off + size_align, size - size_align))
+                       return -1;
+
+               size = size_align;
+       }
+
+       *poff = off;
+       *psize = size;
+       return 0;
+}
 /*
  * WRITE case:
  *
@@ -284,6 +357,11 @@ static void kaio_sbl_submit(struct file *file, struct ploop_request *preq,
        ploop_prepare_io_request(preq);

        size <<= 9;
+
+       if ((rw & REQ_DISCARD) &&
+           preprocess_discard_req(file, preq, &off, &size))
+               goto out;
+
        while (size > 0) {
                struct kaio_req *kreq;
                int nr_segs;
@@ -311,6 +389,7 @@ static void kaio_sbl_submit(struct file *file, struct ploop_request *preq,
                size -= copy;
        }

+out:
        kaio_complete_io_request(preq);
 }

--
1.8.3.1




More information about the Devel mailing list