@@ -3091,29 +3091,20 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
30913091 ssize_t ret = 0 ;
30923092 struct file * file = iocb -> ki_filp ;
30933093 struct fuse_file * ff = file -> private_data ;
3094- bool async_dio = ff -> fc -> async_dio ;
30953094 loff_t pos = 0 ;
30963095 struct inode * inode ;
30973096 loff_t i_size ;
3098- size_t count = iov_iter_count (iter );
3097+ size_t count = iov_iter_count (iter ), shortened = 0 ;
30993098 loff_t offset = iocb -> ki_pos ;
31003099 struct fuse_io_priv * io ;
31013100
31023101 pos = offset ;
31033102 inode = file -> f_mapping -> host ;
31043103 i_size = i_size_read (inode );
31053104
3106- if ((iov_iter_rw (iter ) == READ ) && (offset > i_size ))
3105+ if ((iov_iter_rw (iter ) == READ ) && (offset >= i_size ))
31073106 return 0 ;
31083107
3109- /* optimization for short read */
3110- if (async_dio && iov_iter_rw (iter ) != WRITE && offset + count > i_size ) {
3111- if (offset >= i_size )
3112- return 0 ;
3113- iov_iter_truncate (iter , fuse_round_up (ff -> fc , i_size - offset ));
3114- count = iov_iter_count (iter );
3115- }
3116-
31173108 io = kmalloc (sizeof (struct fuse_io_priv ), GFP_KERNEL );
31183109 if (!io )
31193110 return - ENOMEM ;
@@ -3129,15 +3120,22 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
31293120 * By default, we want to optimize all I/Os with async request
31303121 * submission to the client filesystem if supported.
31313122 */
3132- io -> async = async_dio ;
3123+ io -> async = ff -> fc -> async_dio ;
31333124 io -> iocb = iocb ;
31343125 io -> blocking = is_sync_kiocb (iocb );
31353126
3127+ /* optimization for short read */
3128+ if (io -> async && !io -> write && offset + count > i_size ) {
3129+ iov_iter_truncate (iter , fuse_round_up (ff -> fc , i_size - offset ));
3130+ shortened = count - iov_iter_count (iter );
3131+ count -= shortened ;
3132+ }
3133+
31363134 /*
31373135 * We cannot asynchronously extend the size of a file.
31383136 * In such case the aio will behave exactly like sync io.
31393137 */
3140- if ((offset + count > i_size ) && iov_iter_rw ( iter ) == WRITE )
3138+ if ((offset + count > i_size ) && io -> write )
31413139 io -> blocking = true;
31423140
31433141 if (io -> async && io -> blocking ) {
@@ -3155,6 +3153,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
31553153 } else {
31563154 ret = __fuse_direct_read (io , iter , & pos );
31573155 }
3156+ iov_iter_reexpand (iter , iov_iter_count (iter ) + shortened );
31583157
31593158 if (io -> async ) {
31603159 bool blocking = io -> blocking ;
0 commit comments