diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-10-30 14:19:41 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-10-30 14:19:41 -0400 |
commit | 9036c10208e1fc496cef7692ba66a78699b360dc (patch) | |
tree | a5b272158acc0e01e71731f5ccbc895a8eee1151 /fs/btrfs/file.c | |
parent | 19b9bdb054895ba07086f0264641c9f80e0eb2c4 (diff) |
Btrfs: update hole handling v2
This patch splits the hole insertion code out of btrfs_setattr
into btrfs_cont_expand and updates btrfs_get_extent to properly
handle the case that file extent items are not continuous.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 41 |
1 files changed, 6 insertions, 35 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 0aa15436590e..b8a7637e14a1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -142,40 +142,6 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
142 | } | 142 | } |
143 | set_extent_uptodate(io_tree, start_pos, end_of_last_block, GFP_NOFS); | 143 | set_extent_uptodate(io_tree, start_pos, end_of_last_block, GFP_NOFS); |
144 | 144 | ||
145 | /* FIXME...EIEIO, ENOSPC and more */ | ||
146 | /* insert any holes we need to create */ | ||
147 | if (isize < start_pos) { | ||
148 | u64 last_pos_in_file; | ||
149 | u64 hole_size; | ||
150 | u64 mask = root->sectorsize - 1; | ||
151 | last_pos_in_file = (isize + mask) & ~mask; | ||
152 | hole_size = (start_pos - last_pos_in_file + mask) & ~mask; | ||
153 | if (hole_size > 0) { | ||
154 | btrfs_wait_ordered_range(inode, last_pos_in_file, | ||
155 | last_pos_in_file + hole_size); | ||
156 | mutex_lock(&BTRFS_I(inode)->extent_mutex); | ||
157 | err = btrfs_drop_extents(trans, root, inode, | ||
158 | last_pos_in_file, | ||
159 | last_pos_in_file + hole_size, | ||
160 | last_pos_in_file, | ||
161 | &hint_byte); | ||
162 | if (err) | ||
163 | goto failed; | ||
164 | |||
165 | err = btrfs_insert_file_extent(trans, root, | ||
166 | inode->i_ino, | ||
167 | last_pos_in_file, | ||
168 | 0, 0, hole_size, 0, | ||
169 | hole_size, 0, 0, 0); | ||
170 | btrfs_drop_extent_cache(inode, last_pos_in_file, | ||
171 | last_pos_in_file + hole_size - 1, 0); | ||
172 | mutex_unlock(&BTRFS_I(inode)->extent_mutex); | ||
173 | btrfs_check_file(root, inode); | ||
174 | } | ||
175 | if (err) | ||
176 | goto failed; | ||
177 | } | ||
178 | |||
179 | /* check for reserved extents on each page, we don't want | 145 | /* check for reserved extents on each page, we don't want |
180 | * to reset the delalloc bit on things that already have | 146 | * to reset the delalloc bit on things that already have |
181 | * extents reserved. | 147 | * extents reserved. |
@@ -191,7 +157,6 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans, | |||
191 | i_size_write(inode, end_pos); | 157 | i_size_write(inode, end_pos); |
192 | btrfs_update_inode(trans, root, inode); | 158 | btrfs_update_inode(trans, root, inode); |
193 | } | 159 | } |
194 | failed: | ||
195 | err = btrfs_end_transaction(trans, root); | 160 | err = btrfs_end_transaction(trans, root); |
196 | out_unlock: | 161 | out_unlock: |
197 | unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); | 162 | unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); |
@@ -697,6 +662,12 @@ static int noinline prepare_pages(struct btrfs_root *root, struct file *file, | |||
697 | start_pos = pos & ~((u64)root->sectorsize - 1); | 662 | start_pos = pos & ~((u64)root->sectorsize - 1); |
698 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; | 663 | last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; |
699 | 664 | ||
665 | if (start_pos > inode->i_size) { | ||
666 | err = btrfs_cont_expand(inode, start_pos); | ||
667 | if (err) | ||
668 | return err; | ||
669 | } | ||
670 | |||
700 | memset(pages, 0, num_pages * sizeof(struct page *)); | 671 | memset(pages, 0, num_pages * sizeof(struct page *)); |
701 | again: | 672 | again: |
702 | for (i = 0; i < num_pages; i++) { | 673 | for (i = 0; i < num_pages; i++) { |