Skip to content

Commit 728fbc0

Browse files
goldwynraxboe
authored andcommitted
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>
1 parent 03a07c9 commit 728fbc0

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

fs/ext4/file.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ static ssize_t ext4_dax_read_iter(struct kiocb *iocb, struct iov_iter *to)
3737
struct inode *inode = file_inode(iocb->ki_filp);
3838
ssize_t ret;
3939

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+
}
4145
/*
4246
* Recheck under inode lock - at this point we are sure it cannot
4347
* change anymore
@@ -179,7 +183,11 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
179183
struct inode *inode = file_inode(iocb->ki_filp);
180184
ssize_t ret;
181185

182-
inode_lock(inode);
186+
if (!inode_trylock(inode)) {
187+
if (iocb->ki_flags & IOCB_NOWAIT)
188+
return -EAGAIN;
189+
inode_lock(inode);
190+
}
183191
ret = ext4_write_checks(iocb, from);
184192
if (ret <= 0)
185193
goto out;
@@ -216,7 +224,12 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
216224
return ext4_dax_write_iter(iocb, from);
217225
#endif
218226

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+
220233
ret = ext4_write_checks(iocb, from);
221234
if (ret <= 0)
222235
goto out;
@@ -235,9 +248,15 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
235248

236249
iocb->private = &overwrite;
237250
/* Check whether we do a DIO overwrite or not */
238-
if (o_direct && ext4_should_dioread_nolock(inode) && !unaligned_aio &&
239-
ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from)))
240-
overwrite = 1;
251+
if (o_direct && !unaligned_aio) {
252+
if (ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) {
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+
}
241260

242261
ret = __generic_file_write_iter(iocb, from);
243262
inode_unlock(inode);
@@ -435,6 +454,10 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
435454
if (ret < 0)
436455
return ret;
437456
}
457+
458+
/* Set the flags to support nowait AIO */
459+
filp->f_mode |= FMODE_AIO_NOWAIT;
460+
438461
return dquot_file_open(inode, filp);
439462
}
440463

0 commit comments

Comments
 (0)