aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file-item.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r--fs/btrfs/file-item.c46
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
265int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, 269int 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;
628out: 643out:
629 btrfs_free_path(path); 644 btrfs_free_path(path);
630 return 0; 645 return ret;
631} 646}
632 647
633int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, 648int 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
760insert: 774insert:
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 }