.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