浏览代码

Btrfs: Take the csum mutex while reading checksums

Signed-off-by: Chris Mason <chris.mason@oracle.com>
Chris Mason 17 年之前
父节点
当前提交
ed98b56a63
共有 5 个文件被更改,包括 12 次插入5 次删除
  1. 5 3
      fs/btrfs/file-item.c
  2. 2 0
      fs/btrfs/inode.c
  3. 1 1
      fs/btrfs/ordered-data.c
  4. 1 1
      fs/btrfs/ordered-data.h
  5. 3 0
      fs/btrfs/transaction.c

+ 5 - 3
fs/btrfs/file-item.c

@@ -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 *)&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,
 
 
 	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;

+ 2 - 0
fs/btrfs/inode.c

@@ -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;

+ 1 - 1
fs/btrfs/ordered-data.c

@@ -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;

+ 1 - 1
fs/btrfs/ordered-data.h

@@ -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[];
 };
 };
 
 
 /*
 /*

+ 3 - 0
fs/btrfs/transaction.c

@@ -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;