aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-02-16 14:46:50 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-04-26 18:02:20 -0400
commit60b11392f1a09433740bda3048202213daa27736 (patch)
treea8687fcb0ce62b130b732d663b54a984564d28b2 /fs/ocfs2/file.c
parent25baf2da1473d9dcde1a4c7b0ab26e7d67d9bf62 (diff)
ocfs2: zero tail of sparse files on truncate
Since we don't zero on extend anymore, truncate needs to be fixed up to zero the part of a file between i_size and and end of it's cluster. Otherwise a subsequent extend could expose bad data. This introduced a new helper, which can be used in ocfs2_write(). Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r--fs/ocfs2/file.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 667e5a869bf5..5fd49ec169dc 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -262,6 +262,7 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
262{ 262{
263 int status; 263 int status;
264 handle_t *handle; 264 handle_t *handle;
265 struct ocfs2_dinode *di;
265 266
266 mlog_entry_void(); 267 mlog_entry_void();
267 268
@@ -275,12 +276,39 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
275 goto out; 276 goto out;
276 } 277 }
277 278
278 status = ocfs2_set_inode_size(handle, inode, fe_bh, new_i_size); 279 status = ocfs2_journal_access(handle, inode, fe_bh,
280 OCFS2_JOURNAL_ACCESS_WRITE);
281 if (status < 0) {
282 mlog_errno(status);
283 goto out_commit;
284 }
285
286 /*
287 * Do this before setting i_size.
288 */
289 status = ocfs2_zero_tail_for_truncate(inode, handle, new_i_size);
290 if (status) {
291 mlog_errno(status);
292 goto out_commit;
293 }
294
295 i_size_write(inode, new_i_size);
296 inode->i_blocks = ocfs2_align_bytes_to_sectors(new_i_size);
297 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
298
299 di = (struct ocfs2_dinode *) fe_bh->b_data;
300 di->i_size = cpu_to_le64(new_i_size);
301 di->i_ctime = di->i_mtime = cpu_to_le64(inode->i_ctime.tv_sec);
302 di->i_ctime_nsec = di->i_mtime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
303
304 status = ocfs2_journal_dirty(handle, fe_bh);
279 if (status < 0) 305 if (status < 0)
280 mlog_errno(status); 306 mlog_errno(status);
281 307
308out_commit:
282 ocfs2_commit_trans(osb, handle); 309 ocfs2_commit_trans(osb, handle);
283out: 310out:
311
284 mlog_exit(status); 312 mlog_exit(status);
285 return status; 313 return status;
286} 314}
@@ -343,7 +371,6 @@ static int ocfs2_truncate_file(struct inode *inode,
343 mlog_errno(status); 371 mlog_errno(status);
344 goto bail; 372 goto bail;
345 } 373 }
346 ocfs2_data_unlock(inode, 1);
347 374
348 /* alright, we're going to need to do a full blown alloc size 375 /* alright, we're going to need to do a full blown alloc size
349 * change. Orphan the inode so that recovery can complete the 376 * change. Orphan the inode so that recovery can complete the
@@ -352,22 +379,25 @@ static int ocfs2_truncate_file(struct inode *inode,
352 status = ocfs2_orphan_for_truncate(osb, inode, di_bh, new_i_size); 379 status = ocfs2_orphan_for_truncate(osb, inode, di_bh, new_i_size);
353 if (status < 0) { 380 if (status < 0) {
354 mlog_errno(status); 381 mlog_errno(status);
355 goto bail; 382 goto bail_unlock_data;
356 } 383 }
357 384
358 status = ocfs2_prepare_truncate(osb, inode, di_bh, &tc); 385 status = ocfs2_prepare_truncate(osb, inode, di_bh, &tc);
359 if (status < 0) { 386 if (status < 0) {
360 mlog_errno(status); 387 mlog_errno(status);
361 goto bail; 388 goto bail_unlock_data;
362 } 389 }
363 390
364 status = ocfs2_commit_truncate(osb, inode, di_bh, tc); 391 status = ocfs2_commit_truncate(osb, inode, di_bh, tc);
365 if (status < 0) { 392 if (status < 0) {
366 mlog_errno(status); 393 mlog_errno(status);
367 goto bail; 394 goto bail_unlock_data;
368 } 395 }
369 396
370 /* TODO: orphan dir cleanup here. */ 397 /* TODO: orphan dir cleanup here. */
398bail_unlock_data:
399 ocfs2_data_unlock(inode, 1);
400
371bail: 401bail:
372 402
373 mlog_exit(status); 403 mlog_exit(status);