btrfs: make btrfs_buffered_write nowait compatible

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>
This commit is contained in:
Stefan Roesch 2022-09-12 12:27:50 -07:00 committed by David Sterba
parent 304e45acdb
commit 965f47aeb5

View 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;
}