diff options
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r-- | fs/btrfs/file-item.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index a562a250ae77..90d4ee52cd45 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -48,7 +48,8 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, | |||
48 | struct extent_buffer *leaf; | 48 | struct extent_buffer *leaf; |
49 | 49 | ||
50 | path = btrfs_alloc_path(); | 50 | path = btrfs_alloc_path(); |
51 | BUG_ON(!path); | 51 | if (!path) |
52 | return -ENOMEM; | ||
52 | file_key.objectid = objectid; | 53 | file_key.objectid = objectid; |
53 | file_key.offset = pos; | 54 | file_key.offset = pos; |
54 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); | 55 | btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); |
@@ -169,6 +170,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, | |||
169 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; | 170 | struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; |
170 | 171 | ||
171 | path = btrfs_alloc_path(); | 172 | path = btrfs_alloc_path(); |
173 | if (!path) | ||
174 | return -ENOMEM; | ||
172 | if (bio->bi_size > PAGE_CACHE_SIZE * 8) | 175 | if (bio->bi_size > PAGE_CACHE_SIZE * 8) |
173 | path->reada = 2; | 176 | path->reada = 2; |
174 | 177 | ||
@@ -190,7 +193,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, | |||
190 | u32 item_size; | 193 | u32 item_size; |
191 | 194 | ||
192 | if (item) | 195 | if (item) |
193 | btrfs_release_path(root, path); | 196 | btrfs_release_path(path); |
194 | item = btrfs_lookup_csum(NULL, root->fs_info->csum_root, | 197 | item = btrfs_lookup_csum(NULL, root->fs_info->csum_root, |
195 | path, disk_bytenr, 0); | 198 | path, disk_bytenr, 0); |
196 | if (IS_ERR(item)) { | 199 | if (IS_ERR(item)) { |
@@ -205,12 +208,13 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, | |||
205 | EXTENT_NODATASUM, GFP_NOFS); | 208 | EXTENT_NODATASUM, GFP_NOFS); |
206 | } else { | 209 | } else { |
207 | printk(KERN_INFO "btrfs no csum found " | 210 | printk(KERN_INFO "btrfs no csum found " |
208 | "for inode %lu start %llu\n", | 211 | "for inode %llu start %llu\n", |
209 | inode->i_ino, | 212 | (unsigned long long) |
213 | btrfs_ino(inode), | ||
210 | (unsigned long long)offset); | 214 | (unsigned long long)offset); |
211 | } | 215 | } |
212 | item = NULL; | 216 | item = NULL; |
213 | btrfs_release_path(root, path); | 217 | btrfs_release_path(path); |
214 | goto found; | 218 | goto found; |
215 | } | 219 | } |
216 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, | 220 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, |
@@ -263,7 +267,7 @@ int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, | |||
263 | } | 267 | } |
264 | 268 | ||
265 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | 269 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, |
266 | struct list_head *list) | 270 | struct list_head *list, int search_commit) |
267 | { | 271 | { |
268 | struct btrfs_key key; | 272 | struct btrfs_key key; |
269 | struct btrfs_path *path; | 273 | struct btrfs_path *path; |
@@ -280,6 +284,12 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | |||
280 | path = btrfs_alloc_path(); | 284 | path = btrfs_alloc_path(); |
281 | BUG_ON(!path); | 285 | BUG_ON(!path); |
282 | 286 | ||
287 | if (search_commit) { | ||
288 | path->skip_locking = 1; | ||
289 | path->reada = 2; | ||
290 | path->search_commit_root = 1; | ||
291 | } | ||
292 | |||
283 | key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; | 293 | key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; |
284 | key.offset = start; | 294 | key.offset = start; |
285 | key.type = BTRFS_EXTENT_CSUM_KEY; | 295 | key.type = BTRFS_EXTENT_CSUM_KEY; |
@@ -492,7 +502,6 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, | |||
492 | u32 new_size = (bytenr - key->offset) >> blocksize_bits; | 502 | u32 new_size = (bytenr - key->offset) >> blocksize_bits; |
493 | new_size *= csum_size; | 503 | new_size *= csum_size; |
494 | ret = btrfs_truncate_item(trans, root, path, new_size, 1); | 504 | ret = btrfs_truncate_item(trans, root, path, new_size, 1); |
495 | BUG_ON(ret); | ||
496 | } else if (key->offset >= bytenr && csum_end > end_byte && | 505 | } else if (key->offset >= bytenr && csum_end > end_byte && |
497 | end_byte > key->offset) { | 506 | end_byte > key->offset) { |
498 | /* | 507 | /* |
@@ -505,7 +514,6 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, | |||
505 | new_size *= csum_size; | 514 | new_size *= csum_size; |
506 | 515 | ||
507 | ret = btrfs_truncate_item(trans, root, path, new_size, 0); | 516 | ret = btrfs_truncate_item(trans, root, path, new_size, 0); |
508 | BUG_ON(ret); | ||
509 | 517 | ||
510 | key->offset = end_byte; | 518 | key->offset = end_byte; |
511 | ret = btrfs_set_item_key_safe(trans, root, path, key); | 519 | ret = btrfs_set_item_key_safe(trans, root, path, key); |
@@ -536,6 +544,8 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
536 | root = root->fs_info->csum_root; | 544 | root = root->fs_info->csum_root; |
537 | 545 | ||
538 | path = btrfs_alloc_path(); | 546 | path = btrfs_alloc_path(); |
547 | if (!path) | ||
548 | return -ENOMEM; | ||
539 | 549 | ||
540 | while (1) { | 550 | while (1) { |
541 | key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; | 551 | key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; |
@@ -546,9 +556,12 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
546 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 556 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
547 | if (ret > 0) { | 557 | if (ret > 0) { |
548 | if (path->slots[0] == 0) | 558 | if (path->slots[0] == 0) |
549 | goto out; | 559 | break; |
550 | path->slots[0]--; | 560 | path->slots[0]--; |
561 | } else if (ret < 0) { | ||
562 | break; | ||
551 | } | 563 | } |
564 | |||
552 | leaf = path->nodes[0]; | 565 | leaf = path->nodes[0]; |
553 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | 566 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
554 | 567 | ||
@@ -571,7 +584,8 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
571 | /* delete the entire item, it is inside our range */ | 584 | /* delete the entire item, it is inside our range */ |
572 | if (key.offset >= bytenr && csum_end <= end_byte) { | 585 | if (key.offset >= bytenr && csum_end <= end_byte) { |
573 | ret = btrfs_del_item(trans, root, path); | 586 | ret = btrfs_del_item(trans, root, path); |
574 | BUG_ON(ret); | 587 | if (ret) |
588 | goto out; | ||
575 | if (key.offset == bytenr) | 589 | if (key.offset == bytenr) |
576 | break; | 590 | break; |
577 | } else if (key.offset < bytenr && csum_end > end_byte) { | 591 | } else if (key.offset < bytenr && csum_end > end_byte) { |
@@ -623,11 +637,12 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, | |||
623 | if (key.offset < bytenr) | 637 | if (key.offset < bytenr) |
624 | break; | 638 | break; |
625 | } | 639 | } |
626 | btrfs_release_path(root, path); | 640 | btrfs_release_path(path); |
627 | } | 641 | } |
642 | ret = 0; | ||
628 | out: | 643 | out: |
629 | btrfs_free_path(path); | 644 | btrfs_free_path(path); |
630 | return 0; | 645 | return ret; |
631 | } | 646 | } |
632 | 647 | ||
633 | int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, | 648 | int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, |
@@ -714,7 +729,7 @@ again: | |||
714 | * at this point, we know the tree has an item, but it isn't big | 729 | * at this point, we know the tree has an item, but it isn't big |
715 | * enough yet to put our csum in. Grow it | 730 | * enough yet to put our csum in. Grow it |
716 | */ | 731 | */ |
717 | btrfs_release_path(root, path); | 732 | btrfs_release_path(path); |
718 | ret = btrfs_search_slot(trans, root, &file_key, path, | 733 | ret = btrfs_search_slot(trans, root, &file_key, path, |
719 | csum_size, 1); | 734 | csum_size, 1); |
720 | if (ret < 0) | 735 | if (ret < 0) |
@@ -753,12 +768,11 @@ again: | |||
753 | goto insert; | 768 | goto insert; |
754 | 769 | ||
755 | ret = btrfs_extend_item(trans, root, path, diff); | 770 | ret = btrfs_extend_item(trans, root, path, diff); |
756 | BUG_ON(ret); | ||
757 | goto csum; | 771 | goto csum; |
758 | } | 772 | } |
759 | 773 | ||
760 | insert: | 774 | insert: |
761 | btrfs_release_path(root, path); | 775 | btrfs_release_path(path); |
762 | csum_offset = 0; | 776 | csum_offset = 0; |
763 | if (found_next) { | 777 | if (found_next) { |
764 | u64 tmp = total_bytes + root->sectorsize; | 778 | u64 tmp = total_bytes + root->sectorsize; |
@@ -842,7 +856,7 @@ next_sector: | |||
842 | } | 856 | } |
843 | btrfs_mark_buffer_dirty(path->nodes[0]); | 857 | btrfs_mark_buffer_dirty(path->nodes[0]); |
844 | if (total_bytes < sums->len) { | 858 | if (total_bytes < sums->len) { |
845 | btrfs_release_path(root, path); | 859 | btrfs_release_path(path); |
846 | cond_resched(); | 860 | cond_resched(); |
847 | goto again; | 861 | goto again; |
848 | } | 862 | } |