aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2015-02-16 19:00:09 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-16 20:56:05 -0500
commit3a83b342c87e6d21290de8dc76ec20a67821261d (patch)
tree3eca9a53ced95e893768ff44c77926a510612ca1 /fs/ocfs2/file.c
parentd943d59dd32d33cd8a44a2f9caf373ede11200da (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.c43
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);