.submit_alloc may queue prealloc_preq and set io->prealloc_size.
Despite .alloc is called under quiesce state, previously submitted
prealloc_preq may be handled by truncate thread. After quiesce state
is released, ploop thread updates io->prealloced_size, but inode
size is less, since kaio_alloc_sync() truncates image under them.
Fix that.

https://jira.sw.ru/browse/PSBM-101533

Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com>
---
 drivers/block/ploop/io_kaio.c |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/block/ploop/io_kaio.c b/drivers/block/ploop/io_kaio.c
index 9ed448bf0026..51ee627c4037 100644
--- a/drivers/block/ploop/io_kaio.c
+++ b/drivers/block/ploop/io_kaio.c
@@ -890,10 +890,26 @@ static int kaio_sync_read_many(struct ploop_io *io, 
struct page *pages[],
 
 static int kaio_alloc_sync(struct ploop_io * io, loff_t pos, loff_t len)
 {
-       int err = __kaio_truncate(io, io->files.file, pos + len);
+       struct ploop_device *plo = io->plo;
+       loff_t size = pos + len;
+       int err = 0;
+       u32 a_h;
 
-       if (!err)
-               io->alloc_head = (pos + len) >> (io->plo->cluster_log + 9);
+       a_h = size >> (plo->cluster_log + 9);
+
+       /* Close race with truncate thread */
+       if (io->prealloc_preq && size < io->prealloc_preq->prealloc_size)
+               size = io->prealloc_preq->prealloc_size;
+       if (size < io->prealloced_size)
+               size = io->prealloced_size;
+
+       if (size > i_size_read(io->files.inode))
+               err = __kaio_truncate(io, io->files.file, size);
+
+       if (!err) {
+               WARN_ON(io->alloc_head > a_h);
+               io->alloc_head = a_h;
+       }
 
        return err;
 }


_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to