aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-10-30 14:19:41 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-30 14:19:41 -0400
commit9036c10208e1fc496cef7692ba66a78699b360dc (patch)
treea5b272158acc0e01e71731f5ccbc895a8eee1151 /fs/btrfs/file.c
parent19b9bdb054895ba07086f0264641c9f80e0eb2c4 (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.c41
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 }
194failed:
195 err = btrfs_end_transaction(trans, root); 160 err = btrfs_end_transaction(trans, root);
196out_unlock: 161out_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 *));
701again: 672again:
702 for (i = 0; i < num_pages; i++) { 673 for (i = 0; i < num_pages; i++) {