@@ -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