From: Goldwyn Rodrigues <rgold...@suse.com>

This is similar to 942491c9e6d6 ("xfs: fix AIM7 regression")
Apparently our current rwsem code doesn't like doing the trylock, then
lock for real scheme.  So change our read/write methods to just do the
trylock for the RWF_NOWAIT case.

Fixes: 728fbc0e10b7 ("ext4: nowait aio support")
Signed-off-by: Goldwyn Rodrigues <rgold...@suse.com>
---
 fs/ext4/file.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 70b0438dbc94..d5b2d0cc325d 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -40,11 +40,13 @@ static ssize_t ext4_dax_read_iter(struct kiocb *iocb, 
struct iov_iter *to)
        struct inode *inode = file_inode(iocb->ki_filp);
        ssize_t ret;
 
-       if (!inode_trylock_shared(inode)) {
-               if (iocb->ki_flags & IOCB_NOWAIT)
+       if (iocb->ki_flags & IOCB_NOWAIT) {
+               if (!inode_trylock_shared(inode))
                        return -EAGAIN;
+       } else {
                inode_lock_shared(inode);
        }
+
        /*
         * Recheck under inode lock - at this point we are sure it cannot
         * change anymore
@@ -190,11 +192,13 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter 
*from)
        struct inode *inode = file_inode(iocb->ki_filp);
        ssize_t ret;
 
-       if (!inode_trylock(inode)) {
-               if (iocb->ki_flags & IOCB_NOWAIT)
+       if (iocb->ki_flags & IOCB_NOWAIT) {
+               if (!inode_trylock(inode))
                        return -EAGAIN;
+       } else {
                inode_lock(inode);
        }
+
        ret = ext4_write_checks(iocb, from);
        if (ret <= 0)
                goto out;
@@ -233,9 +237,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter 
*from)
        if (!o_direct && (iocb->ki_flags & IOCB_NOWAIT))
                return -EOPNOTSUPP;
 
-       if (!inode_trylock(inode)) {
-               if (iocb->ki_flags & IOCB_NOWAIT)
+       if (iocb->ki_flags & IOCB_NOWAIT) {
+               if (!inode_trylock(inode))
                        return -EAGAIN;
+       } else {
                inode_lock(inode);
        }
 
-- 
2.16.4

Reply via email to