diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-01-17 15:53:31 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-04-26 18:01:56 -0400 |
commit | 3a0782d09c07aa3ec767ba6089cd15cfbfbfc508 (patch) | |
tree | 4791919970e11f4b2fb3162481a59a56f5196fe4 /fs/ocfs2/file.c | |
parent | 363041a5f74b953ab6b705ac9c88e5eda218a24b (diff) |
ocfs2: teach extend/truncate about sparse files
For ocfs2_truncate_file(), we eliminate the "simple" truncate case which no
longer exists since i_size is not tied to i_clusters. In
ocfs2_extend_file(), we skip the allocation / page zeroing code for file
systems which understand sparse files.
The core truncate code is changed to do a bottom up tree traversal. This
gets abstracted out into it's own function. To make things more readable,
most of the special case handling for in-inode extents from
ocfs2_do_truncate() is also removed.
Though write support for sparse files comes in a later patch, we at least
update ocfs2_prepare_inode_for_write() to skip allocation for sparse files.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8c97fa1c45f6..edc0b617f409 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -344,18 +344,6 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
344 | } | 344 | } |
345 | ocfs2_data_unlock(inode, 1); | 345 | ocfs2_data_unlock(inode, 1); |
346 | 346 | ||
347 | if (le32_to_cpu(fe->i_clusters) == | ||
348 | ocfs2_clusters_for_bytes(osb->sb, new_i_size)) { | ||
349 | mlog(0, "fe->i_clusters = %u, so we do a simple truncate\n", | ||
350 | fe->i_clusters); | ||
351 | /* No allocation change is required, so lets fast path | ||
352 | * this truncate. */ | ||
353 | status = ocfs2_simple_size_update(inode, di_bh, new_i_size); | ||
354 | if (status < 0) | ||
355 | mlog_errno(status); | ||
356 | goto bail; | ||
357 | } | ||
358 | |||
359 | /* alright, we're going to need to do a full blown alloc size | 347 | /* alright, we're going to need to do a full blown alloc size |
360 | * change. Orphan the inode so that recovery can complete the | 348 | * change. Orphan the inode so that recovery can complete the |
361 | * truncate if necessary. This does the task of marking | 349 | * truncate if necessary. This does the task of marking |
@@ -785,7 +773,7 @@ static int ocfs2_extend_file(struct inode *inode, | |||
785 | size_t tail_to_skip) | 773 | size_t tail_to_skip) |
786 | { | 774 | { |
787 | int ret = 0; | 775 | int ret = 0; |
788 | u32 clusters_to_add; | 776 | u32 clusters_to_add = 0; |
789 | 777 | ||
790 | BUG_ON(!tail_to_skip && !di_bh); | 778 | BUG_ON(!tail_to_skip && !di_bh); |
791 | 779 | ||
@@ -797,6 +785,11 @@ static int ocfs2_extend_file(struct inode *inode, | |||
797 | goto out; | 785 | goto out; |
798 | BUG_ON(new_i_size < i_size_read(inode)); | 786 | BUG_ON(new_i_size < i_size_read(inode)); |
799 | 787 | ||
788 | if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) { | ||
789 | BUG_ON(tail_to_skip != 0); | ||
790 | goto out_update_size; | ||
791 | } | ||
792 | |||
800 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) - | 793 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) - |
801 | OCFS2_I(inode)->ip_clusters; | 794 | OCFS2_I(inode)->ip_clusters; |
802 | 795 | ||
@@ -832,6 +825,7 @@ static int ocfs2_extend_file(struct inode *inode, | |||
832 | goto out_unlock; | 825 | goto out_unlock; |
833 | } | 826 | } |
834 | 827 | ||
828 | out_update_size: | ||
835 | if (!tail_to_skip) { | 829 | if (!tail_to_skip) { |
836 | /* We're being called from ocfs2_setattr() which wants | 830 | /* We're being called from ocfs2_setattr() which wants |
837 | * us to update i_size */ | 831 | * us to update i_size */ |
@@ -841,7 +835,8 @@ static int ocfs2_extend_file(struct inode *inode, | |||
841 | } | 835 | } |
842 | 836 | ||
843 | out_unlock: | 837 | out_unlock: |
844 | ocfs2_data_unlock(inode, 1); | 838 | if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) |
839 | ocfs2_data_unlock(inode, 1); | ||
845 | 840 | ||
846 | out: | 841 | out: |
847 | return ret; | 842 | return ret; |
@@ -1097,6 +1092,14 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, | |||
1097 | } else { | 1092 | } else { |
1098 | saved_pos = *ppos; | 1093 | saved_pos = *ppos; |
1099 | } | 1094 | } |
1095 | |||
1096 | /* | ||
1097 | * The rest of this loop is concerned with legacy file | ||
1098 | * systems which don't support sparse files. | ||
1099 | */ | ||
1100 | if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | ||
1101 | break; | ||
1102 | |||
1100 | newsize = count + saved_pos; | 1103 | newsize = count + saved_pos; |
1101 | 1104 | ||
1102 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", | 1105 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", |