diff options
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r-- | fs/btrfs/file-item.c | 41 |
1 files changed, 11 insertions, 30 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 90d4ee52cd4..08bcfa92a22 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c | |||
@@ -177,6 +177,15 @@ 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 | |||
180 | disk_bytenr = (u64)bio->bi_sector << 9; | 189 | disk_bytenr = (u64)bio->bi_sector << 9; |
181 | if (dio) | 190 | if (dio) |
182 | offset = logical_offset; | 191 | offset = logical_offset; |
@@ -664,10 +673,6 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, | |||
664 | struct btrfs_sector_sum *sector_sum; | 673 | struct btrfs_sector_sum *sector_sum; |
665 | u32 nritems; | 674 | u32 nritems; |
666 | u32 ins_size; | 675 | 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 = | 676 | u16 csum_size = |
672 | btrfs_super_csum_size(&root->fs_info->super_copy); | 677 | btrfs_super_csum_size(&root->fs_info->super_copy); |
673 | 678 | ||
@@ -814,30 +819,9 @@ found: | |||
814 | item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); | 819 | item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); |
815 | item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + | 820 | item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + |
816 | btrfs_item_size_nr(leaf, path->slots[0])); | 821 | btrfs_item_size_nr(leaf, path->slots[0])); |
817 | eb_token = NULL; | ||
818 | next_sector: | 822 | next_sector: |
819 | 823 | ||
820 | if (!eb_token || | 824 | 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 | 825 | ||
842 | total_bytes += root->sectorsize; | 826 | total_bytes += root->sectorsize; |
843 | sector_sum++; | 827 | sector_sum++; |
@@ -850,10 +834,7 @@ next_sector: | |||
850 | goto next_sector; | 834 | goto next_sector; |
851 | } | 835 | } |
852 | } | 836 | } |
853 | if (eb_token) { | 837 | |
854 | unmap_extent_buffer(leaf, eb_token, KM_USER1); | ||
855 | eb_token = NULL; | ||
856 | } | ||
857 | btrfs_mark_buffer_dirty(path->nodes[0]); | 838 | btrfs_mark_buffer_dirty(path->nodes[0]); |
858 | if (total_bytes < sums->len) { | 839 | if (total_bytes < sums->len) { |
859 | btrfs_release_path(path); | 840 | btrfs_release_path(path); |