Btrfs: Take the csum mutex while reading checksums
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
c286ac48ed
commit
ed98b56a63
|
@ -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,
|
||||||
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,
|
||||||
(char *)§or_sum->sum);
|
(char *)§or_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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
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,
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue