aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-09-12 06:43:55 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:52 -0400
commitdc380aea5fa4636fc498a351eb720943bc644451 (patch)
tree9bbc8a668a1c18b828ff7fc71d6807e6df4ad538
parent23ea8e5a07673127d05cb5cf6f9914d7a53e0847 (diff)
Btrfs: cleanup similar code of the buffered data data check and dio read data check
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/inode.c102
1 files changed, 47 insertions, 55 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index fca944211bf0..70eaae127181 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2899,6 +2899,40 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
2899 return 0; 2899 return 0;
2900} 2900}
2901 2901
2902static int __readpage_endio_check(struct inode *inode,
2903 struct btrfs_io_bio *io_bio,
2904 int icsum, struct page *page,
2905 int pgoff, u64 start, size_t len)
2906{
2907 char *kaddr;
2908 u32 csum_expected;
2909 u32 csum = ~(u32)0;
2910 static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
2911 DEFAULT_RATELIMIT_BURST);
2912
2913 csum_expected = *(((u32 *)io_bio->csum) + icsum);
2914
2915 kaddr = kmap_atomic(page);
2916 csum = btrfs_csum_data(kaddr + pgoff, csum, len);
2917 btrfs_csum_final(csum, (char *)&csum);
2918 if (csum != csum_expected)
2919 goto zeroit;
2920
2921 kunmap_atomic(kaddr);
2922 return 0;
2923zeroit:
2924 if (__ratelimit(&_rs))
2925 btrfs_info(BTRFS_I(inode)->root->fs_info,
2926 "csum failed ino %llu off %llu csum %u expected csum %u",
2927 btrfs_ino(inode), start, csum, csum_expected);
2928 memset(kaddr + pgoff, 1, len);
2929 flush_dcache_page(page);
2930 kunmap_atomic(kaddr);
2931 if (csum_expected == 0)
2932 return 0;
2933 return -EIO;
2934}
2935
2902/* 2936/*
2903 * when reads are done, we need to check csums to verify the data is correct 2937 * when reads are done, we need to check csums to verify the data is correct
2904 * if there's a match, we allow the bio to finish. If not, the code in 2938 * if there's a match, we allow the bio to finish. If not, the code in
@@ -2911,20 +2945,15 @@ static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
2911 size_t offset = start - page_offset(page); 2945 size_t offset = start - page_offset(page);
2912 struct inode *inode = page->mapping->host; 2946 struct inode *inode = page->mapping->host;
2913 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 2947 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
2914 char *kaddr;
2915 struct btrfs_root *root = BTRFS_I(inode)->root; 2948 struct btrfs_root *root = BTRFS_I(inode)->root;
2916 u32 csum_expected;
2917 u32 csum = ~(u32)0;
2918 static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
2919 DEFAULT_RATELIMIT_BURST);
2920 2949
2921 if (PageChecked(page)) { 2950 if (PageChecked(page)) {
2922 ClearPageChecked(page); 2951 ClearPageChecked(page);
2923 goto good; 2952 return 0;
2924 } 2953 }
2925 2954
2926 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM) 2955 if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)
2927 goto good; 2956 return 0;
2928 2957
2929 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && 2958 if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID &&
2930 test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) { 2959 test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) {
@@ -2934,28 +2963,8 @@ static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
2934 } 2963 }
2935 2964
2936 phy_offset >>= inode->i_sb->s_blocksize_bits; 2965 phy_offset >>= inode->i_sb->s_blocksize_bits;
2937 csum_expected = *(((u32 *)io_bio->csum) + phy_offset); 2966 return __readpage_endio_check(inode, io_bio, phy_offset, page, offset,
2938 2967 start, (size_t)(end - start + 1));
2939 kaddr = kmap_atomic(page);
2940 csum = btrfs_csum_data(kaddr + offset, csum, end - start + 1);
2941 btrfs_csum_final(csum, (char *)&csum);
2942 if (csum != csum_expected)
2943 goto zeroit;
2944
2945 kunmap_atomic(kaddr);
2946good:
2947 return 0;
2948
2949zeroit:
2950 if (__ratelimit(&_rs))
2951 btrfs_info(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u",
2952 btrfs_ino(page->mapping->host), start, csum, csum_expected);
2953 memset(kaddr + offset, 1, end - start + 1);
2954 flush_dcache_page(page);
2955 kunmap_atomic(kaddr);
2956 if (csum_expected == 0)
2957 return 0;
2958 return -EIO;
2959} 2968}
2960 2969
2961struct delayed_iput { 2970struct delayed_iput {
@@ -7238,41 +7247,24 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
7238 struct btrfs_dio_private *dip = bio->bi_private; 7247 struct btrfs_dio_private *dip = bio->bi_private;
7239 struct bio_vec *bvec; 7248 struct bio_vec *bvec;
7240 struct inode *inode = dip->inode; 7249 struct inode *inode = dip->inode;
7241 struct btrfs_root *root = BTRFS_I(inode)->root;
7242 struct bio *dio_bio; 7250 struct bio *dio_bio;
7243 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); 7251 struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
7244 u32 *csums = (u32 *)io_bio->csum;
7245 u64 start; 7252 u64 start;
7253 int ret;
7246 int i; 7254 int i;
7247 7255
7256 if (err || (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
7257 goto skip_checksum;
7258
7248 start = dip->logical_offset; 7259 start = dip->logical_offset;
7249 bio_for_each_segment_all(bvec, bio, i) { 7260 bio_for_each_segment_all(bvec, bio, i) {
7250 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { 7261 ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page,
7251 struct page *page = bvec->bv_page; 7262 0, start, bvec->bv_len);
7252 char *kaddr; 7263 if (ret)
7253 u32 csum = ~(u32)0; 7264 err = -EIO;
7254 unsigned long flags;
7255
7256 local_irq_save(flags);
7257 kaddr = kmap_atomic(page);
7258 csum = btrfs_csum_data(kaddr + bvec->bv_offset,
7259 csum, bvec->bv_len);
7260 btrfs_csum_final(csum, (char *)&csum);
7261 kunmap_atomic(kaddr);
7262 local_irq_restore(flags);
7263
7264 flush_dcache_page(bvec->bv_page);
7265 if (csum != csums[i]) {
7266 btrfs_err(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u",
7267 btrfs_ino(inode), start, csum,
7268 csums[i]);
7269 err = -EIO;
7270 }
7271 }
7272
7273 start += bvec->bv_len; 7265 start += bvec->bv_len;
7274 } 7266 }
7275 7267skip_checksum:
7276 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, 7268 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
7277 dip->logical_offset + dip->bytes - 1); 7269 dip->logical_offset + dip->bytes - 1);
7278 dio_bio = dip->dio_bio; 7270 dio_bio = dip->dio_bio;