Dima, please review.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 03/13/2016 09:01 PM, Maxim Patlasov wrote:
Long time ago, when ploop used FALLOC_FL_KEEP_SIZE, the logic of
updating io->prealloced_size was implemented correctly:

1) Calculate [pos, end_pos) -- a fragment of image file we're going to
    write to.

2) If [pos, end_pos) is beyond end of file (i.e. end_pos > i_size), let's
    either simply use preallocated space:

        io->prealloced_size -= clu_siz;

    or firstly prealloc more space and then use the space:

        fallocate(file, mode, pos, prealloc);
        io->prealloced_size -= clu_siz;

Now, when ploop doesn't use FALLOC_FL_KEEP_SIZE, the logic above doesn't
work as expected because after prealloc, i_size is extended and the condition
"end_pos > i_size" is false. Hence, a lot of writes to preallocated space
come without "io->prealloced_size -= clu_siz;". And, when all preallocated
space is logically exhausted, io->prealloced_size is still not zero. Then
ploop skips fallocate() and goes to pagecache_write_begin() stuff.

Signed-off-by: Maxim Patlasov <[email protected]>
---
  drivers/block/ploop/io_direct.c |   12 +++++++-----
  1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index cfd7882..3678d5b 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -69,7 +69,7 @@ struct bio_list_walk

  static int cached_submit(struct ploop_io *io, iblock_t iblk,
              struct ploop_request * preq,
-             struct bio_list * sbl, unsigned int size);
+             struct bio_list * sbl, unsigned int size, bool use_prealloc);

  static void
  dio_submit(struct ploop_io *io, struct ploop_request * preq,
@@ -268,7 +268,7 @@ write_unint:
        ploop_add_lockout(preq, 0);
        spin_unlock_irq(&preq->plo->lock);

-       err = cached_submit(io, iblk, preq, sbl, size);
+       err = cached_submit(io, iblk, preq, sbl, size, false);
        goto out;

  write_unint_fail:
@@ -362,7 +362,7 @@ static inline void bzero_page(struct page *page)

  static int
  cached_submit(struct ploop_io *io, iblock_t iblk, struct ploop_request * preq,
-             struct bio_list * sbl, unsigned int size)
+             struct bio_list * sbl, unsigned int size, bool use_prealloc)
  {
        struct ploop_device * plo = preq->plo;
        int err = 0;
@@ -370,14 +370,16 @@ cached_submit(struct ploop_io *io, iblock_t iblk, struct 
ploop_request * preq,
        loff_t clu_siz = 1 << (plo->cluster_log + 9);
        struct bio_iter biter;
        loff_t new_size;
+       loff_t used_pos;

        trace_cached_submit(preq);

        pos = (loff_t)iblk << (plo->cluster_log + 9);
        end_pos = pos + clu_siz;
+       used_pos = (io->alloc_head - 1) << (io->plo->cluster_log + 9);

  #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24)
-       if (end_pos > i_size_read(io->files.inode) &&
+       if (use_prealloc && end_pos > used_pos &&
            io->files.file->f_op->fallocate &&
            io->files.flags & EXT4_EXTENTS_FL) {
                if (unlikely(io->prealloced_size < clu_siz)) {
@@ -701,7 +703,7 @@ dio_submit_alloc(struct ploop_io *io, struct ploop_request 
* preq,
                return;
        }

-       err = cached_submit(io, iblk, preq, sbl, size);
+       err = cached_submit(io, iblk, preq, sbl, size, true);
        if (err) {
                if (err == -ENOSPC)
                        io->alloc_head--;


_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to