Skip to content

Commit 1729a27

Browse files
maharmstonekdave
authored andcommitted
btrfs: don't sleep in btrfs_encoded_read() if IOCB_NOWAIT is set
Change btrfs_encoded_read() so that it returns -EAGAIN rather than sleeps if IOCB_NOWAIT is set in iocb->ki_flags. The conditions that require sleeping are: inode lock, writeback, extent lock, ordered range. Signed-off-by: Mark Harmstone <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 6c457c2 commit 1729a27

File tree

1 file changed

+44
-11
lines changed

1 file changed

+44
-11
lines changed

fs/btrfs/inode.c

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8983,12 +8983,16 @@ static ssize_t btrfs_encoded_read_inline(
89838983
unsigned long ptr;
89848984
void *tmp;
89858985
ssize_t ret;
8986+
const bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
89868987

89878988
path = btrfs_alloc_path();
89888989
if (!path) {
89898990
ret = -ENOMEM;
89908991
goto out;
89918992
}
8993+
8994+
path->nowait = nowait;
8995+
89928996
ret = btrfs_lookup_file_extent(NULL, root, path, btrfs_ino(inode),
89938997
extent_start, 0);
89948998
if (ret) {
@@ -9198,11 +9202,15 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
91989202
size_t count = iov_iter_count(iter);
91999203
u64 start, lockend;
92009204
struct extent_map *em;
9205+
const bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
92019206
bool unlocked = false;
92029207

92039208
file_accessed(iocb->ki_filp);
92049209

9205-
btrfs_inode_lock(inode, BTRFS_ILOCK_SHARED);
9210+
ret = btrfs_inode_lock(inode,
9211+
BTRFS_ILOCK_SHARED | (nowait ? BTRFS_ILOCK_TRY : 0));
9212+
if (ret)
9213+
return ret;
92069214

92079215
if (iocb->ki_pos >= inode->vfs_inode.i_size) {
92089216
btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
@@ -9215,21 +9223,46 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
92159223
*/
92169224
lockend = start + BTRFS_MAX_UNCOMPRESSED - 1;
92179225

9218-
for (;;) {
9226+
if (nowait) {
92199227
struct btrfs_ordered_extent *ordered;
92209228

9221-
ret = btrfs_wait_ordered_range(inode, start,
9222-
lockend - start + 1);
9223-
if (ret)
9229+
if (filemap_range_needs_writeback(inode->vfs_inode.i_mapping,
9230+
start, lockend)) {
9231+
ret = -EAGAIN;
92249232
goto out_unlock_inode;
9225-
lock_extent(io_tree, start, lockend, cached_state);
9233+
}
9234+
9235+
if (!try_lock_extent(io_tree, start, lockend, cached_state)) {
9236+
ret = -EAGAIN;
9237+
goto out_unlock_inode;
9238+
}
9239+
92269240
ordered = btrfs_lookup_ordered_range(inode, start,
92279241
lockend - start + 1);
9228-
if (!ordered)
9229-
break;
9230-
btrfs_put_ordered_extent(ordered);
9231-
unlock_extent(io_tree, start, lockend, cached_state);
9232-
cond_resched();
9242+
if (ordered) {
9243+
btrfs_put_ordered_extent(ordered);
9244+
unlock_extent(io_tree, start, lockend, cached_state);
9245+
ret = -EAGAIN;
9246+
goto out_unlock_inode;
9247+
}
9248+
} else {
9249+
for (;;) {
9250+
struct btrfs_ordered_extent *ordered;
9251+
9252+
ret = btrfs_wait_ordered_range(inode, start,
9253+
lockend - start + 1);
9254+
if (ret)
9255+
goto out_unlock_inode;
9256+
9257+
lock_extent(io_tree, start, lockend, cached_state);
9258+
ordered = btrfs_lookup_ordered_range(inode, start,
9259+
lockend - start + 1);
9260+
if (!ordered)
9261+
break;
9262+
btrfs_put_ordered_extent(ordered);
9263+
unlock_extent(io_tree, start, lockend, cached_state);
9264+
cond_resched();
9265+
}
92339266
}
92349267

92359268
em = btrfs_get_extent(inode, NULL, start, lockend - start + 1);

0 commit comments

Comments
 (0)