btrfs: make btrfs_buffered_write nowait compatible
authorStefan Roesch <shr@fb.com>
Mon, 12 Sep 2022 19:27:50 +0000 (12:27 -0700)
committerDavid Sterba <dsterba@suse.com>
Thu, 29 Sep 2022 15:08:28 +0000 (17:08 +0200)
We need to avoid unconditionally calling balance_dirty_pages_ratelimited
as it could wait for some reason. Use balance_dirty_pages_ratelimited_flags
with the BDP_ASYNC in case the buffered write is nowait, returning
EAGAIN eventually.

It also moves the function after the again label. This can cause the
function to be called a bit later, but this should have no impact in the
real world.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Stefan Roesch <shr@fb.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/file.c

index 805dd86..30604e7 100644 (file)
@@ -1653,6 +1653,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
        loff_t old_isize = i_size_read(inode);
        unsigned int ilock_flags = 0;
        const bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
+       unsigned int bdp_flags = (nowait ? BDP_ASYNC : 0);
 
        if (nowait)
                ilock_flags |= BTRFS_ILOCK_TRY;
@@ -1755,6 +1756,10 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
 
                release_bytes = reserve_bytes;
 again:
+               ret = balance_dirty_pages_ratelimited_flags(inode->i_mapping, bdp_flags);
+               if (ret)
+                       break;
+
                /*
                 * This is going to setup the pages array with the number of
                 * pages we want, so we don't really need to worry about the
@@ -1858,8 +1863,6 @@ again:
 
                cond_resched();
 
-               balance_dirty_pages_ratelimited(inode->i_mapping);
-
                pos += copied;
                num_written += copied;
        }