aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-22 23:06:42 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commited98b56a6393c5e150fd5095b9eb7fd7d3cfb041 (patch)
tree1e69d882a08d089d083132b2b10fcf385d857620
parentc286ac48ed7aaf53586f575af6053ae2a0f8554a (diff)
Btrfs: Take the csum mutex while reading checksums
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/file-item.c8
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/ordered-data.c2
-rw-r--r--fs/btrfs/ordered-data.h2
-rw-r--r--fs/btrfs/transaction.c3
5 files changed, 12 insertions, 5 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 45127e4797c8..afe42d00b5a6 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -152,7 +152,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
152 if (!sums) 152 if (!sums)
153 return -ENOMEM; 153 return -ENOMEM;
154 154
155 sector_sum = &sums->sums; 155 sector_sum = sums->sums;
156 sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset; 156 sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset;
157 sums->len = bio->bi_size; 157 sums->len = bio->bi_size;
158 INIT_LIST_HEAD(&sums->list); 158 INIT_LIST_HEAD(&sums->list);
@@ -174,7 +174,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
174 sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), 174 sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left),
175 GFP_NOFS); 175 GFP_NOFS);
176 BUG_ON(!sums); 176 BUG_ON(!sums);
177 sector_sum = &sums->sums; 177 sector_sum = sums->sums;
178 sums->len = bytes_left; 178 sums->len = bytes_left;
179 sums->file_offset = offset; 179 sums->file_offset = offset;
180 ordered = btrfs_lookup_ordered_extent(inode, 180 ordered = btrfs_lookup_ordered_extent(inode,
@@ -193,12 +193,14 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
193 (char *)&sector_sum->sum); 193 (char *)&sector_sum->sum);
194 sector_sum->offset = page_offset(bvec->bv_page) + 194 sector_sum->offset = page_offset(bvec->bv_page) +
195 bvec->bv_offset; 195 bvec->bv_offset;
196
196 sector_sum++; 197 sector_sum++;
197 bio_index++; 198 bio_index++;
198 total_bytes += bvec->bv_len; 199 total_bytes += bvec->bv_len;
199 this_sum_bytes += bvec->bv_len; 200 this_sum_bytes += bvec->bv_len;
200 bvec++; 201 bvec++;
201 } 202 }
203 this_sum_bytes = 0;
202 btrfs_add_ordered_sum(inode, ordered, sums); 204 btrfs_add_ordered_sum(inode, ordered, sums);
203 btrfs_put_ordered_extent(ordered); 205 btrfs_put_ordered_extent(ordered);
204 return 0; 206 return 0;
@@ -231,7 +233,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
231 233
232 path = btrfs_alloc_path(); 234 path = btrfs_alloc_path();
233 BUG_ON(!path); 235 BUG_ON(!path);
234 sector_sum = &sums->sums; 236 sector_sum = sums->sums;
235again: 237again:
236 next_offset = (u64)-1; 238 next_offset = (u64)-1;
237 found_next = 0; 239 found_next = 0;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3da12a4d913d..28e667052ec3 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -612,6 +612,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
612 return 0; 612 return 0;
613 613
614 path = btrfs_alloc_path(); 614 path = btrfs_alloc_path();
615 mutex_lock(&BTRFS_I(inode)->csum_mutex);
615 item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0); 616 item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
616 if (IS_ERR(item)) { 617 if (IS_ERR(item)) {
617 /* 618 /*
@@ -640,6 +641,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
640found: 641found:
641 set_state_private(io_tree, start, csum); 642 set_state_private(io_tree, start, csum);
642out: 643out:
644 mutex_unlock(&BTRFS_I(inode)->csum_mutex);
643 if (path) 645 if (path)
644 btrfs_free_path(path); 646 btrfs_free_path(path);
645 return ret; 647 return ret;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 830dbaea6853..b695f5b29c45 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -545,7 +545,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u32 *sum)
545 ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list); 545 ordered_sum = list_entry(cur, struct btrfs_ordered_sum, list);
546 if (offset >= ordered_sum->file_offset) { 546 if (offset >= ordered_sum->file_offset) {
547 num_sectors = ordered_sum->len / sectorsize; 547 num_sectors = ordered_sum->len / sectorsize;
548 sector_sums = &ordered_sum->sums; 548 sector_sums = ordered_sum->sums;
549 for (i = 0; i < num_sectors; i++) { 549 for (i = 0; i < num_sectors; i++) {
550 if (sector_sums[i].offset == offset) { 550 if (sector_sums[i].offset == offset) {
551 *sum = sector_sums[i].sum; 551 *sum = sector_sums[i].sum;
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 8e8e3c0404f3..36e63f1f79b3 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -46,7 +46,7 @@ struct btrfs_ordered_sum {
46 unsigned long len; 46 unsigned long len;
47 struct list_head list; 47 struct list_head list;
48 /* last field is a variable length array of btrfs_sector_sums */ 48 /* last field is a variable length array of btrfs_sector_sums */
49 struct btrfs_sector_sum sums; 49 struct btrfs_sector_sum sums[];
50}; 50};
51 51
52/* 52/*
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 38c75a0256cb..0f756e0175c0 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -382,6 +382,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans,
382 memcpy(dirty->root, root, sizeof(*root)); 382 memcpy(dirty->root, root, sizeof(*root));
383 dirty->root->node = root->commit_root; 383 dirty->root->node = root->commit_root;
384 dirty->latest_root = root; 384 dirty->latest_root = root;
385 spin_lock_init(&dirty->root->node_lock);
386 mutex_init(&dirty->root->objectid_mutex);
387
385 root->commit_root = NULL; 388 root->commit_root = NULL;
386 389
387 root->root_key.offset = root->fs_info->generation; 390 root->root_key.offset = root->fs_info->generation;