diff options
Diffstat (limited to 'fs/ocfs2/file.c')
| -rw-r--r-- | fs/ocfs2/file.c | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 3950693dd0f6..46e0d4e857c7 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -295,7 +295,7 @@ out: | |||
| 295 | return ret; | 295 | return ret; |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | static int ocfs2_set_inode_size(handle_t *handle, | 298 | int ocfs2_set_inode_size(handle_t *handle, |
| 299 | struct inode *inode, | 299 | struct inode *inode, |
| 300 | struct buffer_head *fe_bh, | 300 | struct buffer_head *fe_bh, |
| 301 | u64 new_i_size) | 301 | u64 new_i_size) |
| @@ -441,7 +441,7 @@ out: | |||
| 441 | return status; | 441 | return status; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | static int ocfs2_truncate_file(struct inode *inode, | 444 | int ocfs2_truncate_file(struct inode *inode, |
| 445 | struct buffer_head *di_bh, | 445 | struct buffer_head *di_bh, |
| 446 | u64 new_i_size) | 446 | u64 new_i_size) |
| 447 | { | 447 | { |
| @@ -569,7 +569,7 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start, | |||
| 569 | handle_t *handle = NULL; | 569 | handle_t *handle = NULL; |
| 570 | struct ocfs2_alloc_context *data_ac = NULL; | 570 | struct ocfs2_alloc_context *data_ac = NULL; |
| 571 | struct ocfs2_alloc_context *meta_ac = NULL; | 571 | struct ocfs2_alloc_context *meta_ac = NULL; |
| 572 | enum ocfs2_alloc_restarted why; | 572 | enum ocfs2_alloc_restarted why = RESTART_NONE; |
| 573 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 573 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 574 | struct ocfs2_extent_tree et; | 574 | struct ocfs2_extent_tree et; |
| 575 | int did_quota = 0; | 575 | int did_quota = 0; |
| @@ -709,6 +709,13 @@ leave: | |||
| 709 | return status; | 709 | return status; |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | int ocfs2_extend_allocation(struct inode *inode, u32 logical_start, | ||
| 713 | u32 clusters_to_add, int mark_unwritten) | ||
| 714 | { | ||
| 715 | return __ocfs2_extend_allocation(inode, logical_start, | ||
| 716 | clusters_to_add, mark_unwritten); | ||
| 717 | } | ||
| 718 | |||
| 712 | /* | 719 | /* |
| 713 | * While a write will already be ordering the data, a truncate will not. | 720 | * While a write will already be ordering the data, a truncate will not. |
| 714 | * Thus, we need to explicitly order the zeroed pages. | 721 | * Thus, we need to explicitly order the zeroed pages. |
| @@ -2109,6 +2116,9 @@ static int ocfs2_prepare_inode_for_write(struct file *file, | |||
| 2109 | struct dentry *dentry = file->f_path.dentry; | 2116 | struct dentry *dentry = file->f_path.dentry; |
| 2110 | struct inode *inode = dentry->d_inode; | 2117 | struct inode *inode = dentry->d_inode; |
| 2111 | loff_t saved_pos = 0, end; | 2118 | loff_t saved_pos = 0, end; |
| 2119 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
| 2120 | int full_coherency = !(osb->s_mount_opt & | ||
| 2121 | OCFS2_MOUNT_COHERENCY_BUFFERED); | ||
| 2112 | 2122 | ||
| 2113 | /* | 2123 | /* |
| 2114 | * We start with a read level meta lock and only jump to an ex | 2124 | * We start with a read level meta lock and only jump to an ex |
| @@ -2197,7 +2207,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file, | |||
| 2197 | * one node could wind up truncating another | 2207 | * one node could wind up truncating another |
| 2198 | * nodes writes. | 2208 | * nodes writes. |
| 2199 | */ | 2209 | */ |
| 2200 | if (end > i_size_read(inode)) { | 2210 | if (end > i_size_read(inode) && !full_coherency) { |
| 2211 | *direct_io = 0; | ||
| 2212 | break; | ||
| 2213 | } | ||
| 2214 | |||
| 2215 | /* | ||
| 2216 | * Fallback to old way if the feature bit is not set. | ||
| 2217 | */ | ||
| 2218 | if (end > i_size_read(inode) && | ||
| 2219 | !ocfs2_supports_append_dio(osb)) { | ||
| 2201 | *direct_io = 0; | 2220 | *direct_io = 0; |
| 2202 | break; | 2221 | break; |
| 2203 | } | 2222 | } |
| @@ -2210,7 +2229,13 @@ static int ocfs2_prepare_inode_for_write(struct file *file, | |||
| 2210 | */ | 2229 | */ |
| 2211 | ret = ocfs2_check_range_for_holes(inode, saved_pos, count); | 2230 | ret = ocfs2_check_range_for_holes(inode, saved_pos, count); |
| 2212 | if (ret == 1) { | 2231 | if (ret == 1) { |
| 2213 | *direct_io = 0; | 2232 | /* |
| 2233 | * Fallback to old way if the feature bit is not set. | ||
| 2234 | * Otherwise try dio first and then complete the rest | ||
| 2235 | * request through buffer io. | ||
| 2236 | */ | ||
| 2237 | if (!ocfs2_supports_append_dio(osb)) | ||
| 2238 | *direct_io = 0; | ||
| 2214 | ret = 0; | 2239 | ret = 0; |
| 2215 | } else if (ret < 0) | 2240 | } else if (ret < 0) |
| 2216 | mlog_errno(ret); | 2241 | mlog_errno(ret); |
| @@ -2243,6 +2268,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, | |||
| 2243 | u32 old_clusters; | 2268 | u32 old_clusters; |
| 2244 | struct file *file = iocb->ki_filp; | 2269 | struct file *file = iocb->ki_filp; |
| 2245 | struct inode *inode = file_inode(file); | 2270 | struct inode *inode = file_inode(file); |
| 2271 | struct address_space *mapping = file->f_mapping; | ||
| 2246 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 2272 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 2247 | int full_coherency = !(osb->s_mount_opt & | 2273 | int full_coherency = !(osb->s_mount_opt & |
| 2248 | OCFS2_MOUNT_COHERENCY_BUFFERED); | 2274 | OCFS2_MOUNT_COHERENCY_BUFFERED); |
| @@ -2357,13 +2383,53 @@ relock: | |||
| 2357 | 2383 | ||
| 2358 | iov_iter_truncate(from, count); | 2384 | iov_iter_truncate(from, count); |
| 2359 | if (direct_io) { | 2385 | if (direct_io) { |
| 2386 | loff_t endbyte; | ||
| 2387 | ssize_t written_buffered; | ||
| 2360 | written = generic_file_direct_write(iocb, from, *ppos); | 2388 | written = generic_file_direct_write(iocb, from, *ppos); |
| 2361 | if (written < 0) { | 2389 | if (written < 0 || written == count) { |
| 2362 | ret = written; | 2390 | ret = written; |
| 2363 | goto out_dio; | 2391 | goto out_dio; |
| 2364 | } | 2392 | } |
| 2393 | |||
| 2394 | /* | ||
| 2395 | * for completing the rest of the request. | ||
| 2396 | */ | ||
| 2397 | *ppos += written; | ||
| 2398 | count -= written; | ||
| 2399 | written_buffered = generic_perform_write(file, from, *ppos); | ||
| 2400 | /* | ||
| 2401 | * If generic_file_buffered_write() returned a synchronous error | ||
| 2402 | * then we want to return the number of bytes which were | ||
| 2403 | * direct-written, or the error code if that was zero. Note | ||
| 2404 | * that this differs from normal direct-io semantics, which | ||
| 2405 | * will return -EFOO even if some bytes were written. | ||
| 2406 | */ | ||
| 2407 | if (written_buffered < 0) { | ||
| 2408 | ret = written_buffered; | ||
| 2409 | goto out_dio; | ||
| 2410 | } | ||
| 2411 | |||
| 2412 | iocb->ki_pos = *ppos + written_buffered; | ||
| 2413 | /* We need to ensure that the page cache pages are written to | ||
| 2414 | * disk and invalidated to preserve the expected O_DIRECT | ||
| 2415 | * semantics. | ||
| 2416 | */ | ||
| 2417 | endbyte = *ppos + written_buffered - 1; | ||
| 2418 | ret = filemap_write_and_wait_range(file->f_mapping, *ppos, | ||
| 2419 | endbyte); | ||
| 2420 | if (ret == 0) { | ||
| 2421 | written += written_buffered; | ||
| 2422 | invalidate_mapping_pages(mapping, | ||
| 2423 | *ppos >> PAGE_CACHE_SHIFT, | ||
| 2424 | endbyte >> PAGE_CACHE_SHIFT); | ||
| 2425 | } else { | ||
| 2426 | /* | ||
| 2427 | * We don't know how much we wrote, so just return | ||
| 2428 | * the number of bytes which were direct-written | ||
| 2429 | */ | ||
| 2430 | } | ||
| 2365 | } else { | 2431 | } else { |
| 2366 | current->backing_dev_info = file->f_mapping->backing_dev_info; | 2432 | current->backing_dev_info = inode_to_bdi(inode); |
| 2367 | written = generic_perform_write(file, from, *ppos); | 2433 | written = generic_perform_write(file, from, *ppos); |
| 2368 | if (likely(written >= 0)) | 2434 | if (likely(written >= 0)) |
| 2369 | iocb->ki_pos = *ppos + written; | 2435 | iocb->ki_pos = *ppos + written; |
