[vz7] ploop: fix dio_invalidate_cache()

Submitted by Maxim Patlasov on Nov. 10, 2017, 10:32 p.m.

Details

Message ID 151035311762.17240.6883983826767167456.stgit@maxim-thinkpad
State New
Series "ploop: fix dio_invalidate_cache()"
Headers show

Commit Message

Maxim Patlasov Nov. 10, 2017, 10:32 p.m.
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@virtuozzo.com>
---
 drivers/block/ploop/io_direct.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/block/ploop/io_direct.c b/drivers/block/ploop/io_direct.c
index fb594c8874e..d6b1118bf2a 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 @@  retry:
 
 		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);