diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-02-16 14:46:50 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-04-26 18:02:20 -0400 |
commit | 60b11392f1a09433740bda3048202213daa27736 (patch) | |
tree | a8687fcb0ce62b130b732d663b54a984564d28b2 /fs/ocfs2/inode.c | |
parent | 25baf2da1473d9dcde1a4c7b0ab26e7d67d9bf62 (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/inode.c')
-rw-r--r-- | fs/ocfs2/inode.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 0bd86a137591..78c99b5050df 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -489,12 +489,38 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
489 | int status = 0; | 489 | int status = 0; |
490 | struct ocfs2_truncate_context *tc = NULL; | 490 | struct ocfs2_truncate_context *tc = NULL; |
491 | struct ocfs2_dinode *fe; | 491 | struct ocfs2_dinode *fe; |
492 | handle_t *handle = NULL; | ||
492 | 493 | ||
493 | mlog_entry_void(); | 494 | mlog_entry_void(); |
494 | 495 | ||
495 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 496 | fe = (struct ocfs2_dinode *) fe_bh->b_data; |
496 | 497 | ||
497 | if (fe->i_clusters) { | 498 | if (fe->i_clusters) { |
499 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
500 | if (IS_ERR(handle)) { | ||
501 | status = PTR_ERR(handle); | ||
502 | mlog_errno(status); | ||
503 | goto out; | ||
504 | } | ||
505 | |||
506 | status = ocfs2_journal_access(handle, inode, fe_bh, | ||
507 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
508 | if (status < 0) { | ||
509 | mlog_errno(status); | ||
510 | goto out; | ||
511 | } | ||
512 | |||
513 | i_size_write(inode, 0); | ||
514 | |||
515 | status = ocfs2_mark_inode_dirty(handle, inode, fe_bh); | ||
516 | if (status < 0) { | ||
517 | mlog_errno(status); | ||
518 | goto out; | ||
519 | } | ||
520 | |||
521 | ocfs2_commit_trans(osb, handle); | ||
522 | handle = NULL; | ||
523 | |||
498 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); | 524 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); |
499 | if (status < 0) { | 525 | if (status < 0) { |
500 | mlog_errno(status); | 526 | mlog_errno(status); |
@@ -507,8 +533,10 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
507 | goto out; | 533 | goto out; |
508 | } | 534 | } |
509 | } | 535 | } |
510 | out: | ||
511 | 536 | ||
537 | out: | ||
538 | if (handle) | ||
539 | ocfs2_commit_trans(osb, handle); | ||
512 | mlog_exit(status); | 540 | mlog_exit(status); |
513 | return status; | 541 | return status; |
514 | } | 542 | } |