diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-06-24 14:29:46 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-07-20 20:47:48 -0400 |
commit | df2d6f26586f12a24f3ae5df4e236dc5c08d6eb4 (patch) | |
tree | 68c6ec96177f766d3b9ab0a48408271ef2af4d89 /fs/ocfs2/file.c | |
parent | 562c72aa57c36b178eacc3500a0215651eca9429 (diff) |
fs: always maintain i_dio_count
Maintain i_dio_count for all filesystems, not just those using DIO_LOCKING.
This these filesystems to also protect truncate against direct I/O requests
by using common code. Right now the only non-DIO_LOCKING filesystem that
appears to do so is XFS, which uses an opencoded variant of the i_dio_count
scheme.
Behaviour doesn't change for filesystems never calling inode_dio_wait.
For ext4 behaviour changes when using the dioread_nonlock option, which
previously was missing any protection between truncate and direct I/O reads.
For ocfs2 that handcrafted i_dio_count manipulations are replaced with
the common code now enable.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 736283ca4a4c..22d604601957 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2240,7 +2240,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
2240 | relock: | 2240 | relock: |
2241 | /* to match setattr's i_mutex -> rw_lock ordering */ | 2241 | /* to match setattr's i_mutex -> rw_lock ordering */ |
2242 | if (direct_io) { | 2242 | if (direct_io) { |
2243 | atomic_inc(&inode->i_dio_count); | ||
2244 | have_alloc_sem = 1; | 2243 | have_alloc_sem = 1; |
2245 | /* communicate with ocfs2_dio_end_io */ | 2244 | /* communicate with ocfs2_dio_end_io */ |
2246 | ocfs2_iocb_set_sem_locked(iocb); | 2245 | ocfs2_iocb_set_sem_locked(iocb); |
@@ -2292,7 +2291,6 @@ relock: | |||
2292 | */ | 2291 | */ |
2293 | if (direct_io && !can_do_direct) { | 2292 | if (direct_io && !can_do_direct) { |
2294 | ocfs2_rw_unlock(inode, rw_level); | 2293 | ocfs2_rw_unlock(inode, rw_level); |
2295 | inode_dio_done(inode); | ||
2296 | 2294 | ||
2297 | have_alloc_sem = 0; | 2295 | have_alloc_sem = 0; |
2298 | rw_level = -1; | 2296 | rw_level = -1; |
@@ -2379,10 +2377,8 @@ out: | |||
2379 | ocfs2_rw_unlock(inode, rw_level); | 2377 | ocfs2_rw_unlock(inode, rw_level); |
2380 | 2378 | ||
2381 | out_sems: | 2379 | out_sems: |
2382 | if (have_alloc_sem) { | 2380 | if (have_alloc_sem) |
2383 | inode_dio_done(inode); | ||
2384 | ocfs2_iocb_clear_sem_locked(iocb); | 2381 | ocfs2_iocb_clear_sem_locked(iocb); |
2385 | } | ||
2386 | 2382 | ||
2387 | mutex_unlock(&inode->i_mutex); | 2383 | mutex_unlock(&inode->i_mutex); |
2388 | 2384 | ||
@@ -2533,7 +2529,6 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2533 | */ | 2529 | */ |
2534 | if (filp->f_flags & O_DIRECT) { | 2530 | if (filp->f_flags & O_DIRECT) { |
2535 | have_alloc_sem = 1; | 2531 | have_alloc_sem = 1; |
2536 | atomic_inc(&inode->i_dio_count); | ||
2537 | ocfs2_iocb_set_sem_locked(iocb); | 2532 | ocfs2_iocb_set_sem_locked(iocb); |
2538 | 2533 | ||
2539 | ret = ocfs2_rw_lock(inode, 0); | 2534 | ret = ocfs2_rw_lock(inode, 0); |
@@ -2575,10 +2570,9 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2575 | } | 2570 | } |
2576 | 2571 | ||
2577 | bail: | 2572 | bail: |
2578 | if (have_alloc_sem) { | 2573 | if (have_alloc_sem) |
2579 | inode_dio_done(inode); | ||
2580 | ocfs2_iocb_clear_sem_locked(iocb); | 2574 | ocfs2_iocb_clear_sem_locked(iocb); |
2581 | } | 2575 | |
2582 | if (rw_level != -1) | 2576 | if (rw_level != -1) |
2583 | ocfs2_rw_unlock(inode, rw_level); | 2577 | ocfs2_rw_unlock(inode, rw_level); |
2584 | 2578 | ||