diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-09 14:01:33 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:30:22 -0400 |
commit | 7da839c475894ea872ec909a5d2e83dddccff5be (patch) | |
tree | f3ee71b51322913371a9ca4ff2fb2e8957125679 /fs | |
parent | 2ba48ce513c4e545318d22b138861d5876edf906 (diff) |
ocfs2: use __generic_file_write_iter()
we can do that now - all we need is to clear IOCB_DIRECT from ->ki_flags in
"can't do dio" case.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/file.c | 64 |
1 files changed, 7 insertions, 57 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index cd37f6cd4d51..913fc250d85a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2259,11 +2259,11 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
2259 | u32 old_clusters; | 2259 | u32 old_clusters; |
2260 | struct file *file = iocb->ki_filp; | 2260 | struct file *file = iocb->ki_filp; |
2261 | struct inode *inode = file_inode(file); | 2261 | struct inode *inode = file_inode(file); |
2262 | struct address_space *mapping = file->f_mapping; | ||
2263 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 2262 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
2264 | int full_coherency = !(osb->s_mount_opt & | 2263 | int full_coherency = !(osb->s_mount_opt & |
2265 | OCFS2_MOUNT_COHERENCY_BUFFERED); | 2264 | OCFS2_MOUNT_COHERENCY_BUFFERED); |
2266 | int unaligned_dio = 0; | 2265 | int unaligned_dio = 0; |
2266 | int dropped_dio = 0; | ||
2267 | 2267 | ||
2268 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, | 2268 | trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, |
2269 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 2269 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
@@ -2351,7 +2351,9 @@ relock: | |||
2351 | rw_level = -1; | 2351 | rw_level = -1; |
2352 | 2352 | ||
2353 | direct_io = 0; | 2353 | direct_io = 0; |
2354 | iocb->ki_flags &= ~IOCB_DIRECT; | ||
2354 | iov_iter_reexpand(from, orig_count); | 2355 | iov_iter_reexpand(from, orig_count); |
2356 | dropped_dio = 1; | ||
2355 | goto relock; | 2357 | goto relock; |
2356 | } | 2358 | } |
2357 | 2359 | ||
@@ -2375,67 +2377,15 @@ relock: | |||
2375 | /* communicate with ocfs2_dio_end_io */ | 2377 | /* communicate with ocfs2_dio_end_io */ |
2376 | ocfs2_iocb_set_rw_locked(iocb, rw_level); | 2378 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
2377 | 2379 | ||
2378 | if (direct_io) { | 2380 | written = __generic_file_write_iter(iocb, from); |
2379 | loff_t endbyte; | ||
2380 | ssize_t written_buffered; | ||
2381 | written = generic_file_direct_write(iocb, from, iocb->ki_pos); | ||
2382 | if (written < 0 || !iov_iter_count(from)) { | ||
2383 | ret = written; | ||
2384 | goto out_dio; | ||
2385 | } | ||
2386 | |||
2387 | /* | ||
2388 | * for completing the rest of the request. | ||
2389 | */ | ||
2390 | written_buffered = generic_perform_write(file, from, iocb->ki_pos); | ||
2391 | /* | ||
2392 | * If generic_file_buffered_write() returned a synchronous error | ||
2393 | * then we want to return the number of bytes which were | ||
2394 | * direct-written, or the error code if that was zero. Note | ||
2395 | * that this differs from normal direct-io semantics, which | ||
2396 | * will return -EFOO even if some bytes were written. | ||
2397 | */ | ||
2398 | if (written_buffered < 0) { | ||
2399 | ret = written_buffered; | ||
2400 | goto out_dio; | ||
2401 | } | ||
2402 | |||
2403 | /* We need to ensure that the page cache pages are written to | ||
2404 | * disk and invalidated to preserve the expected O_DIRECT | ||
2405 | * semantics. | ||
2406 | */ | ||
2407 | endbyte = iocb->ki_pos + written_buffered - 1; | ||
2408 | ret = filemap_write_and_wait_range(file->f_mapping, iocb->ki_pos, | ||
2409 | endbyte); | ||
2410 | if (ret == 0) { | ||
2411 | iocb->ki_pos += written_buffered; | ||
2412 | written += written_buffered; | ||
2413 | invalidate_mapping_pages(mapping, | ||
2414 | iocb->ki_pos >> PAGE_CACHE_SHIFT, | ||
2415 | endbyte >> PAGE_CACHE_SHIFT); | ||
2416 | } else { | ||
2417 | /* | ||
2418 | * We don't know how much we wrote, so just return | ||
2419 | * the number of bytes which were direct-written | ||
2420 | */ | ||
2421 | } | ||
2422 | } else { | ||
2423 | current->backing_dev_info = inode_to_bdi(inode); | ||
2424 | written = generic_perform_write(file, from, iocb->ki_pos); | ||
2425 | if (likely(written >= 0)) | ||
2426 | iocb->ki_pos = iocb->ki_pos + written; | ||
2427 | current->backing_dev_info = NULL; | ||
2428 | } | ||
2429 | |||
2430 | out_dio: | ||
2431 | /* buffered aio wouldn't have proper lock coverage today */ | 2381 | /* buffered aio wouldn't have proper lock coverage today */ |
2432 | BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); | 2382 | BUG_ON(written == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT)); |
2433 | 2383 | ||
2434 | if (unlikely(written <= 0)) | 2384 | if (unlikely(written <= 0)) |
2435 | goto no_sync; | 2385 | goto no_sync; |
2436 | 2386 | ||
2437 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || | 2387 | if (((file->f_flags & O_DSYNC) && !direct_io) || |
2438 | ((file->f_flags & O_DIRECT) && !direct_io)) { | 2388 | IS_SYNC(inode) || dropped_dio) { |
2439 | ret = filemap_fdatawrite_range(file->f_mapping, | 2389 | ret = filemap_fdatawrite_range(file->f_mapping, |
2440 | iocb->ki_pos - written, | 2390 | iocb->ki_pos - written, |
2441 | iocb->ki_pos - 1); | 2391 | iocb->ki_pos - 1); |