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 09fe781813a8c4e74ad6f9621cf26acb705424f4 Author: Andrey Smetanin <asmeta...@virtuozzo.com> Date: Tue May 19 08:26:54 2015 +0400
ploop: fix accounting ploop_io_images_size ploop_io_images_size is a global counter supposed to be total sum of io->size for all io structs. However, actual size of image can be used by userspace. E.g. when userspace grows lower delta for merge operartion. This means that by the time ploop_dio_close() is called, actual size may differ slightly from the size we initially accounted. The patch fixes the problem by accurate accounting of images sizes: we can subtruct from ploop_io_images_size only so many bytes as we actually added earlier. Another fix is for growing lower delta in userspace: we try to catch up changes made by userspace when kernel merge starts and ploop_dio_upgrade is being called. https://jira.sw.ru/browse/PSBM-19906 Signed-off-by: Maxim V. Patlasov <mpatla...@parallels.com> --- drivers/block/ploop/io_direct.c | 12 +++++------- drivers/block/ploop/io_direct_map.c | 20 +++++++++++++++----- drivers/block/ploop/io_direct_map.h | 6 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c index 8d716ca..cbb7edc 100644 --- a/drivers/block/ploop/io_direct.c +++ b/drivers/block/ploop/io_direct.c @@ -852,7 +852,7 @@ static void dio_destroy(struct ploop_io * io) if (io->files.em_tree) { io->files.em_tree = NULL; mutex_lock(&io->files.inode->i_mutex); - ploop_dio_close(io->files.mapping, delta->flags & PLOOP_FMT_RDONLY); + ploop_dio_close(io, delta->flags & PLOOP_FMT_RDONLY); (void)dio_invalidate_cache(io->files.mapping, io->files.bdev); mutex_unlock(&io->files.inode->i_mutex); } @@ -910,7 +910,7 @@ static int dio_open(struct ploop_io * io) dio_fsync(file); mutex_lock(&io->files.inode->i_mutex); - em_tree = ploop_dio_open(io->files.file, (delta->flags & PLOOP_FMT_RDONLY)); + em_tree = ploop_dio_open(io, (delta->flags & PLOOP_FMT_RDONLY)); err = PTR_ERR(em_tree); if (IS_ERR(em_tree)) goto out; @@ -920,7 +920,7 @@ static int dio_open(struct ploop_io * io) err = dio_invalidate_cache(io->files.mapping, io->files.bdev); if (err) { io->files.em_tree = NULL; - ploop_dio_close(io->files.mapping, 0); + ploop_dio_close(io, 0); goto out; } @@ -930,7 +930,7 @@ static int dio_open(struct ploop_io * io) delta->plo->index); if (io->fsync_thread == NULL) { io->files.em_tree = NULL; - ploop_dio_close(io->files.mapping, 0); + ploop_dio_close(io, 0); goto out; } wake_up_process(io->fsync_thread); @@ -938,8 +938,6 @@ static int dio_open(struct ploop_io * io) out: mutex_unlock(&io->files.inode->i_mutex); - if (!err) - io->size = i_size_read(io->files.inode); return err; } @@ -1644,7 +1642,7 @@ static int dio_prepare_merge(struct ploop_io * io, struct ploop_snapdata *sd) return err; } - err = ploop_dio_upgrade(io->files.mapping); + err = ploop_dio_upgrade(io); if (err) { mutex_unlock(&io->files.inode->i_mutex); fput(file); diff --git a/drivers/block/ploop/io_direct_map.c b/drivers/block/ploop/io_direct_map.c index 62984bf..2ddf93a 100644 --- a/drivers/block/ploop/io_direct_map.c +++ b/drivers/block/ploop/io_direct_map.c @@ -52,10 +52,11 @@ extern atomic_long_t ploop_io_images_size; */ struct extent_map_tree * -ploop_dio_open(struct file * file, int rdonly) +ploop_dio_open(struct ploop_io * io, int rdonly) { int err; struct ploop_mapping *m, *pm; + struct file * file = io->files.file; struct address_space * mapping = file->f_mapping; pm = kzalloc(sizeof(struct ploop_mapping), GFP_KERNEL); @@ -100,7 +101,8 @@ out_unlock: pm->readers = rdonly ? 1 : -1; list_add(&pm->list, &ploop_mappings); mapping->host->i_flags |= S_SWAPFILE; - atomic_long_add(i_size_read(mapping->host), &ploop_io_images_size); + io->size = i_size_read(mapping->host); + atomic_long_add(io->size, &ploop_io_images_size); pm->saved_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, @@ -125,8 +127,9 @@ out_unlock: } int -ploop_dio_close(struct address_space * mapping, int rdonly) +ploop_dio_close(struct ploop_io * io, int rdonly) { + struct address_space * mapping = io->files.mapping; struct ploop_mapping *m, *pm = NULL; spin_lock(&ploop_mappings_lock); @@ -140,8 +143,9 @@ ploop_dio_close(struct address_space * mapping, int rdonly) } if (m->readers == 0) { - atomic_long_sub(i_size_read(mapping->host), + atomic_long_sub(io->size, &ploop_io_images_size); + io->size = 0; mapping->host->i_flags &= ~S_SWAPFILE; list_del(&m->list); pm = m; @@ -175,8 +179,9 @@ void ploop_dio_downgrade(struct address_space * mapping) spin_unlock(&ploop_mappings_lock); } -int ploop_dio_upgrade(struct address_space * mapping) +int ploop_dio_upgrade(struct ploop_io * io) { + struct address_space * mapping = io->files.mapping; struct ploop_mapping * m; int err = -ESRCH; @@ -185,6 +190,11 @@ int ploop_dio_upgrade(struct address_space * mapping) if (m->mapping == mapping) { err = -EBUSY; if (m->readers == 1) { + loff_t new_size = i_size_read(io->files.inode); + atomic_long_add(new_size - io->size, + &ploop_io_images_size); + io->size = new_size; + m->readers = -1; err = 0; } diff --git a/drivers/block/ploop/io_direct_map.h b/drivers/block/ploop/io_direct_map.h index cb5804c..79e00e3 100644 --- a/drivers/block/ploop/io_direct_map.h +++ b/drivers/block/ploop/io_direct_map.h @@ -50,10 +50,10 @@ struct extent_map *map_extent_get_block(struct extent_map_tree *tree, gfp_t gfp_mask, get_block_t get_block); void trim_extent_mappings(struct extent_map_tree *tree, sector_t start); -int ploop_dio_close(struct address_space * mapping, int rdonly); -struct extent_map_tree * ploop_dio_open(struct file * file, int rdonly); +int ploop_dio_close(struct ploop_io * io, int rdonly); +struct extent_map_tree * ploop_dio_open(struct ploop_io * io, int rdonly); void ploop_dio_downgrade(struct address_space * mapping); -int ploop_dio_upgrade(struct address_space * mapping); +int ploop_dio_upgrade(struct ploop_io * io); int __init extent_map_init(void); void extent_map_exit(void); _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel