X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;ds=sidebyside;f=fs%2Fbtrfs%2Ffile-item.c;h=9b99886562d0b2c8ea9e883f3f2623b0ec6d8674;hb=3daeb42c13567e1505f233f6a699cc0e23c8ab5a;hp=b11abfad81a5bb8f8634c2d347d6441aae6cdfb0;hpb=d397712bcc6a759a560fd247e6053ecae091f958;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index b11abfa..9b99886 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -27,6 +27,12 @@ #define MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) * 2) / \ size) - 1)) + +#define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \ + sizeof(struct btrfs_ordered_sum)) / \ + sizeof(struct btrfs_sector_sum) * \ + (r)->sectorsize - (r)->sectorsize) + int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid, u64 pos, @@ -46,6 +52,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, file_key.offset = pos; btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); + path->leave_spinning = 1; ret = btrfs_insert_empty_item(trans, root, path, &file_key, sizeof(*item)); if (ret < 0) @@ -259,8 +266,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, key.offset = start; key.type = BTRFS_EXTENT_CSUM_KEY; - ret = btrfs_search_slot(NULL, root->fs_info->csum_root, - &key, path, 0, 0); + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) goto fail; if (ret > 0 && path->slots[0] > 0) { @@ -279,7 +285,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, while (start <= end) { leaf = path->nodes[0]; if (path->slots[0] >= btrfs_header_nritems(leaf)) { - ret = btrfs_next_leaf(root->fs_info->csum_root, path); + ret = btrfs_next_leaf(root, path); if (ret < 0) goto fail; if (ret > 0) @@ -306,33 +312,38 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, continue; } - size = min(csum_end, end + 1) - start; - sums = kzalloc(btrfs_ordered_sum_size(root, size), GFP_NOFS); - BUG_ON(!sums); + csum_end = min(csum_end, end + 1); + item = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_csum_item); + while (start < csum_end) { + size = min_t(size_t, csum_end - start, + MAX_ORDERED_SUM_BYTES(root)); + sums = kzalloc(btrfs_ordered_sum_size(root, size), + GFP_NOFS); + BUG_ON(!sums); - sector_sum = sums->sums; - sums->bytenr = start; - sums->len = size; + sector_sum = sums->sums; + sums->bytenr = start; + sums->len = size; - offset = (start - key.offset) >> - root->fs_info->sb->s_blocksize_bits; - offset *= csum_size; + offset = (start - key.offset) >> + root->fs_info->sb->s_blocksize_bits; + offset *= csum_size; - item = btrfs_item_ptr(path->nodes[0], path->slots[0], - struct btrfs_csum_item); - while (size > 0) { - read_extent_buffer(path->nodes[0], §or_sum->sum, - ((unsigned long)item) + offset, - csum_size); - sector_sum->bytenr = start; - - size -= root->sectorsize; - start += root->sectorsize; - offset += csum_size; - sector_sum++; + while (size > 0) { + read_extent_buffer(path->nodes[0], + §or_sum->sum, + ((unsigned long)item) + + offset, csum_size); + sector_sum->bytenr = start; + + size -= root->sectorsize; + start += root->sectorsize; + offset += csum_size; + sector_sum++; + } + list_add_tail(&sums->list, list); } - list_add_tail(&sums->list, list); - path->slots[0]++; } ret = 0; @@ -513,6 +524,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, key.offset = end_byte - 1; key.type = BTRFS_EXTENT_CSUM_KEY; + path->leave_spinning = 1; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret > 0) { if (path->slots[0] == 0) @@ -747,8 +759,10 @@ insert: } else { ins_size = csum_size; } + path->leave_spinning = 1; ret = btrfs_insert_empty_item(trans, root, path, &file_key, ins_size); + path->leave_spinning = 0; if (ret < 0) goto fail_unlock; if (ret != 0) { @@ -766,7 +780,6 @@ found: item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + btrfs_item_size_nr(leaf, path->slots[0])); eb_token = NULL; - cond_resched(); next_sector: if (!eb_token || @@ -807,9 +820,9 @@ next_sector: eb_token = NULL; } btrfs_mark_buffer_dirty(path->nodes[0]); - cond_resched(); if (total_bytes < sums->len) { btrfs_release_path(root, path); + cond_resched(); goto again; } out: