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