Commit 728fbc0e authored by Goldwyn Rodrigues's avatar Goldwyn Rodrigues Committed by Jens Axboe

ext4: nowait aio support

Return EAGAIN if any of the following checks fail for direct I/O:
  + i_rwsem is lockable
  + Writing beyond end of file (will trigger allocation)
  + Blocks are not allocated at the write location
Signed-off-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 03a07c92
...@@ -37,7 +37,11 @@ static ssize_t ext4_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) ...@@ -37,7 +37,11 @@ static ssize_t ext4_dax_read_iter(struct kiocb *iocb, struct iov_iter *to)
struct inode *inode = file_inode(iocb->ki_filp); struct inode *inode = file_inode(iocb->ki_filp);
ssize_t ret; ssize_t ret;
if (!inode_trylock_shared(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
return -EAGAIN;
inode_lock_shared(inode); inode_lock_shared(inode);
}
/* /*
* Recheck under inode lock - at this point we are sure it cannot * Recheck under inode lock - at this point we are sure it cannot
* change anymore * change anymore
...@@ -179,7 +183,11 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -179,7 +183,11 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
struct inode *inode = file_inode(iocb->ki_filp); struct inode *inode = file_inode(iocb->ki_filp);
ssize_t ret; ssize_t ret;
if (!inode_trylock(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
return -EAGAIN;
inode_lock(inode); inode_lock(inode);
}
ret = ext4_write_checks(iocb, from); ret = ext4_write_checks(iocb, from);
if (ret <= 0) if (ret <= 0)
goto out; goto out;
...@@ -216,7 +224,12 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -216,7 +224,12 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
return ext4_dax_write_iter(iocb, from); return ext4_dax_write_iter(iocb, from);
#endif #endif
if (!inode_trylock(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
return -EAGAIN;
inode_lock(inode); inode_lock(inode);
}
ret = ext4_write_checks(iocb, from); ret = ext4_write_checks(iocb, from);
if (ret <= 0) if (ret <= 0)
goto out; goto out;
...@@ -235,9 +248,15 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -235,9 +248,15 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
iocb->private = &overwrite; iocb->private = &overwrite;
/* Check whether we do a DIO overwrite or not */ /* Check whether we do a DIO overwrite or not */
if (o_direct && ext4_should_dioread_nolock(inode) && !unaligned_aio && if (o_direct && !unaligned_aio) {
ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) if (ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) {
if (ext4_should_dioread_nolock(inode))
overwrite = 1; overwrite = 1;
} else if (iocb->ki_flags & IOCB_NOWAIT) {
ret = -EAGAIN;
goto out;
}
}
ret = __generic_file_write_iter(iocb, from); ret = __generic_file_write_iter(iocb, from);
inode_unlock(inode); inode_unlock(inode);
...@@ -435,6 +454,10 @@ static int ext4_file_open(struct inode * inode, struct file * filp) ...@@ -435,6 +454,10 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
/* Set the flags to support nowait AIO */
filp->f_mode |= FMODE_AIO_NOWAIT;
return dquot_file_open(inode, filp); return dquot_file_open(inode, filp);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment