[RHEL7,COMMIT] ploop: fix dio_invalidate_cache()

Submitted by Konstantin Khorenko on Nov. 13, 2017, 8:35 a.m.

Details

Message ID 201711130835.vAD8ZMeo016544@finist_ce7.work
State New
Series "ploop: fix dio_invalidate_cache()"
Headers show

Commit Message

Konstantin Khorenko Nov. 13, 2017, 8:35 a.m.
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@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@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 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);