[Devel] [PATCH RHEL7 COMMIT] ploop: fix dio_invalidate_cache()
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Nov 13 11:35:22 MSK 2017
The commit is pushed to "branch-rh7-3.10.0-693.1.1.vz7.37.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.1.1.vz7.37.26
------>
commit 887eece598408a684fb08e932ebc7246723939b2
Author: Maxim Patlasov <mpatlasov at virtuozzo.com>
Date: Mon Nov 13 11:35:22 2017 +0300
ploop: fix dio_invalidate_cache()
The patch fixes two critical bugs in dio_invalidate_cache:
1) "bdev" arg points to the block_device of underlying block device
(where image file resides), not ploop block device. Hence, the statement:
> struct ploop_device *plo = bdev->bd_disk->private_data;
is mistake -- that private_data is not our ploop private_data.
2) dio_invalidate_cache() is always called with plo->ctl_mutex held. Hence,
we cannot use ploop_get_dm_crypt_bdev() who tries to acquire the lock again.
https://jira.sw.ru/browse/PSBM-73999
Signed-off-by: Maxim Patlasov <mpatlasov at virtuozzo.com>
---
drivers/block/ploop/io_direct.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index fb594c8..d6b1118 100644
--- a/drivers/block/ploop/io_direct.c
+++ b/drivers/block/ploop/io_direct.c
@@ -860,16 +860,17 @@ static int dio_fsync_thread(void * data)
* must not be quiesced.
*/
-static int dio_invalidate_cache(struct address_space * mapping,
- struct block_device * bdev)
+static int dio_invalidate_cache(struct ploop_io * io)
{
+ struct address_space *mapping = io->files.mapping;
+ struct block_device *bdev = io->files.bdev;
int err;
int attempt2 = 0;
retry:
err = invalidate_inode_pages2(mapping);
if (err) {
- struct ploop_device *plo = bdev->bd_disk->private_data;
+ struct ploop_device *plo = io->plo;
struct block_device *dm_crypt_bdev;
printk("PLOOP: failed to invalidate page cache %d/%d\n", err, attempt2);
@@ -879,7 +880,8 @@ static int dio_invalidate_cache(struct address_space * mapping,
mutex_unlock(&mapping->host->i_mutex);
- dm_crypt_bdev = ploop_get_dm_crypt_bdev(plo);
+ WARN_ONCE(!mutex_is_locked(&plo->ctl_mutex), "ctl_mutex is not held");
+ dm_crypt_bdev = __ploop_get_dm_crypt_bdev(plo);
if (dm_crypt_bdev)
bdev = dm_crypt_bdev;
else
@@ -928,7 +930,7 @@ static void dio_destroy(struct ploop_io * io)
io->files.em_tree = NULL;
mutex_lock(&io->files.inode->i_mutex);
ploop_dio_close(io, delta->flags & PLOOP_FMT_RDONLY);
- (void)dio_invalidate_cache(io->files.mapping, io->files.bdev);
+ (void)dio_invalidate_cache(io);
mutex_unlock(&io->files.inode->i_mutex);
}
@@ -991,7 +993,7 @@ static int dio_open(struct ploop_io * io)
io->files.em_tree = em_tree;
- err = dio_invalidate_cache(io->files.mapping, io->files.bdev);
+ err = dio_invalidate_cache(io);
if (err) {
io->files.em_tree = NULL;
ploop_dio_close(io, 0);
@@ -1637,7 +1639,7 @@ static int dio_prepare_snapshot(struct ploop_io * io, struct ploop_snapdata *sd)
}
mutex_lock(&io->files.inode->i_mutex);
- err = dio_invalidate_cache(io->files.mapping, io->files.bdev);
+ err = dio_invalidate_cache(io);
mutex_unlock(&io->files.inode->i_mutex);
if (err) {
@@ -1709,7 +1711,7 @@ static int dio_prepare_merge(struct ploop_io * io, struct ploop_snapdata *sd)
mutex_lock(&io->files.inode->i_mutex);
- err = dio_invalidate_cache(io->files.mapping, io->files.bdev);
+ err = dio_invalidate_cache(io);
if (err) {
mutex_unlock(&io->files.inode->i_mutex);
fput(file);
More information about the Devel
mailing list