diff options
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r-- | fs/btrfs/file-item.c | 50 |
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; |
677 | again: | 687 | again: |
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; | ||
818 | next_sector: | 827 | next_sector: |
819 | 828 | ||
820 | if (!eb_token || | 829 | write_extent_buffer(leaf, §or_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 | §or_sum->sum, csum_size); | ||
837 | } else { | ||
838 | write_extent_buffer(leaf, §or_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); |