diff options
author | Changwei Ge <ge.changwei@h3c.com> | 2018-11-02 18:48:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-11-03 13:09:37 -0400 |
commit | 9e985787750db8aae87f02b67e908f28ac4d6b83 (patch) | |
tree | b7693d418aa7201f4bc290774c5b8540350356c9 /fs/ocfs2/file.c | |
parent | 21158ca85b73ddd0088076a5209cfd040513a8b5 (diff) |
ocfs2: don't use iocb when EIOCBQUEUED returns
When -EIOCBQUEUED returns, it means that aio_complete() will be called
from dio_complete(), which is an asynchronous progress against
write_iter. Generally, IO is a very slow progress than executing
instruction, but we still can't take the risk to access a freed iocb.
And we do face a BUG crash issue. Using the crash tool, iocb is
obviously freed already.
crash> struct -x kiocb ffff881a350f5900
struct kiocb {
ki_filp = 0xffff881a350f5a80,
ki_pos = 0x0,
ki_complete = 0x0,
private = 0x0,
ki_flags = 0x0
}
And the backtrace shows:
ocfs2_file_write_iter+0xcaa/0xd00 [ocfs2]
aio_run_iocb+0x229/0x2f0
do_io_submit+0x291/0x540
SyS_io_submit+0x10/0x20
system_call_fastpath+0x16/0x75
Link: http://lkml.kernel.org/r/1523361653-14439-1-git-send-email-ge.changwei@h3c.com
Signed-off-by: Changwei Ge <ge.changwei@h3c.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <jiangqi903@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index fe570824b991..d640c5f8a85d 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2343,7 +2343,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
2343 | 2343 | ||
2344 | written = __generic_file_write_iter(iocb, from); | 2344 | written = __generic_file_write_iter(iocb, from); |
2345 | /* buffered aio wouldn't have proper lock coverage today */ | 2345 | /* buffered aio wouldn't have proper lock coverage today */ |
2346 | BUG_ON(written == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); | 2346 | BUG_ON(written == -EIOCBQUEUED && !direct_io); |
2347 | 2347 | ||
2348 | /* | 2348 | /* |
2349 | * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io | 2349 | * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io |
@@ -2463,7 +2463,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, | |||
2463 | trace_generic_file_read_iter_ret(ret); | 2463 | trace_generic_file_read_iter_ret(ret); |
2464 | 2464 | ||
2465 | /* buffered aio wouldn't have proper lock coverage today */ | 2465 | /* buffered aio wouldn't have proper lock coverage today */ |
2466 | BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); | 2466 | BUG_ON(ret == -EIOCBQUEUED && !direct_io); |
2467 | 2467 | ||
2468 | /* see ocfs2_file_write_iter */ | 2468 | /* see ocfs2_file_write_iter */ |
2469 | if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) { | 2469 | if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) { |