diff options
| author | Chris Mason <chris.mason@oracle.com> | 2007-06-28 15:57:36 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-06-28 15:57:36 -0400 |
| commit | ccd467d60e81b48cdbecae93532b66bcdedca91d (patch) | |
| tree | 7c8c74ca8c6c058fc2e3c90c0082e796b7c1e92e /fs/btrfs/file.c | |
| parent | f2654de42a759127cb1f1e8a626ec94178732e20 (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.c | 15 |
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]); |
| 131 | fail: | 131 | fail: |
| 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])) { |
