[Devel] [vzlin-dev] [PATCH rh7] ploop: fix direct_io prealloc checks
Dmitry Monakhov
dmonakhov at openvz.org
Wed Mar 16 05:41:18 PDT 2016
Maxim Patlasov <mpatlasov at virtuozzo.com> writes:
> Long time ago, when ploop used FALLOC_FL_KEEP_SIZE, the logic of
> updating io->prealloced_size was implemented correctly:
Ack-by: Dmitry Monakhov <dmonakhov at parallels.com>
>
> 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 <mpatlasov at virtuozzo.com>
> ---
> 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--;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <http://lists.openvz.org/pipermail/devel/attachments/20160316/c437d131/attachment.sig>
More information about the Devel
mailing list