@@ -8983,12 +8983,16 @@ static ssize_t btrfs_encoded_read_inline(
8983
8983
unsigned long ptr ;
8984
8984
void * tmp ;
8985
8985
ssize_t ret ;
8986
+ const bool nowait = (iocb -> ki_flags & IOCB_NOWAIT );
8986
8987
8987
8988
path = btrfs_alloc_path ();
8988
8989
if (!path ) {
8989
8990
ret = - ENOMEM ;
8990
8991
goto out ;
8991
8992
}
8993
+
8994
+ path -> nowait = nowait ;
8995
+
8992
8996
ret = btrfs_lookup_file_extent (NULL , root , path , btrfs_ino (inode ),
8993
8997
extent_start , 0 );
8994
8998
if (ret ) {
@@ -9198,11 +9202,15 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
9198
9202
size_t count = iov_iter_count (iter );
9199
9203
u64 start , lockend ;
9200
9204
struct extent_map * em ;
9205
+ const bool nowait = (iocb -> ki_flags & IOCB_NOWAIT );
9201
9206
bool unlocked = false;
9202
9207
9203
9208
file_accessed (iocb -> ki_filp );
9204
9209
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 ;
9206
9214
9207
9215
if (iocb -> ki_pos >= inode -> vfs_inode .i_size ) {
9208
9216
btrfs_inode_unlock (inode , BTRFS_ILOCK_SHARED );
@@ -9215,21 +9223,46 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
9215
9223
*/
9216
9224
lockend = start + BTRFS_MAX_UNCOMPRESSED - 1 ;
9217
9225
9218
- for (;; ) {
9226
+ if ( nowait ) {
9219
9227
struct btrfs_ordered_extent * ordered ;
9220
9228
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 ;
9224
9232
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
+
9226
9240
ordered = btrfs_lookup_ordered_range (inode , start ,
9227
9241
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
+ }
9233
9266
}
9234
9267
9235
9268
em = btrfs_get_extent (inode , NULL , start , lockend - start + 1 );
0 commit comments