aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-28 15:57:36 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-28 15:57:36 -0400
commitccd467d60e81b48cdbecae93532b66bcdedca91d (patch)
tree7c8c74ca8c6c058fc2e3c90c0082e796b7c1e92e /fs/btrfs/file.c
parentf2654de42a759127cb1f1e8a626ec94178732e20 (diff)
Btrfs: crash recovery fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index fef7ba1e707f..2456cc3e1cfd 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -127,7 +127,7 @@ static int insert_inline_extent(struct btrfs_root *root, struct inode *inode,
127 ptr, kaddr + bh_offset(bh), 127 ptr, kaddr + bh_offset(bh),
128 size); 128 size);
129 kunmap_atomic(kaddr, KM_USER0); 129 kunmap_atomic(kaddr, KM_USER0);
130 mark_buffer_dirty(path->nodes[0]); 130 btrfs_mark_buffer_dirty(path->nodes[0]);
131fail: 131fail:
132 btrfs_free_path(path); 132 btrfs_free_path(path);
133 ret = btrfs_end_transaction(trans, root); 133 ret = btrfs_end_transaction(trans, root);
@@ -211,11 +211,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
211 int found_type; 211 int found_type;
212 int found_extent; 212 int found_extent;
213 int found_inline; 213 int found_inline;
214 int recow;
214 215
215 path = btrfs_alloc_path(); 216 path = btrfs_alloc_path();
216 if (!path) 217 if (!path)
217 return -ENOMEM; 218 return -ENOMEM;
218 while(1) { 219 while(1) {
220 recow = 0;
219 btrfs_release_path(root, path); 221 btrfs_release_path(root, path);
220 ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, 222 ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino,
221 search_start, -1); 223 search_start, -1);
@@ -244,6 +246,10 @@ next_slot:
244 if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY) { 246 if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY) {
245 goto out; 247 goto out;
246 } 248 }
249 if (recow) {
250 search_start = key.offset;
251 continue;
252 }
247 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { 253 if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) {
248 extent = btrfs_item_ptr(leaf, slot, 254 extent = btrfs_item_ptr(leaf, slot,
249 struct btrfs_file_extent_item); 255 struct btrfs_file_extent_item);
@@ -274,6 +280,7 @@ next_slot:
274 nextret = btrfs_next_leaf(root, path); 280 nextret = btrfs_next_leaf(root, path);
275 if (nextret) 281 if (nextret)
276 goto out; 282 goto out;
283 recow = 1;
277 } else { 284 } else {
278 path->slots[0]++; 285 path->slots[0]++;
279 } 286 }
@@ -321,7 +328,7 @@ next_slot:
321 } 328 }
322 btrfs_set_file_extent_num_blocks(extent, 329 btrfs_set_file_extent_num_blocks(extent,
323 new_num); 330 new_num);
324 mark_buffer_dirty(path->nodes[0]); 331 btrfs_mark_buffer_dirty(path->nodes[0]);
325 } else { 332 } else {
326 WARN_ON(1); 333 WARN_ON(1);
327 } 334 }
@@ -452,6 +459,8 @@ static int prepare_pages(struct btrfs_root *root,
452 err = -ENOMEM; 459 err = -ENOMEM;
453 goto failed_release; 460 goto failed_release;
454 } 461 }
462 cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
463 wait_on_page_writeback(pages[i]);
455 } 464 }
456 465
457 mutex_lock(&root->fs_info->fs_mutex); 466 mutex_lock(&root->fs_info->fs_mutex);
@@ -522,8 +531,6 @@ static int prepare_pages(struct btrfs_root *root,
522 mutex_unlock(&root->fs_info->fs_mutex); 531 mutex_unlock(&root->fs_info->fs_mutex);
523 532
524 for (i = 0; i < num_pages; i++) { 533 for (i = 0; i < num_pages; i++) {
525 cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
526 wait_on_page_writeback(pages[i]);
527 offset = pos & (PAGE_CACHE_SIZE -1); 534 offset = pos & (PAGE_CACHE_SIZE -1);
528 this_write = min((size_t)PAGE_CACHE_SIZE - offset, write_bytes); 535 this_write = min((size_t)PAGE_CACHE_SIZE - offset, write_bytes);
529 if (!page_has_buffers(pages[i])) { 536 if (!page_has_buffers(pages[i])) {