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); |