Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ocfs2: move generic_write_checks() before the alignment checks

Alignment checks for dio depend upon the range truncation done by
generic_write_checks(). They can be done as soon as we got ocfs2_rw_lock()
and that actually makes ocfs2_prepare_inode_for_write() simpler.

The only thing to watch out for is restoring the original count
in "unlock and redo without dio" case. Position doesn't need to be
restored, since we change it only in O_APPEND case and in that case it
will be reassigned anyway.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 90320251 5dc3161c

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