[Devel] [PATCH rh7 07/38] ploop: rework accounting images_size

Andrey Smetanin asmetanin at virtuozzo.com
Fri May 15 09:48:08 PDT 2015


The way how we kept ploop_io_images_size up-to-date (should be always
equal to total number of bytes of all loaded image files) was very prone
to errors: first delta loaded kept actual io->size, then backup delta was
initialized with io->size=0; since then, if first delta was unloaded before
the second, unloading the second delta led to subtracting io->size=0 from
ploop_io_images_size. This is obviously incorrect.

The patch makes the accounting much more straightforward: the size of image
is actually the property of mapping, not a delta (because several deltas
may point to the same mapping). So, let's keep actual 'size' in ploop_mapping
structure and let every delta point to it.

No extra locking is needed because the image is either opened by several
device read-only, or one and only one device read-write.

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

Signed-off-by: Maxim Patlasov <MPatlasov at parallels.com>
---
 drivers/block/ploop/io_direct.c     | 10 +++++-----
 drivers/block/ploop/io_direct_map.c | 16 ++++++++++------
 include/linux/ploop/ploop.h         |  2 +-
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index 17dbf6c..ab74849 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -31,7 +31,7 @@
 int max_extent_map_pages __read_mostly;
 int min_extent_map_entries __read_mostly;
 
-/* total sum of io->size for all io structs */
+/* total sum of m->size for all ploop_mapping structs */
 atomic_long_t ploop_io_images_size = ATOMIC_LONG_INIT(0);
 
 /* Direct IO from/to file.
@@ -436,8 +436,8 @@ try_again:
 	mutex_unlock(&io->files.inode->i_mutex);
 
 	new_size = i_size_read(io->files.inode);
-	atomic_long_add(new_size - io->size, &ploop_io_images_size);
-	io->size = new_size;
+	atomic_long_add(new_size - *io->size_ptr, &ploop_io_images_size);
+	*io->size_ptr = new_size;
 
 	if (!err)
 		err = filemap_fdatawrite(io->files.mapping);
@@ -1684,8 +1684,8 @@ static int dio_truncate(struct ploop_io * io, struct file * file,
 	mutex_unlock(&io->files.inode->i_mutex);
 
 	new_size = i_size_read(io->files.inode);
-	atomic_long_sub(io->size - new_size, &ploop_io_images_size);
-	io->size = new_size;
+	atomic_long_sub(*io->size_ptr - new_size, &ploop_io_images_size);
+	*io->size_ptr = new_size;
 
 	if (!err)
 		err = dio_fsync(file);
diff --git a/drivers/block/ploop/io_direct_map.c b/drivers/block/ploop/io_direct_map.c
index 6b0886c..b3cb04d 100644
--- a/drivers/block/ploop/io_direct_map.c
+++ b/drivers/block/ploop/io_direct_map.c
@@ -31,6 +31,7 @@ struct ploop_mapping
 	struct address_space	* mapping;
 	int			readers;
 	unsigned long		saved_gfp_mask;
+	loff_t			size;
 
 	struct extent_map_tree	extent_root;
 };
@@ -81,6 +82,8 @@ out_unlock:
 			spin_unlock(&ploop_mappings_lock);
 			if (pm)
 				kfree(pm);
+			if (!err)
+				io->size_ptr = &m->size;
 			return err ? ERR_PTR(err) : &m->extent_root;
 		}
 	}
@@ -101,8 +104,9 @@ out_unlock:
 	pm->readers = rdonly ? 1 : -1;
 	list_add(&pm->list, &ploop_mappings);
 	mapping->host->i_flags |= S_SWAPFILE;
-	io->size = i_size_read(mapping->host);
-	atomic_long_add(io->size, &ploop_io_images_size);
+	io->size_ptr = &pm->size;
+	*io->size_ptr = i_size_read(mapping->host);
+	atomic_long_add(*io->size_ptr, &ploop_io_images_size);
 
 	pm->saved_gfp_mask = mapping_gfp_mask(mapping);
 	mapping_set_gfp_mask(mapping,
@@ -143,9 +147,9 @@ ploop_dio_close(struct ploop_io * io, int rdonly)
 			}
 
 			if (m->readers == 0) {
-				atomic_long_sub(io->size,
+				atomic_long_sub(*io->size_ptr,
 						&ploop_io_images_size);
-				io->size = 0;
+				*io->size_ptr = 0;
 				mapping->host->i_flags &= ~S_SWAPFILE;
 				list_del(&m->list);
 				pm = m;
@@ -191,9 +195,9 @@ int ploop_dio_upgrade(struct ploop_io * io)
 			err = -EBUSY;
 			if (m->readers == 1) {
 				loff_t new_size = i_size_read(io->files.inode);
-				atomic_long_add(new_size - io->size,
+				atomic_long_add(new_size - *io->size_ptr,
 						&ploop_io_images_size);
-				io->size = new_size;
+				*io->size_ptr = new_size;
 
 				m->readers = -1;
 				err = 0;
diff --git a/include/linux/ploop/ploop.h b/include/linux/ploop/ploop.h
index ea86ce6..d295cba 100644
--- a/include/linux/ploop/ploop.h
+++ b/include/linux/ploop/ploop.h
@@ -91,7 +91,7 @@ struct ploop_io
 {
 	struct ploop_device	*plo;
 
-	loff_t			size;
+	loff_t		       *size_ptr; /* NULL or points to ploop_mapping */
 	loff_t			prealloced_size;
 	struct ploop_request   *prealloc_preq;  /* preq who does prealloc */
 	loff_t			max_size;	/* Infinity */
-- 
1.9.3




More information about the Devel mailing list