[rh7] ploop: kaio: Close race between truncate thread and grow

Submitted by Kirill Tkhai on Feb. 18, 2020, 8:31 a.m.

Details

Message ID 158201467865.16147.7951828346207457161.stgit@localhost.localdomain
State New
Series "ploop: kaio: Close race between truncate thread and grow"
Headers show

Commit Message

Kirill Tkhai Feb. 18, 2020, 8:31 a.m.
.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 <ktkhai@virtuozzo.com>
---
 drivers/block/ploop/io_kaio.c |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

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;
 }