fs: support RWF_NOWAIT for buffered reads

This is based on the old idea and code from Milosz Tanski. With the aio
nowait code it becomes mostly trivial now. Buffered writes continue to
return -EOPNOTSUPP if RWF_NOWAIT is passed.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Christoph Hellwig and committed by
Al Viro
91f9943e 3239d834

+20 -15
-6
fs/aio.c
··· 1593 1593 goto out_put_req; 1594 1594 } 1595 1595 1596 - if ((req->common.ki_flags & IOCB_NOWAIT) && 1597 - !(req->common.ki_flags & IOCB_DIRECT)) { 1598 - ret = -EOPNOTSUPP; 1599 - goto out_put_req; 1600 - } 1601 - 1602 1596 ret = put_user(KIOCB_KEY, &user_iocb->aio_key); 1603 1597 if (unlikely(ret)) { 1604 1598 pr_debug("EFAULT: aio_key\n");
+5 -1
fs/btrfs/file.c
··· 1886 1886 loff_t oldsize; 1887 1887 int clean_page = 0; 1888 1888 1889 + if (!(iocb->ki_flags & IOCB_DIRECT) && 1890 + (iocb->ki_flags & IOCB_NOWAIT)) 1891 + return -EOPNOTSUPP; 1892 + 1889 1893 if (!inode_trylock(inode)) { 1890 1894 if (iocb->ki_flags & IOCB_NOWAIT) 1891 1895 return -EAGAIN; ··· 3109 3105 3110 3106 static int btrfs_file_open(struct inode *inode, struct file *filp) 3111 3107 { 3112 - filp->f_mode |= FMODE_AIO_NOWAIT; 3108 + filp->f_mode |= FMODE_NOWAIT; 3113 3109 return generic_file_open(inode, filp); 3114 3110 } 3115 3111
+3 -3
fs/ext4/file.c
··· 223 223 if (IS_DAX(inode)) 224 224 return ext4_dax_write_iter(iocb, from); 225 225 #endif 226 + if (!o_direct && (iocb->ki_flags & IOCB_NOWAIT)) 227 + return -EOPNOTSUPP; 226 228 227 229 if (!inode_trylock(inode)) { 228 230 if (iocb->ki_flags & IOCB_NOWAIT) ··· 450 448 return ret; 451 449 } 452 450 453 - /* Set the flags to support nowait AIO */ 454 - filp->f_mode |= FMODE_AIO_NOWAIT; 455 - 451 + filp->f_mode |= FMODE_NOWAIT; 456 452 return dquot_file_open(inode, filp); 457 453 } 458 454
+9 -2
fs/xfs/xfs_file.c
··· 259 259 260 260 trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos); 261 261 262 - xfs_ilock(ip, XFS_IOLOCK_SHARED); 262 + if (!xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED)) { 263 + if (iocb->ki_flags & IOCB_NOWAIT) 264 + return -EAGAIN; 265 + xfs_ilock(ip, XFS_IOLOCK_SHARED); 266 + } 263 267 ret = generic_file_read_iter(iocb, to); 264 268 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 265 269 ··· 640 636 int enospc = 0; 641 637 int iolock; 642 638 639 + if (iocb->ki_flags & IOCB_NOWAIT) 640 + return -EOPNOTSUPP; 641 + 643 642 write_retry: 644 643 iolock = XFS_IOLOCK_EXCL; 645 644 xfs_ilock(ip, iolock); ··· 919 912 return -EFBIG; 920 913 if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb))) 921 914 return -EIO; 922 - file->f_mode |= FMODE_AIO_NOWAIT; 915 + file->f_mode |= FMODE_NOWAIT; 923 916 return 0; 924 917 } 925 918
+3 -3
include/linux/fs.h
··· 146 146 /* File was opened by fanotify and shouldn't generate fanotify events */ 147 147 #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) 148 148 149 - /* File is capable of returning -EAGAIN if AIO will block */ 150 - #define FMODE_AIO_NOWAIT ((__force fmode_t)0x8000000) 149 + /* File is capable of returning -EAGAIN if I/O will block */ 150 + #define FMODE_NOWAIT ((__force fmode_t)0x8000000) 151 151 152 152 /* 153 153 * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector ··· 3149 3149 return -EOPNOTSUPP; 3150 3150 3151 3151 if (flags & RWF_NOWAIT) { 3152 - if (!(ki->ki_filp->f_mode & FMODE_AIO_NOWAIT)) 3152 + if (!(ki->ki_filp->f_mode & FMODE_NOWAIT)) 3153 3153 return -EOPNOTSUPP; 3154 3154 ki->ki_flags |= IOCB_NOWAIT; 3155 3155 }