diff options
author | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2017-06-20 08:05:47 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2017-06-20 09:12:03 -0400 |
commit | 728fbc0e10b7f3ce2ee043b32e3453fd5201c055 (patch) | |
tree | eff612a5bd8832bb002d3adde66a9b6c5a475f6d /fs/ext4/file.c | |
parent | 03a07c92a9ed9938d828ca7f1d11b8bc63a7bb89 (diff) |
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: Goldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/ext4/file.c')
-rw-r--r-- | fs/ext4/file.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 02ce7e7bbdf5..58e2eeaa0bc4 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -37,7 +37,11 @@ static ssize_t ext4_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) | |||
37 | struct inode *inode = file_inode(iocb->ki_filp); | 37 | struct inode *inode = file_inode(iocb->ki_filp); |
38 | ssize_t ret; | 38 | ssize_t ret; |
39 | 39 | ||
40 | inode_lock_shared(inode); | 40 | if (!inode_trylock_shared(inode)) { |
41 | if (iocb->ki_flags & IOCB_NOWAIT) | ||
42 | return -EAGAIN; | ||
43 | inode_lock_shared(inode); | ||
44 | } | ||
41 | /* | 45 | /* |
42 | * Recheck under inode lock - at this point we are sure it cannot | 46 | * Recheck under inode lock - at this point we are sure it cannot |
43 | * change anymore | 47 | * change anymore |
@@ -179,7 +183,11 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
179 | struct inode *inode = file_inode(iocb->ki_filp); | 183 | struct inode *inode = file_inode(iocb->ki_filp); |
180 | ssize_t ret; | 184 | ssize_t ret; |
181 | 185 | ||
182 | inode_lock(inode); | 186 | if (!inode_trylock(inode)) { |
187 | if (iocb->ki_flags & IOCB_NOWAIT) | ||
188 | return -EAGAIN; | ||
189 | inode_lock(inode); | ||
190 | } | ||
183 | ret = ext4_write_checks(iocb, from); | 191 | ret = ext4_write_checks(iocb, from); |
184 | if (ret <= 0) | 192 | if (ret <= 0) |
185 | goto out; | 193 | goto out; |
@@ -216,7 +224,12 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
216 | return ext4_dax_write_iter(iocb, from); | 224 | return ext4_dax_write_iter(iocb, from); |
217 | #endif | 225 | #endif |
218 | 226 | ||
219 | inode_lock(inode); | 227 | if (!inode_trylock(inode)) { |
228 | if (iocb->ki_flags & IOCB_NOWAIT) | ||
229 | return -EAGAIN; | ||
230 | inode_lock(inode); | ||
231 | } | ||
232 | |||
220 | ret = ext4_write_checks(iocb, from); | 233 | ret = ext4_write_checks(iocb, from); |
221 | if (ret <= 0) | 234 | if (ret <= 0) |
222 | goto out; | 235 | goto out; |
@@ -235,9 +248,15 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
235 | 248 | ||
236 | iocb->private = &overwrite; | 249 | iocb->private = &overwrite; |
237 | /* Check whether we do a DIO overwrite or not */ | 250 | /* Check whether we do a DIO overwrite or not */ |
238 | if (o_direct && ext4_should_dioread_nolock(inode) && !unaligned_aio && | 251 | if (o_direct && !unaligned_aio) { |
239 | ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) | 252 | if (ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) { |
240 | overwrite = 1; | 253 | if (ext4_should_dioread_nolock(inode)) |
254 | overwrite = 1; | ||
255 | } else if (iocb->ki_flags & IOCB_NOWAIT) { | ||
256 | ret = -EAGAIN; | ||
257 | goto out; | ||
258 | } | ||
259 | } | ||
241 | 260 | ||
242 | ret = __generic_file_write_iter(iocb, from); | 261 | ret = __generic_file_write_iter(iocb, from); |
243 | inode_unlock(inode); | 262 | inode_unlock(inode); |
@@ -435,6 +454,10 @@ static int ext4_file_open(struct inode * inode, struct file * filp) | |||
435 | if (ret < 0) | 454 | if (ret < 0) |
436 | return ret; | 455 | return ret; |
437 | } | 456 | } |
457 | |||
458 | /* Set the flags to support nowait AIO */ | ||
459 | filp->f_mode |= FMODE_AIO_NOWAIT; | ||
460 | |||
438 | return dquot_file_open(inode, filp); | 461 | return dquot_file_open(inode, filp); |
439 | } | 462 | } |
440 | 463 | ||