diff options
author | Joseph Qi <joseph.qi@huawei.com> | 2015-02-16 19:00:09 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-16 20:56:05 -0500 |
commit | 3a83b342c87e6d21290de8dc76ec20a67821261d (patch) | |
tree | 3eca9a53ced95e893768ff44c77926a510612ca1 /fs/ocfs2/file.c | |
parent | d943d59dd32d33cd8a44a2f9caf373ede11200da (diff) |
ocfs2: complete the rest request through buffer io
Complte the rest request thourgh buffer io after direct write performed.
Signed-off-by: Joseph Qi <joseph.qi@huawei.com>
Cc: Weiwei Wang <wangww631@huawei.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Xuejiufei <xuejiufei@huawei.com>
Cc: alex chen <alex.chen@huawei.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 | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 1055a2ece738..784f2c72c992 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2253,6 +2253,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
2253 | u32 old_clusters; | 2253 | u32 old_clusters; |
2254 | struct file *file = iocb->ki_filp; | 2254 | struct file *file = iocb->ki_filp; |
2255 | struct inode *inode = file_inode(file); | 2255 | struct inode *inode = file_inode(file); |
2256 | struct address_space *mapping = file->f_mapping; | ||
2256 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 2257 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
2257 | int full_coherency = !(osb->s_mount_opt & | 2258 | int full_coherency = !(osb->s_mount_opt & |
2258 | OCFS2_MOUNT_COHERENCY_BUFFERED); | 2259 | OCFS2_MOUNT_COHERENCY_BUFFERED); |
@@ -2367,11 +2368,51 @@ relock: | |||
2367 | 2368 | ||
2368 | iov_iter_truncate(from, count); | 2369 | iov_iter_truncate(from, count); |
2369 | if (direct_io) { | 2370 | if (direct_io) { |
2371 | loff_t endbyte; | ||
2372 | ssize_t written_buffered; | ||
2370 | written = generic_file_direct_write(iocb, from, *ppos); | 2373 | written = generic_file_direct_write(iocb, from, *ppos); |
2371 | if (written < 0) { | 2374 | if (written < 0 || written == count) { |
2372 | ret = written; | 2375 | ret = written; |
2373 | goto out_dio; | 2376 | goto out_dio; |
2374 | } | 2377 | } |
2378 | |||
2379 | /* | ||
2380 | * for completing the rest of the request. | ||
2381 | */ | ||
2382 | *ppos += written; | ||
2383 | count -= written; | ||
2384 | written_buffered = generic_perform_write(file, from, *ppos); | ||
2385 | /* | ||
2386 | * If generic_file_buffered_write() returned a synchronous error | ||
2387 | * then we want to return the number of bytes which were | ||
2388 | * direct-written, or the error code if that was zero. Note | ||
2389 | * that this differs from normal direct-io semantics, which | ||
2390 | * will return -EFOO even if some bytes were written. | ||
2391 | */ | ||
2392 | if (written_buffered < 0) { | ||
2393 | ret = written_buffered; | ||
2394 | goto out_dio; | ||
2395 | } | ||
2396 | |||
2397 | iocb->ki_pos = *ppos + written_buffered; | ||
2398 | /* We need to ensure that the page cache pages are written to | ||
2399 | * disk and invalidated to preserve the expected O_DIRECT | ||
2400 | * semantics. | ||
2401 | */ | ||
2402 | endbyte = *ppos + written_buffered - 1; | ||
2403 | ret = filemap_write_and_wait_range(file->f_mapping, *ppos, | ||
2404 | endbyte); | ||
2405 | if (ret == 0) { | ||
2406 | written += written_buffered; | ||
2407 | invalidate_mapping_pages(mapping, | ||
2408 | *ppos >> PAGE_CACHE_SHIFT, | ||
2409 | endbyte >> PAGE_CACHE_SHIFT); | ||
2410 | } else { | ||
2411 | /* | ||
2412 | * We don't know how much we wrote, so just return | ||
2413 | * the number of bytes which were direct-written | ||
2414 | */ | ||
2415 | } | ||
2375 | } else { | 2416 | } else { |
2376 | current->backing_dev_info = inode_to_bdi(inode); | 2417 | current->backing_dev_info = inode_to_bdi(inode); |
2377 | written = generic_perform_write(file, from, *ppos); | 2418 | written = generic_perform_write(file, from, *ppos); |