Re: [PATCH v2] loop: avoid EAGAIN, if offset or block_size are changed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/26/19 2:32 PM, Jaegeuk Kim wrote:
+static void
+loop_mq_freeze_queue(struct loop_device *lo)
+{
+	for (;;) {
+		sync_blockdev(lo->lo_device);
+
+		/* I/O need to be drained during transfer transition */
+		blk_mq_freeze_queue(lo->lo_queue);
+
+		if (is_dirty_bdev(lo->lo_device))
+			blk_mq_unfreeze_queue(lo->lo_queue);
+		else
+			break;
+	}
+	kill_bdev(lo->lo_device);
+}

Maybe I overlooked something, but how does the above code prevent that pages get dirtied after is_dirty_bdev() returns false? blk_mq_freeze_queue() freezes lo->lo_queue but not the filesystem that uses that request queue. Did you perhaps want to call a function that freezes filesystem activity from inside the loop (not sure if such a function already exists)?

[ ... ]
  	/* I/O need to be drained during transfer transition */
-	blk_mq_freeze_queue(lo->lo_queue);
+	if (drop_cache)
+		loop_mq_freeze_queue(lo);
+	else
+		blk_mq_freeze_queue(lo->lo_queue);

How about always calling loop_mq_freeze_queue(), independent of the value of 'drop_cache'? I think that will make the code both easier to read and easier to test.

+	/* I/O need to be drained during transfer transition */
+	if (drop_cache)
+		loop_mq_freeze_queue(lo);
+	else
+		blk_mq_freeze_queue(lo->lo_queue);

Same comment here.

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9c073dbdc1b0..81fe3beef92b 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -74,6 +74,18 @@ static void bdev_write_inode(struct block_device *bdev)
  	spin_unlock(&inode->i_lock);
  }
+bool is_dirty_bdev(struct block_device *bdev)
+{
+	struct inode *inode = bdev->bd_inode;
+	bool dirty;
+
+	spin_lock(&inode->i_lock);
+	dirty = inode->i_state & I_DIRTY ? true: false;
+	spin_unlock(&inode->i_lock);
+	return dirty;
+}

Since the Linux kernel 'bool' datatype conforms to C99, I think that the " ? true : false" part can be left out. From include/linux/types.h:

typedef _Bool			bool;

From http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf: "When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1."

Thanks,

Bart.



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux