Commit ed98b56a authored by Chris Mason's avatar Chris Mason

Btrfs: Take the csum mutex while reading checksums

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent c286ac48
...@@ -152,7 +152,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, ...@@ -152,7 +152,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
if (!sums) if (!sums)
return -ENOMEM; return -ENOMEM;
sector_sum = &sums->sums; sector_sum = sums->sums;
sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset; sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset;
sums->len = bio->bi_size; sums->len = bio->bi_size;
INIT_LIST_HEAD(&sums->list); INIT_LIST_HEAD(&sums->list);
...@@ -174,7 +174,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, ...@@ -174,7 +174,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
GFP_NOFS); GFP_NOFS);
BUG_ON(!sums); BUG_ON(!sums);
sector_sum = &sums->sums; sector_sum = sums->sums;
sums->len = bytes_left; sums->len = bytes_left;
sums->file_offset = offset; sums->file_offset = offset;
ordered = btrfs_lookup_ordered_extent(inode, ordered = btrfs_lookup_ordered_extent(inode,
...@@ -193,12 +193,14 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, ...@@ -193,12 +193,14 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
(char *)&sector_sum->sum); (char *)&sector_sum->sum);
sector_sum->offset = page_offset(bvec->bv_page) + sector_sum->offset = page_offset(bvec->bv_page) +
bvec->bv_offset; bvec->bv_offset;
sector_sum++; sector_sum++;
bio_index++; bio_index++;
total_bytes += bvec->bv_len; total_bytes += bvec->bv_len;
this_sum_bytes += bvec->bv_len; this_sum_bytes += bvec->bv_len;
bvec++; bvec++;
} }
this_sum_bytes = 0;
btrfs_add_ordered_sum(inode, ordered, sums); btrfs_add_ordered_sum(inode, ordered, sums);
btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered);
return 0; return 0;
...@@ -231,7 +233,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, ...@@ -231,7 +233,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
path = btrfs_alloc_path(); path = btrfs_alloc_path();
BUG_ON(!path); BUG_ON(!path);
sector_sum = &sums->sums; sector_sum = sums->sums;
again: again:
next_offset = (u64)-1; next_offset = (u64)-1;
found_next = 0; found_next = 0;
......
...@@ -612,6 +612,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) ...@@ -612,6 +612,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
return 0; return 0;
path = btrfs_alloc_path(); path = btrfs_alloc_path();
mutex_lock(&BTRFS_I(inode)->csum_mutex);
item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0); item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
if (IS_ERR(item)) { if (IS_ERR(item)) {
/* /*
...@@ -640,6 +641,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) ...@@ -640,6 +641,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
found: found:
set_state_private(io_tree, start, csum); set_state_private(io_tree, start, csum);
out: out:
mutex_unlock(&BTRFS_I(inode)->csum_mutex);
if (path) if (path)
btrfs_free_path(path); btrfs_free_path(path);
return ret; return ret;
......
...@@ -545,7 +545,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u32 *sum) ...@@ -545,7 +545,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u32 *sum)
ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list); ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list);
if (offset >= ordered_sum->file_offset) { if (offset >= ordered_sum->file_offset) {
num_sectors = ordered_sum->len / sectorsize; num_sectors = ordered_sum->len / sectorsize;
sector_sums = &ordered_sum->sums; sector_sums = ordered_sum->sums;
for (i = 0; i < num_sectors; i++) { for (i = 0; i < num_sectors; i++) {
if (sector_sums[i].offset == offset) { if (sector_sums[i].offset == offset) {
*sum = sector_sums[i].sum; *sum = sector_sums[i].sum;
......
...@@ -46,7 +46,7 @@ struct btrfs_ordered_sum { ...@@ -46,7 +46,7 @@ struct btrfs_ordered_sum {
unsigned long len; unsigned long len;
struct list_head list; struct list_head list;
/* last field is a variable length array of btrfs_sector_sums */ /* last field is a variable length array of btrfs_sector_sums */
struct btrfs_sector_sum sums; struct btrfs_sector_sum sums[];
}; };
/* /*
......
...@@ -382,6 +382,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans, ...@@ -382,6 +382,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans,
memcpy(dirty->root, root, sizeof(*root)); memcpy(dirty->root, root, sizeof(*root));
dirty->root->node = root->commit_root; dirty->root->node = root->commit_root;
dirty->latest_root = root; dirty->latest_root = root;
spin_lock_init(&dirty->root->node_lock);
mutex_init(&dirty->root->objectid_mutex);
root->commit_root = NULL; root->commit_root = NULL;
root->root_key.offset = root->fs_info->generation; root->root_key.offset = root->fs_info->generation;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment