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.c50
1 files changed, 18 insertions, 32 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 90d4ee52cd4..a1cb7821bec 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -177,6 +177,17 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
177 177
178 WARN_ON(bio->bi_vcnt <= 0); 178 WARN_ON(bio->bi_vcnt <= 0);
179 179
180 /*
181 * the free space stuff is only read when it hasn't been
182 * updated in the current transaction. So, we can safely
183 * read from the commit root and sidestep a nasty deadlock
184 * between reading the free space cache and updating the csum tree.
185 */
186 if (btrfs_is_free_space_inode(root, inode)) {
187 path->search_commit_root = 1;
188 path->skip_locking = 1;
189 }
190
180 disk_bytenr = (u64)bio->bi_sector << 9; 191 disk_bytenr = (u64)bio->bi_sector << 9;
181 if (dio) 192 if (dio)
182 offset = logical_offset; 193 offset = logical_offset;
@@ -282,7 +293,8 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
282 u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy); 293 u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy);
283 294
284 path = btrfs_alloc_path(); 295 path = btrfs_alloc_path();
285 BUG_ON(!path); 296 if (!path)
297 return -ENOMEM;
286 298
287 if (search_commit) { 299 if (search_commit) {
288 path->skip_locking = 1; 300 path->skip_locking = 1;
@@ -664,15 +676,13 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
664 struct btrfs_sector_sum *sector_sum; 676 struct btrfs_sector_sum *sector_sum;
665 u32 nritems; 677 u32 nritems;
666 u32 ins_size; 678 u32 ins_size;
667 char *eb_map;
668 char *eb_token;
669 unsigned long map_len;
670 unsigned long map_start;
671 u16 csum_size = 679 u16 csum_size =
672 btrfs_super_csum_size(&root->fs_info->super_copy); 680 btrfs_super_csum_size(&root->fs_info->super_copy);
673 681
674 path = btrfs_alloc_path(); 682 path = btrfs_alloc_path();
675 BUG_ON(!path); 683 if (!path)
684 return -ENOMEM;
685
676 sector_sum = sums->sums; 686 sector_sum = sums->sums;
677again: 687again:
678 next_offset = (u64)-1; 688 next_offset = (u64)-1;
@@ -814,30 +824,9 @@ found:
814 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); 824 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
815 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + 825 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end +
816 btrfs_item_size_nr(leaf, path->slots[0])); 826 btrfs_item_size_nr(leaf, path->slots[0]));
817 eb_token = NULL;
818next_sector: 827next_sector:
819 828
820 if (!eb_token || 829 write_extent_buffer(leaf, &sector_sum->sum, (unsigned long)item, csum_size);
821 (unsigned long)item + csum_size >= map_start + map_len) {
822 int err;
823
824 if (eb_token)
825 unmap_extent_buffer(leaf, eb_token, KM_USER1);
826 eb_token = NULL;
827 err = map_private_extent_buffer(leaf, (unsigned long)item,
828 csum_size,
829 &eb_token, &eb_map,
830 &map_start, &map_len, KM_USER1);
831 if (err)
832 eb_token = NULL;
833 }
834 if (eb_token) {
835 memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)),
836 &sector_sum->sum, csum_size);
837 } else {
838 write_extent_buffer(leaf, &sector_sum->sum,
839 (unsigned long)item, csum_size);
840 }
841 830
842 total_bytes += root->sectorsize; 831 total_bytes += root->sectorsize;
843 sector_sum++; 832 sector_sum++;
@@ -850,10 +839,7 @@ next_sector:
850 goto next_sector; 839 goto next_sector;
851 } 840 }
852 } 841 }
853 if (eb_token) { 842
854 unmap_extent_buffer(leaf, eb_token, KM_USER1);
855 eb_token = NULL;
856 }
857 btrfs_mark_buffer_dirty(path->nodes[0]); 843 btrfs_mark_buffer_dirty(path->nodes[0]);
858 if (total_bytes < sums->len) { 844 if (total_bytes < sums->len) {
859 btrfs_release_path(path); 845 btrfs_release_path(path);