Btrfs: Take the csum mutex while reading checksums
authorChris Mason <chris.mason@oracle.com>
Wed, 23 Jul 2008 03:06:42 +0000 (23:06 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:04:05 +0000 (11:04 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/file-item.c
fs/btrfs/inode.c
fs/btrfs/ordered-data.c
fs/btrfs/ordered-data.h
fs/btrfs/transaction.c

index 45127e4..afe42d0 100644 (file)
@@ -152,7 +152,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
        if (!sums)
                return -ENOMEM;
 
-       sector_sum = &sums->sums;
+       sector_sum = sums->sums;
        sums->file_offset = page_offset(bvec->bv_page) + bvec->bv_offset;
        sums->len = bio->bi_size;
        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),
                                       GFP_NOFS);
                        BUG_ON(!sums);
-                       sector_sum = &sums->sums;
+                       sector_sum = sums->sums;
                        sums->len = bytes_left;
                        sums->file_offset = offset;
                        ordered = btrfs_lookup_ordered_extent(inode,
@@ -193,12 +193,14 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
                                 (char *)&sector_sum->sum);
                sector_sum->offset = page_offset(bvec->bv_page) +
                        bvec->bv_offset;
+
                sector_sum++;
                bio_index++;
                total_bytes += bvec->bv_len;
                this_sum_bytes += bvec->bv_len;
                bvec++;
        }
+       this_sum_bytes = 0;
        btrfs_add_ordered_sum(inode, ordered, sums);
        btrfs_put_ordered_extent(ordered);
        return 0;
@@ -231,7 +233,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
 
        path = btrfs_alloc_path();
        BUG_ON(!path);
-       sector_sum = &sums->sums;
+       sector_sum = sums->sums;
 again:
        next_offset = (u64)-1;
        found_next = 0;
index 3da12a4..28e6670 100644 (file)
@@ -612,6 +612,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
                return 0;
 
        path = btrfs_alloc_path();
+       mutex_lock(&BTRFS_I(inode)->csum_mutex);
        item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
        if (IS_ERR(item)) {
                /*
@@ -640,6 +641,7 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
 found:
        set_state_private(io_tree, start, csum);
 out:
+       mutex_unlock(&BTRFS_I(inode)->csum_mutex);
        if (path)
                btrfs_free_path(path);
        return ret;
index 830dbae..b695f5b 100644 (file)
@@ -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);
                if (offset >= ordered_sum->file_offset) {
                        num_sectors = ordered_sum->len / sectorsize;
-                       sector_sums = &ordered_sum->sums;
+                       sector_sums = ordered_sum->sums;
                        for (i = 0; i < num_sectors; i++) {
                                if (sector_sums[i].offset == offset) {
                                        *sum = sector_sums[i].sum;
index 8e8e3c0..36e63f1 100644 (file)
@@ -46,7 +46,7 @@ struct btrfs_ordered_sum {
        unsigned long len;
        struct list_head list;
        /* last field is a variable length array of btrfs_sector_sums */
-       struct btrfs_sector_sum sums;
+       struct btrfs_sector_sum sums[];
 };
 
 /*
index 38c75a0..0f756e0 100644 (file)
@@ -382,6 +382,9 @@ static noinline int add_dirty_roots(struct btrfs_trans_handle *trans,
                        memcpy(dirty->root, root, sizeof(*root));
                        dirty->root->node = root->commit_root;
                        dirty->latest_root = root;
+                       spin_lock_init(&dirty->root->node_lock);
+                       mutex_init(&dirty->root->objectid_mutex);
+
                        root->commit_root = NULL;
 
                        root->root_key.offset = root->fs_info->generation;