aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/file.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 78e245df5e32..fc53ff065364 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2106,7 +2106,7 @@ out:
2106} 2106}
2107 2107
2108static int ocfs2_prepare_inode_for_write(struct file *file, 2108static int ocfs2_prepare_inode_for_write(struct file *file,
2109 loff_t *ppos, 2109 loff_t pos,
2110 size_t count, 2110 size_t count,
2111 int appending, 2111 int appending,
2112 int *direct_io, 2112 int *direct_io,
@@ -2115,7 +2115,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
2115 int ret = 0, meta_level = 0; 2115 int ret = 0, meta_level = 0;
2116 struct dentry *dentry = file->f_path.dentry; 2116 struct dentry *dentry = file->f_path.dentry;
2117 struct inode *inode = dentry->d_inode; 2117 struct inode *inode = dentry->d_inode;
2118 loff_t saved_pos = 0, end; 2118 loff_t end;
2119 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 2119 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2120 int full_coherency = !(osb->s_mount_opt & 2120 int full_coherency = !(osb->s_mount_opt &
2121 OCFS2_MOUNT_COHERENCY_BUFFERED); 2121 OCFS2_MOUNT_COHERENCY_BUFFERED);
@@ -2155,23 +2155,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
2155 } 2155 }
2156 } 2156 }
2157 2157
2158 /* work on a copy of ppos until we're sure that we won't have 2158 end = pos + count;
2159 * to recalculate it due to relocking. */
2160 if (appending)
2161 saved_pos = i_size_read(inode);
2162 else
2163 saved_pos = *ppos;
2164
2165 end = saved_pos + count;
2166 2159
2167 ret = ocfs2_check_range_for_refcount(inode, saved_pos, count); 2160 ret = ocfs2_check_range_for_refcount(inode, pos, count);
2168 if (ret == 1) { 2161 if (ret == 1) {
2169 ocfs2_inode_unlock(inode, meta_level); 2162 ocfs2_inode_unlock(inode, meta_level);
2170 meta_level = -1; 2163 meta_level = -1;
2171 2164
2172 ret = ocfs2_prepare_inode_for_refcount(inode, 2165 ret = ocfs2_prepare_inode_for_refcount(inode,
2173 file, 2166 file,
2174 saved_pos, 2167 pos,
2175 count, 2168 count,
2176 &meta_level); 2169 &meta_level);
2177 if (has_refcount) 2170 if (has_refcount)
@@ -2227,7 +2220,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
2227 * caller will have to retake some cluster 2220 * caller will have to retake some cluster
2228 * locks and initiate the io as buffered. 2221 * locks and initiate the io as buffered.
2229 */ 2222 */
2230 ret = ocfs2_check_range_for_holes(inode, saved_pos, count); 2223 ret = ocfs2_check_range_for_holes(inode, pos, count);
2231 if (ret == 1) { 2224 if (ret == 1) {
2232 /* 2225 /*
2233 * Fallback to old way if the feature bit is not set. 2226 * Fallback to old way if the feature bit is not set.
@@ -2242,12 +2235,9 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
2242 break; 2235 break;
2243 } 2236 }
2244 2237
2245 if (appending)
2246 *ppos = saved_pos;
2247
2248out_unlock: 2238out_unlock:
2249 trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno, 2239 trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno,
2250 saved_pos, appending, count, 2240 pos, appending, count,
2251 direct_io, has_refcount); 2241 direct_io, has_refcount);
2252 2242
2253 if (meta_level >= 0) 2243 if (meta_level >= 0)
@@ -2263,7 +2253,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
2263 int ret, direct_io, appending, rw_level, have_alloc_sem = 0; 2253 int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
2264 int can_do_direct, has_refcount = 0; 2254 int can_do_direct, has_refcount = 0;
2265 ssize_t written = 0; 2255 ssize_t written = 0;
2266 size_t count = iov_iter_count(from); 2256 size_t count = iov_iter_count(from), orig_count;
2267 loff_t old_size; 2257 loff_t old_size;
2268 u32 old_clusters; 2258 u32 old_clusters;
2269 struct file *file = iocb->ki_filp; 2259 struct file *file = iocb->ki_filp;
@@ -2329,8 +2319,16 @@ relock:
2329 ocfs2_inode_unlock(inode, 1); 2319 ocfs2_inode_unlock(inode, 1);
2330 } 2320 }
2331 2321
2322 orig_count = count;
2323 ret = generic_write_checks(file, &iocb->ki_pos, &count);
2324 if (ret < 0) {
2325 mlog_errno(ret);
2326 goto out;
2327 }
2328 iov_iter_truncate(from, count);
2329
2332 can_do_direct = direct_io; 2330 can_do_direct = direct_io;
2333 ret = ocfs2_prepare_inode_for_write(file, &iocb->ki_pos, count, appending, 2331 ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending,
2334 &can_do_direct, &has_refcount); 2332 &can_do_direct, &has_refcount);
2335 if (ret < 0) { 2333 if (ret < 0) {
2336 mlog_errno(ret); 2334 mlog_errno(ret);
@@ -2351,6 +2349,7 @@ relock:
2351 rw_level = -1; 2349 rw_level = -1;
2352 2350
2353 direct_io = 0; 2351 direct_io = 0;
2352 iov_iter_reexpand(from, count = orig_count);
2354 goto relock; 2353 goto relock;
2355 } 2354 }
2356 2355
@@ -2374,11 +2373,6 @@ relock:
2374 /* communicate with ocfs2_dio_end_io */ 2373 /* communicate with ocfs2_dio_end_io */
2375 ocfs2_iocb_set_rw_locked(iocb, rw_level); 2374 ocfs2_iocb_set_rw_locked(iocb, rw_level);
2376 2375
2377 ret = generic_write_checks(file, &iocb->ki_pos, &count);
2378 if (ret)
2379 goto out_dio;
2380
2381 iov_iter_truncate(from, count);
2382 if (direct_io) { 2376 if (direct_io) {
2383 loff_t endbyte; 2377 loff_t endbyte;
2384 ssize_t written_buffered; 2378 ssize_t written_buffered;