[Devel] [PATCH RHEL7 COMMIT] ploop: rework accounting images_size
Konstantin Khorenko
khorenko at odin.com
Mon May 18 21:26:58 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.1
------>
commit 102acd98b5d6ddf9a310a0c0a54e21d6903d23ab
Author: Andrey Smetanin <asmetanin at virtuozzo.com>
Date: Tue May 19 08:26:58 2015 +0400
ploop: rework accounting images_size
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 */
More information about the Devel
mailing list