diff options
Diffstat (limited to 'fs/ocfs2/file.c')
| -rw-r--r-- | fs/ocfs2/file.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 9a03c151b5ce..9e8cc4346b76 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -64,12 +64,6 @@ | |||
| 64 | 64 | ||
| 65 | #include "buffer_head_io.h" | 65 | #include "buffer_head_io.h" |
| 66 | 66 | ||
| 67 | static int ocfs2_sync_inode(struct inode *inode) | ||
| 68 | { | ||
| 69 | filemap_fdatawrite(inode->i_mapping); | ||
| 70 | return sync_mapping_buffers(inode->i_mapping); | ||
| 71 | } | ||
| 72 | |||
| 73 | static int ocfs2_init_file_private(struct inode *inode, struct file *file) | 67 | static int ocfs2_init_file_private(struct inode *inode, struct file *file) |
| 74 | { | 68 | { |
| 75 | struct ocfs2_file_private *fp; | 69 | struct ocfs2_file_private *fp; |
| @@ -180,16 +174,12 @@ static int ocfs2_sync_file(struct file *file, int datasync) | |||
| 180 | { | 174 | { |
| 181 | int err = 0; | 175 | int err = 0; |
| 182 | journal_t *journal; | 176 | journal_t *journal; |
| 183 | struct dentry *dentry = file->f_path.dentry; | ||
| 184 | struct inode *inode = file->f_mapping->host; | 177 | struct inode *inode = file->f_mapping->host; |
| 185 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 178 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 186 | 179 | ||
| 187 | mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", file, dentry, datasync, | 180 | mlog_entry("(0x%p, %d, 0x%p, '%.*s')\n", file, datasync, |
| 188 | dentry->d_name.len, dentry->d_name.name); | 181 | file->f_path.dentry, file->f_path.dentry->d_name.len, |
| 189 | 182 | file->f_path.dentry->d_name.name); | |
| 190 | err = ocfs2_sync_inode(dentry->d_inode); | ||
| 191 | if (err) | ||
| 192 | goto bail; | ||
| 193 | 183 | ||
| 194 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { | 184 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { |
| 195 | /* | 185 | /* |
| @@ -370,7 +360,7 @@ static int ocfs2_cow_file_pos(struct inode *inode, | |||
| 370 | if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) | 360 | if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) |
| 371 | goto out; | 361 | goto out; |
| 372 | 362 | ||
| 373 | return ocfs2_refcount_cow(inode, fe_bh, cpos, 1, cpos+1); | 363 | return ocfs2_refcount_cow(inode, NULL, fe_bh, cpos, 1, cpos+1); |
| 374 | 364 | ||
| 375 | out: | 365 | out: |
| 376 | return status; | 366 | return status; |
| @@ -913,8 +903,8 @@ static int ocfs2_zero_extend_get_range(struct inode *inode, | |||
| 913 | zero_clusters = last_cpos - zero_cpos; | 903 | zero_clusters = last_cpos - zero_cpos; |
| 914 | 904 | ||
| 915 | if (needs_cow) { | 905 | if (needs_cow) { |
| 916 | rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters, | 906 | rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos, |
| 917 | UINT_MAX); | 907 | zero_clusters, UINT_MAX); |
| 918 | if (rc) { | 908 | if (rc) { |
| 919 | mlog_errno(rc); | 909 | mlog_errno(rc); |
| 920 | goto out; | 910 | goto out; |
| @@ -2062,6 +2052,7 @@ out: | |||
| 2062 | } | 2052 | } |
| 2063 | 2053 | ||
| 2064 | static int ocfs2_prepare_inode_for_refcount(struct inode *inode, | 2054 | static int ocfs2_prepare_inode_for_refcount(struct inode *inode, |
| 2055 | struct file *file, | ||
| 2065 | loff_t pos, size_t count, | 2056 | loff_t pos, size_t count, |
| 2066 | int *meta_level) | 2057 | int *meta_level) |
| 2067 | { | 2058 | { |
| @@ -2079,7 +2070,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode, | |||
| 2079 | 2070 | ||
| 2080 | *meta_level = 1; | 2071 | *meta_level = 1; |
| 2081 | 2072 | ||
| 2082 | ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX); | 2073 | ret = ocfs2_refcount_cow(inode, file, di_bh, cpos, clusters, UINT_MAX); |
| 2083 | if (ret) | 2074 | if (ret) |
| 2084 | mlog_errno(ret); | 2075 | mlog_errno(ret); |
| 2085 | out: | 2076 | out: |
| @@ -2087,7 +2078,7 @@ out: | |||
| 2087 | return ret; | 2078 | return ret; |
| 2088 | } | 2079 | } |
| 2089 | 2080 | ||
| 2090 | static int ocfs2_prepare_inode_for_write(struct dentry *dentry, | 2081 | static int ocfs2_prepare_inode_for_write(struct file *file, |
| 2091 | loff_t *ppos, | 2082 | loff_t *ppos, |
| 2092 | size_t count, | 2083 | size_t count, |
| 2093 | int appending, | 2084 | int appending, |
| @@ -2095,6 +2086,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, | |||
| 2095 | int *has_refcount) | 2086 | int *has_refcount) |
| 2096 | { | 2087 | { |
| 2097 | int ret = 0, meta_level = 0; | 2088 | int ret = 0, meta_level = 0; |
| 2089 | struct dentry *dentry = file->f_path.dentry; | ||
| 2098 | struct inode *inode = dentry->d_inode; | 2090 | struct inode *inode = dentry->d_inode; |
| 2099 | loff_t saved_pos, end; | 2091 | loff_t saved_pos, end; |
| 2100 | 2092 | ||
| @@ -2150,6 +2142,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, | |||
| 2150 | meta_level = -1; | 2142 | meta_level = -1; |
| 2151 | 2143 | ||
| 2152 | ret = ocfs2_prepare_inode_for_refcount(inode, | 2144 | ret = ocfs2_prepare_inode_for_refcount(inode, |
| 2145 | file, | ||
| 2153 | saved_pos, | 2146 | saved_pos, |
| 2154 | count, | 2147 | count, |
| 2155 | &meta_level); | 2148 | &meta_level); |
| @@ -2232,6 +2225,8 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
| 2232 | struct file *file = iocb->ki_filp; | 2225 | struct file *file = iocb->ki_filp; |
| 2233 | struct inode *inode = file->f_path.dentry->d_inode; | 2226 | struct inode *inode = file->f_path.dentry->d_inode; |
| 2234 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 2227 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 2228 | int full_coherency = !(osb->s_mount_opt & | ||
| 2229 | OCFS2_MOUNT_COHERENCY_BUFFERED); | ||
| 2235 | 2230 | ||
| 2236 | mlog_entry("(0x%p, %u, '%.*s')\n", file, | 2231 | mlog_entry("(0x%p, %u, '%.*s')\n", file, |
| 2237 | (unsigned int)nr_segs, | 2232 | (unsigned int)nr_segs, |
| @@ -2255,16 +2250,39 @@ relock: | |||
| 2255 | have_alloc_sem = 1; | 2250 | have_alloc_sem = 1; |
| 2256 | } | 2251 | } |
| 2257 | 2252 | ||
| 2258 | /* concurrent O_DIRECT writes are allowed */ | 2253 | /* |
| 2259 | rw_level = !direct_io; | 2254 | * Concurrent O_DIRECT writes are allowed with |
| 2255 | * mount_option "coherency=buffered". | ||
| 2256 | */ | ||
| 2257 | rw_level = (!direct_io || full_coherency); | ||
| 2258 | |||
| 2260 | ret = ocfs2_rw_lock(inode, rw_level); | 2259 | ret = ocfs2_rw_lock(inode, rw_level); |
| 2261 | if (ret < 0) { | 2260 | if (ret < 0) { |
| 2262 | mlog_errno(ret); | 2261 | mlog_errno(ret); |
| 2263 | goto out_sems; | 2262 | goto out_sems; |
| 2264 | } | 2263 | } |
| 2265 | 2264 | ||
| 2265 | /* | ||
| 2266 | * O_DIRECT writes with "coherency=full" need to take EX cluster | ||
| 2267 | * inode_lock to guarantee coherency. | ||
| 2268 | */ | ||
| 2269 | if (direct_io && full_coherency) { | ||
| 2270 | /* | ||
| 2271 | * We need to take and drop the inode lock to force | ||
| 2272 | * other nodes to drop their caches. Buffered I/O | ||
| 2273 | * already does this in write_begin(). | ||
| 2274 | */ | ||
| 2275 | ret = ocfs2_inode_lock(inode, NULL, 1); | ||
| 2276 | if (ret < 0) { | ||
| 2277 | mlog_errno(ret); | ||
| 2278 | goto out_sems; | ||
| 2279 | } | ||
| 2280 | |||
| 2281 | ocfs2_inode_unlock(inode, 1); | ||
| 2282 | } | ||
| 2283 | |||
| 2266 | can_do_direct = direct_io; | 2284 | can_do_direct = direct_io; |
| 2267 | ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos, | 2285 | ret = ocfs2_prepare_inode_for_write(file, ppos, |
| 2268 | iocb->ki_left, appending, | 2286 | iocb->ki_left, appending, |
| 2269 | &can_do_direct, &has_refcount); | 2287 | &can_do_direct, &has_refcount); |
| 2270 | if (ret < 0) { | 2288 | if (ret < 0) { |
| @@ -2312,17 +2330,6 @@ relock: | |||
| 2312 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, | 2330 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, |
| 2313 | ppos, count, ocount); | 2331 | ppos, count, ocount); |
| 2314 | if (written < 0) { | 2332 | if (written < 0) { |
| 2315 | /* | ||
| 2316 | * direct write may have instantiated a few | ||
| 2317 | * blocks outside i_size. Trim these off again. | ||
| 2318 | * Don't need i_size_read because we hold i_mutex. | ||
| 2319 | * | ||
| 2320 | * XXX(truncate): this looks buggy because ocfs2 did not | ||
| 2321 | * actually implement ->truncate. Take a look at | ||
| 2322 | * the new truncate sequence and update this accordingly | ||
| 2323 | */ | ||
| 2324 | if (*ppos + count > inode->i_size) | ||
| 2325 | truncate_setsize(inode, inode->i_size); | ||
| 2326 | ret = written; | 2333 | ret = written; |
| 2327 | goto out_dio; | 2334 | goto out_dio; |
| 2328 | } | 2335 | } |
| @@ -2394,7 +2401,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, | |||
| 2394 | { | 2401 | { |
| 2395 | int ret; | 2402 | int ret; |
| 2396 | 2403 | ||
| 2397 | ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, | 2404 | ret = ocfs2_prepare_inode_for_write(out, &sd->pos, |
| 2398 | sd->total_len, 0, NULL, NULL); | 2405 | sd->total_len, 0, NULL, NULL); |
| 2399 | if (ret < 0) { | 2406 | if (ret < 0) { |
| 2400 | mlog_errno(ret); | 2407 | mlog_errno(ret); |
