aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/compression.c9
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/extent-tree.c50
-rw-r--r--fs/btrfs/extent_io.h1
-rw-r--r--fs/btrfs/file-item.c114
-rw-r--r--fs/btrfs/file.c8
-rw-r--r--fs/btrfs/inode.c74
7 files changed, 226 insertions, 35 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index ad7274137309..2436163d5436 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -124,8 +124,7 @@ static int check_compressed_csum(struct inode *inode,
124 u32 csum; 124 u32 csum;
125 u32 *cb_sum = &cb->sums; 125 u32 *cb_sum = &cb->sums;
126 126
127 if (btrfs_test_opt(root, NODATASUM) || 127 if (btrfs_test_flag(inode, NODATASUM))
128 btrfs_test_flag(inode, NODATASUM))
129 return 0; 128 return 0;
130 129
131 for (i = 0; i < cb->nr_pages; i++) { 130 for (i = 0; i < cb->nr_pages; i++) {
@@ -671,8 +670,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
671 */ 670 */
672 atomic_inc(&cb->pending_bios); 671 atomic_inc(&cb->pending_bios);
673 672
674 if (!btrfs_test_opt(root, NODATASUM) && 673 if (!btrfs_test_flag(inode, NODATASUM)) {
675 !btrfs_test_flag(inode, NODATASUM)) {
676 btrfs_lookup_bio_sums(root, inode, comp_bio, 674 btrfs_lookup_bio_sums(root, inode, comp_bio,
677 sums); 675 sums);
678 } 676 }
@@ -699,8 +697,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
699 ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); 697 ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0);
700 BUG_ON(ret); 698 BUG_ON(ret);
701 699
702 if (!btrfs_test_opt(root, NODATASUM) && 700 if (!btrfs_test_flag(inode, NODATASUM)) {
703 !btrfs_test_flag(inode, NODATASUM)) {
704 btrfs_lookup_bio_sums(root, inode, comp_bio, sums); 701 btrfs_lookup_bio_sums(root, inode, comp_bio, sums);
705 } 702 }
706 703
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 8733081d97a3..b89999de4564 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1702,7 +1702,7 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
1702int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, 1702int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
1703 struct btrfs_root *root, struct extent_buffer *leaf); 1703 struct btrfs_root *root, struct extent_buffer *leaf);
1704int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, 1704int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
1705 struct btrfs_root *root, u64 bytenr); 1705 struct btrfs_root *root, u64 objectid, u64 bytenr);
1706int btrfs_extent_post_op(struct btrfs_trans_handle *trans, 1706int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
1707 struct btrfs_root *root); 1707 struct btrfs_root *root);
1708int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy); 1708int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy);
@@ -1789,6 +1789,7 @@ int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans,
1789 struct extent_buffer *buf, u64 orig_start); 1789 struct extent_buffer *buf, u64 orig_start);
1790int btrfs_add_dead_reloc_root(struct btrfs_root *root); 1790int btrfs_add_dead_reloc_root(struct btrfs_root *root);
1791int btrfs_cleanup_reloc_trees(struct btrfs_root *root); 1791int btrfs_cleanup_reloc_trees(struct btrfs_root *root);
1792int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len);
1792u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); 1793u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
1793/* ctree.c */ 1794/* ctree.c */
1794int btrfs_previous_item(struct btrfs_root *root, 1795int btrfs_previous_item(struct btrfs_root *root,
@@ -1994,6 +1995,8 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
1994int btrfs_csum_truncate(struct btrfs_trans_handle *trans, 1995int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
1995 struct btrfs_root *root, struct btrfs_path *path, 1996 struct btrfs_root *root, struct btrfs_path *path,
1996 u64 isize); 1997 u64 isize);
1998int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start,
1999 u64 end, struct list_head *list);
1997/* inode.c */ 2000/* inode.c */
1998 2001
1999/* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */ 2002/* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 171057a32679..8004695d24d6 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1359,7 +1359,7 @@ out:
1359} 1359}
1360 1360
1361int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, 1361int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
1362 struct btrfs_root *root, u64 bytenr) 1362 struct btrfs_root *root, u64 objectid, u64 bytenr)
1363{ 1363{
1364 struct btrfs_root *extent_root = root->fs_info->extent_root; 1364 struct btrfs_root *extent_root = root->fs_info->extent_root;
1365 struct btrfs_path *path; 1365 struct btrfs_path *path;
@@ -1418,8 +1418,9 @@ int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
1418 ref_item = btrfs_item_ptr(leaf, path->slots[0], 1418 ref_item = btrfs_item_ptr(leaf, path->slots[0],
1419 struct btrfs_extent_ref); 1419 struct btrfs_extent_ref);
1420 ref_root = btrfs_ref_root(leaf, ref_item); 1420 ref_root = btrfs_ref_root(leaf, ref_item);
1421 if (ref_root != root->root_key.objectid && 1421 if ((ref_root != root->root_key.objectid &&
1422 ref_root != BTRFS_TREE_LOG_OBJECTID) { 1422 ref_root != BTRFS_TREE_LOG_OBJECTID) ||
1423 objectid != btrfs_ref_objectid(leaf, ref_item)) {
1423 ret = 1; 1424 ret = 1;
1424 goto out; 1425 goto out;
1425 } 1426 }
@@ -5367,7 +5368,6 @@ static int noinline relocate_one_extent(struct btrfs_root *extent_root,
5367 if (ret) 5368 if (ret)
5368 goto out; 5369 goto out;
5369 } 5370 }
5370 btrfs_record_root_in_trans(found_root);
5371 ret = replace_one_extent(trans, found_root, 5371 ret = replace_one_extent(trans, found_root,
5372 path, extent_key, 5372 path, extent_key,
5373 &first_key, ref_path, 5373 &first_key, ref_path,
@@ -5534,6 +5534,7 @@ static struct inode noinline *create_reloc_inode(struct btrfs_fs_info *fs_info,
5534 } else { 5534 } else {
5535 BUG_ON(1); 5535 BUG_ON(1);
5536 } 5536 }
5537 BTRFS_I(inode)->index_cnt = group->key.objectid;
5537 5538
5538 err = btrfs_orphan_add(trans, inode); 5539 err = btrfs_orphan_add(trans, inode);
5539out: 5540out:
@@ -5546,6 +5547,47 @@ out:
5546 return inode; 5547 return inode;
5547} 5548}
5548 5549
5550int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len)
5551{
5552
5553 struct btrfs_ordered_sum *sums;
5554 struct btrfs_sector_sum *sector_sum;
5555 struct btrfs_ordered_extent *ordered;
5556 struct btrfs_root *root = BTRFS_I(inode)->root;
5557 struct list_head list;
5558 size_t offset;
5559 int ret;
5560 u64 disk_bytenr;
5561
5562 INIT_LIST_HEAD(&list);
5563
5564 ordered = btrfs_lookup_ordered_extent(inode, file_pos);
5565 BUG_ON(ordered->file_offset != file_pos || ordered->len != len);
5566
5567 disk_bytenr = file_pos + BTRFS_I(inode)->index_cnt;
5568 ret = btrfs_lookup_csums_range(root, disk_bytenr,
5569 disk_bytenr + len - 1, &list);
5570
5571 while (!list_empty(&list)) {
5572 sums = list_entry(list.next, struct btrfs_ordered_sum, list);
5573 list_del_init(&sums->list);
5574
5575 sector_sum = sums->sums;
5576 sums->bytenr = ordered->start;
5577
5578 offset = 0;
5579 while (offset < sums->len) {
5580 sector_sum->bytenr += ordered->start - disk_bytenr;
5581 sector_sum++;
5582 offset += root->sectorsize;
5583 }
5584
5585 btrfs_add_ordered_sum(inode, ordered, sums);
5586 }
5587 btrfs_put_ordered_extent(ordered);
5588 return 0;
5589}
5590
5549int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start) 5591int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start)
5550{ 5592{
5551 struct btrfs_trans_handle *trans; 5593 struct btrfs_trans_handle *trans;
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 2d5f67065b69..c5b483a79137 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -16,6 +16,7 @@
16#define EXTENT_ORDERED (1 << 9) 16#define EXTENT_ORDERED (1 << 9)
17#define EXTENT_ORDERED_METADATA (1 << 10) 17#define EXTENT_ORDERED_METADATA (1 << 10)
18#define EXTENT_BOUNDARY (1 << 11) 18#define EXTENT_BOUNDARY (1 << 11)
19#define EXTENT_NODATASUM (1 << 12)
19#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) 20#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
20 21
21/* flags for bio submission */ 22/* flags for bio submission */
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 3ebef871ee6c..df0447632dbd 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -140,6 +140,7 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
140 return ret; 140 return ret;
141} 141}
142 142
143
143int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, 144int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
144 struct bio *bio, u32 *dst) 145 struct bio *bio, u32 *dst)
145{ 146{
@@ -185,9 +186,16 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
185 if (ret == -ENOENT || ret == -EFBIG) 186 if (ret == -ENOENT || ret == -EFBIG)
186 ret = 0; 187 ret = 0;
187 sum = 0; 188 sum = 0;
188 printk("no csum found for inode %lu start " 189 if (BTRFS_I(inode)->root->root_key.objectid ==
189 "%llu\n", inode->i_ino, 190 BTRFS_DATA_RELOC_TREE_OBJECTID) {
190 (unsigned long long)offset); 191 set_extent_bits(io_tree, offset,
192 offset + bvec->bv_len - 1,
193 EXTENT_NODATASUM, GFP_NOFS);
194 } else {
195 printk("no csum found for inode %lu "
196 "start %llu\n", inode->i_ino,
197 (unsigned long long)offset);
198 }
191 item = NULL; 199 item = NULL;
192 btrfs_release_path(root, path); 200 btrfs_release_path(root, path);
193 goto found; 201 goto found;
@@ -228,6 +236,106 @@ found:
228 return 0; 236 return 0;
229} 237}
230 238
239int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
240 struct list_head *list)
241{
242 struct btrfs_key key;
243 struct btrfs_path *path;
244 struct extent_buffer *leaf;
245 struct btrfs_ordered_sum *sums;
246 struct btrfs_sector_sum *sector_sum;
247 struct btrfs_csum_item *item;
248 unsigned long offset;
249 int ret;
250 size_t size;
251 u64 csum_end;
252 u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy);
253
254 path = btrfs_alloc_path();
255 BUG_ON(!path);
256
257 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
258 key.offset = start;
259 key.type = BTRFS_EXTENT_CSUM_KEY;
260
261 ret = btrfs_search_slot(NULL, root->fs_info->csum_root,
262 &key, path, 0, 0);
263 if (ret < 0)
264 goto fail;
265 if (ret > 0 && path->slots[0] > 0) {
266 leaf = path->nodes[0];
267 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1);
268 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
269 key.type == BTRFS_EXTENT_CSUM_KEY) {
270 offset = (start - key.offset) >>
271 root->fs_info->sb->s_blocksize_bits;
272 if (offset * csum_size <
273 btrfs_item_size_nr(leaf, path->slots[0] - 1))
274 path->slots[0]--;
275 }
276 }
277
278 while (start <= end) {
279 leaf = path->nodes[0];
280 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
281 ret = btrfs_next_leaf(root->fs_info->csum_root, path);
282 if (ret < 0)
283 goto fail;
284 if (ret > 0)
285 break;
286 leaf = path->nodes[0];
287 }
288
289 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
290 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
291 key.type != BTRFS_EXTENT_CSUM_KEY)
292 break;
293
294 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
295 if (key.offset > end)
296 break;
297
298 if (key.offset > start)
299 start = key.offset;
300
301 size = btrfs_item_size_nr(leaf, path->slots[0]);
302 csum_end = key.offset + (size / csum_size) * root->sectorsize;
303
304 size = min(csum_end, end + 1) - start;
305 sums = kzalloc(btrfs_ordered_sum_size(root, size), GFP_NOFS);
306 BUG_ON(!sums);
307
308 sector_sum = sums->sums;
309 sums->bytenr = start;
310 sums->len = size;
311
312 offset = (start - key.offset) >>
313 root->fs_info->sb->s_blocksize_bits;
314 offset *= csum_size;
315
316 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
317 struct btrfs_csum_item);
318 while (size > 0) {
319 read_extent_buffer(path->nodes[0], &sector_sum->sum,
320 ((unsigned long)item) + offset,
321 csum_size);
322 sector_sum->bytenr = start;
323
324 size -= root->sectorsize;
325 start += root->sectorsize;
326 offset += csum_size;
327 sector_sum++;
328 }
329 list_add_tail(&sums->list, list);
330
331 path->slots[0]++;
332 }
333 ret = 0;
334fail:
335 btrfs_free_path(path);
336 return ret;
337}
338
231int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, 339int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
232 struct bio *bio, u64 file_start, int contig) 340 struct bio *bio, u64 file_start, int contig)
233{ 341{
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 71bfe3a6a444..507081059d97 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1060,14 +1060,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1060 last_index = (pos + count) >> PAGE_CACHE_SHIFT; 1060 last_index = (pos + count) >> PAGE_CACHE_SHIFT;
1061 1061
1062 /* 1062 /*
1063 * if this is a nodatasum mount, force summing off for the inode
1064 * all the time. That way a later mount with summing on won't
1065 * get confused
1066 */
1067 if (btrfs_test_opt(root, NODATASUM))
1068 btrfs_set_flag(inode, NODATASUM);
1069
1070 /*
1071 * there are lots of better ways to do this, but this code 1063 * there are lots of better ways to do this, but this code
1072 * makes sure the first and last page in the file range are 1064 * makes sure the first and last page in the file range are
1073 * up to date and ready for cow 1065 * up to date and ready for cow
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 0a28b7706314..e64a4fe19a60 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -771,6 +771,13 @@ static noinline int cow_file_range(struct inode *inode,
771 ram_size, cur_alloc_size, 0); 771 ram_size, cur_alloc_size, 0);
772 BUG_ON(ret); 772 BUG_ON(ret);
773 773
774 if (root->root_key.objectid ==
775 BTRFS_DATA_RELOC_TREE_OBJECTID) {
776 ret = btrfs_reloc_clone_csums(inode, start,
777 cur_alloc_size);
778 BUG_ON(ret);
779 }
780
774 if (disk_num_bytes < cur_alloc_size) { 781 if (disk_num_bytes < cur_alloc_size) {
775 printk("num_bytes %Lu cur_alloc %Lu\n", disk_num_bytes, 782 printk("num_bytes %Lu cur_alloc %Lu\n", disk_num_bytes,
776 cur_alloc_size); 783 cur_alloc_size);
@@ -910,6 +917,26 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
910 return 0; 917 return 0;
911} 918}
912 919
920static int noinline csum_exist_in_range(struct btrfs_root *root,
921 u64 bytenr, u64 num_bytes)
922{
923 int ret;
924 struct btrfs_ordered_sum *sums;
925 LIST_HEAD(list);
926
927 ret = btrfs_lookup_csums_range(root, bytenr, bytenr + num_bytes - 1,
928 &list);
929 if (ret == 0 && list_empty(&list))
930 return 0;
931
932 while (!list_empty(&list)) {
933 sums = list_entry(list.next, struct btrfs_ordered_sum, list);
934 list_del(&sums->list);
935 kfree(sums);
936 }
937 return 1;
938}
939
913/* 940/*
914 * when nowcow writeback call back. This checks for snapshots or COW copies 941 * when nowcow writeback call back. This checks for snapshots or COW copies
915 * of the extents that exist in the file, and COWs the file as required. 942 * of the extents that exist in the file, and COWs the file as required.
@@ -971,6 +998,7 @@ next_slot:
971 998
972 nocow = 0; 999 nocow = 0;
973 disk_bytenr = 0; 1000 disk_bytenr = 0;
1001 num_bytes = 0;
974 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 1002 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
975 1003
976 if (found_key.objectid > inode->i_ino || 1004 if (found_key.objectid > inode->i_ino ||
@@ -996,19 +1024,29 @@ next_slot:
996 path->slots[0]++; 1024 path->slots[0]++;
997 goto next_slot; 1025 goto next_slot;
998 } 1026 }
1027 if (disk_bytenr == 0)
1028 goto out_check;
999 if (btrfs_file_extent_compression(leaf, fi) || 1029 if (btrfs_file_extent_compression(leaf, fi) ||
1000 btrfs_file_extent_encryption(leaf, fi) || 1030 btrfs_file_extent_encryption(leaf, fi) ||
1001 btrfs_file_extent_other_encoding(leaf, fi)) 1031 btrfs_file_extent_other_encoding(leaf, fi))
1002 goto out_check; 1032 goto out_check;
1003 if (disk_bytenr == 0)
1004 goto out_check;
1005 if (extent_type == BTRFS_FILE_EXTENT_REG && !force) 1033 if (extent_type == BTRFS_FILE_EXTENT_REG && !force)
1006 goto out_check; 1034 goto out_check;
1007 if (btrfs_cross_ref_exist(trans, root, disk_bytenr))
1008 goto out_check;
1009 if (btrfs_extent_readonly(root, disk_bytenr)) 1035 if (btrfs_extent_readonly(root, disk_bytenr))
1010 goto out_check; 1036 goto out_check;
1037 if (btrfs_cross_ref_exist(trans, root, inode->i_ino,
1038 disk_bytenr))
1039 goto out_check;
1011 disk_bytenr += btrfs_file_extent_offset(leaf, fi); 1040 disk_bytenr += btrfs_file_extent_offset(leaf, fi);
1041 disk_bytenr += cur_offset - found_key.offset;
1042 num_bytes = min(end + 1, extent_end) - cur_offset;
1043 /*
1044 * force cow if csum exists in the range.
1045 * this ensure that csum for a given extent are
1046 * either valid or do not exist.
1047 */
1048 if (csum_exist_in_range(root, disk_bytenr, num_bytes))
1049 goto out_check;
1012 nocow = 1; 1050 nocow = 1;
1013 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { 1051 } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
1014 extent_end = found_key.offset + 1052 extent_end = found_key.offset +
@@ -1041,8 +1079,6 @@ out_check:
1041 cow_start = (u64)-1; 1079 cow_start = (u64)-1;
1042 } 1080 }
1043 1081
1044 disk_bytenr += cur_offset - found_key.offset;
1045 num_bytes = min(end + 1, extent_end) - cur_offset;
1046 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) { 1082 if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
1047 struct extent_map *em; 1083 struct extent_map *em;
1048 struct extent_map_tree *em_tree; 1084 struct extent_map_tree *em_tree;
@@ -1105,11 +1141,9 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1105 u64 start, u64 end, int *page_started, 1141 u64 start, u64 end, int *page_started,
1106 unsigned long *nr_written) 1142 unsigned long *nr_written)
1107{ 1143{
1108 struct btrfs_root *root = BTRFS_I(inode)->root;
1109 int ret; 1144 int ret;
1110 1145
1111 if (btrfs_test_opt(root, NODATACOW) || 1146 if (btrfs_test_flag(inode, NODATACOW))
1112 btrfs_test_flag(inode, NODATACOW))
1113 ret = run_delalloc_nocow(inode, locked_page, start, end, 1147 ret = run_delalloc_nocow(inode, locked_page, start, end,
1114 page_started, 1, nr_written); 1148 page_started, 1, nr_written);
1115 else if (btrfs_test_flag(inode, PREALLOC)) 1149 else if (btrfs_test_flag(inode, PREALLOC))
@@ -1252,8 +1286,7 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1252 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); 1286 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
1253 BUG_ON(ret); 1287 BUG_ON(ret);
1254 1288
1255 skip_sum = btrfs_test_opt(root, NODATASUM) || 1289 skip_sum = btrfs_test_flag(inode, NODATASUM);
1256 btrfs_test_flag(inode, NODATASUM);
1257 1290
1258 if (!(rw & (1 << BIO_RW))) { 1291 if (!(rw & (1 << BIO_RW))) {
1259 if (bio_flags & EXTENT_BIO_COMPRESSED) { 1292 if (bio_flags & EXTENT_BIO_COMPRESSED) {
@@ -1263,6 +1296,9 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
1263 btrfs_lookup_bio_sums(root, inode, bio, NULL); 1296 btrfs_lookup_bio_sums(root, inode, bio, NULL);
1264 goto mapit; 1297 goto mapit;
1265 } else if (!skip_sum) { 1298 } else if (!skip_sum) {
1299 /* csum items have already been cloned */
1300 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID)
1301 goto mapit;
1266 /* we're doing a write, do the async checksumming */ 1302 /* we're doing a write, do the async checksumming */
1267 return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, 1303 return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info,
1268 inode, rw, bio, mirror_num, 1304 inode, rw, bio, mirror_num,
@@ -1692,9 +1728,15 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
1692 ClearPageChecked(page); 1728 ClearPageChecked(page);
1693 goto good; 1729 goto good;
1694 } 1730 }
1695 if (btrfs_test_opt(root, NODATASUM) || 1731 if (btrfs_test_flag(inode, NODATASUM))
1696 btrfs_test_flag(inode, NODATASUM)) 1732 return 0;
1733
1734 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID &&
1735 test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1)) {
1736 clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM,
1737 GFP_NOFS);
1697 return 0; 1738 return 0;
1739 }
1698 1740
1699 if (state && state->start == start) { 1741 if (state && state->start == start) {
1700 private = state->private; 1742 private = state->private;
@@ -3391,6 +3433,12 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3391 owner = 1; 3433 owner = 1;
3392 BTRFS_I(inode)->block_group = 3434 BTRFS_I(inode)->block_group =
3393 btrfs_find_block_group(root, 0, alloc_hint, owner); 3435 btrfs_find_block_group(root, 0, alloc_hint, owner);
3436 if ((mode & S_IFREG)) {
3437 if (btrfs_test_opt(root, NODATASUM))
3438 btrfs_set_flag(inode, NODATASUM);
3439 if (btrfs_test_opt(root, NODATACOW))
3440 btrfs_set_flag(inode, NODATACOW);
3441 }
3394 3442
3395 key[0].objectid = objectid; 3443 key[0].objectid = objectid;
3396 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); 3444 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);