Re: [PATCH V2] loop: move vfs_fsync() out of loop_update_dio()

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

 



On Tue, Mar 18, 2025 at 09:03:18AM +0800, Ming Lei wrote:
> If vfs_flush() is called with queue frozen, the queue freeze lock may be
> connected with FS internal lock, and lockdep warning can be triggered
> because the queue freeze lock is connected with too many global or
> sub-system locks.
> 
> Fix the warning by moving vfs_fsync() out of loop_update_dio():
> 
> - vfs_fsync() is only needed when switching to dio
> 
> - only loop_change_fd() and loop_configure() may switch from buffered
> IO to direct IO, so call vfs_fsync() directly here. This way is safe
> because either loop is in unbound, or new file isn't attached
> 
> - for the other two cases of set_status and set_block_size, direct IO
> can only become off, so no need to call vfs_fsync()
> 
> Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx>
> Reported-by: Kun Hu <huk23@xxxxxxxxxxxxxx>
> Reported-by: Jiaji Qin <jjtan24@xxxxxxxxxxxxxx>
> Closes: https://lore.kernel.org/linux-block/359BC288-B0B1-4815-9F01-3A349B12E816@xxxxxxxxxxxxxx/T/#u
> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx>
> ---
> V2:
> 	- update comment(Christoph)
> 
>  drivers/block/loop.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 8ca092303794..7ddb3cbc20fe 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -189,18 +189,12 @@ static bool lo_can_use_dio(struct loop_device *lo)
>   */
>  static inline void loop_update_dio(struct loop_device *lo)
>  {
> -	bool dio_in_use = lo->lo_flags & LO_FLAGS_DIRECT_IO;
> -
>  	lockdep_assert_held(&lo->lo_mutex);
>  	WARN_ON_ONCE(lo->lo_state == Lo_bound &&
>  		     lo->lo_queue->mq_freeze_depth == 0);
>  
>  	if ((lo->lo_flags & LO_FLAGS_DIRECT_IO) && !lo_can_use_dio(lo))
>  		lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;
> -
> -	/* flush dirty pages before starting to issue direct I/O */
> -	if ((lo->lo_flags & LO_FLAGS_DIRECT_IO) && !dio_in_use)
> -		vfs_fsync(lo->lo_backing_file, 0);
>  }
>  
>  /**
> @@ -637,6 +631,9 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
>  	if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
>  		goto out_err;
>  
> +	/* may work in dio, so flush page cache before issuing dio */
> +	vfs_fsync(file, 0);

What does "may work" here mean?  I think you mean something like:

	/*
	 * We might switch to direct I/O mode for the loop device, write back
	 * all dirty data the page cache now that so that the individual I/O
	 * operations don't have to do that.
	 */

?





[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