aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c85
1 files changed, 34 insertions, 51 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d3280b2b7592..b47330c8e02c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2826,16 +2826,16 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
2826 * if there's a match, we allow the bio to finish. If not, the code in 2826 * if there's a match, we allow the bio to finish. If not, the code in
2827 * extent_io.c will try to find good copies for us. 2827 * extent_io.c will try to find good copies for us.
2828 */ 2828 */
2829static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, 2829static int btrfs_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
2830 struct extent_state *state, int mirror) 2830 u64 phy_offset, struct page *page,
2831 u64 start, u64 end, int mirror)
2831{ 2832{
2832 size_t offset = start - page_offset(page); 2833 size_t offset = start - page_offset(page);
2833 struct inode *inode = page->mapping->host; 2834 struct inode *inode = page->mapping->host;
2834 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 2835 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
2835 char *kaddr; 2836 char *kaddr;
2836 u64 private = ~(u32)0;
2837 int ret;
2838 struct btrfs_root *root = BTRFS_I(inode)->root; 2837 struct btrfs_root *root = BTRFS_I(inode)->root;
2838 u32 csum_expected;
2839 u32 csum = ~(u32)0; 2839 u32 csum = ~(u32)0;
2840 static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, 2840 static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
2841 DEFAULT_RATELIMIT_BURST); 2841 DEFAULT_RATELIMIT_BURST);
@@ -2855,19 +2855,13 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
2855 return 0; 2855 return 0;
2856 } 2856 }
2857 2857
2858 if (state && state->start == start) { 2858 phy_offset >>= inode->i_sb->s_blocksize_bits;
2859 private = state->private; 2859 csum_expected = *(((u32 *)io_bio->csum) + phy_offset);
2860 ret = 0;
2861 } else {
2862 ret = get_state_private(io_tree, start, &private);
2863 }
2864 kaddr = kmap_atomic(page);
2865 if (ret)
2866 goto zeroit;
2867 2860
2861 kaddr = kmap_atomic(page);
2868 csum = btrfs_csum_data(kaddr + offset, csum, end - start + 1); 2862 csum = btrfs_csum_data(kaddr + offset, csum, end - start + 1);
2869 btrfs_csum_final(csum, (char *)&csum); 2863 btrfs_csum_final(csum, (char *)&csum);
2870 if (csum != private) 2864 if (csum != csum_expected)
2871 goto zeroit; 2865 goto zeroit;
2872 2866
2873 kunmap_atomic(kaddr); 2867 kunmap_atomic(kaddr);
@@ -2876,14 +2870,13 @@ good:
2876 2870
2877zeroit: 2871zeroit:
2878 if (__ratelimit(&_rs)) 2872 if (__ratelimit(&_rs))
2879 btrfs_info(root->fs_info, "csum failed ino %llu off %llu csum %u private %llu", 2873 btrfs_info(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u",
2880 (unsigned long long)btrfs_ino(page->mapping->host), 2874 (unsigned long long)btrfs_ino(page->mapping->host),
2881 (unsigned long long)start, csum, 2875 (unsigned long long)start, csum, csum_expected);
2882 (unsigned long long)private);
2883 memset(kaddr + offset, 1, end - start + 1); 2876 memset(kaddr + offset, 1, end - start + 1);
2884 flush_dcache_page(page); 2877 flush_dcache_page(page);
2885 kunmap_atomic(kaddr); 2878 kunmap_atomic(kaddr);
2886 if (private == 0) 2879 if (csum_expected == 0)
2887 return 0; 2880 return 0;
2888 return -EIO; 2881 return -EIO;
2889} 2882}
@@ -6812,26 +6805,6 @@ unlock_err:
6812 return ret; 6805 return ret;
6813} 6806}
6814 6807
6815struct btrfs_dio_private {
6816 struct inode *inode;
6817 u64 logical_offset;
6818 u64 disk_bytenr;
6819 u64 bytes;
6820 void *private;
6821
6822 /* number of bios pending for this dio */
6823 atomic_t pending_bios;
6824
6825 /* IO errors */
6826 int errors;
6827
6828 /* orig_bio is our btrfs_io_bio */
6829 struct bio *orig_bio;
6830
6831 /* dio_bio came from fs/direct-io.c */
6832 struct bio *dio_bio;
6833};
6834
6835static void btrfs_endio_direct_read(struct bio *bio, int err) 6808static void btrfs_endio_direct_read(struct bio *bio, int err)
6836{ 6809{
6837 struct btrfs_dio_private *dip = bio->bi_private; 6810 struct btrfs_dio_private *dip = bio->bi_private;
@@ -6840,6 +6813,8 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
6840 struct inode *inode = dip->inode; 6813 struct inode *inode = dip->inode;
6841 struct btrfs_root *root = BTRFS_I(inode)->root; 6814 struct btrfs_root *root = BTRFS_I(inode)->root;
6842 struct bio *dio_bio; 6815 struct bio *dio_bio;
6816 u32 *csums = (u32 *)dip->csum;
6817 int index = 0;
6843 u64 start; 6818 u64 start;
6844 6819
6845 start = dip->logical_offset; 6820 start = dip->logical_offset;
@@ -6848,12 +6823,8 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
6848 struct page *page = bvec->bv_page; 6823 struct page *page = bvec->bv_page;
6849 char *kaddr; 6824 char *kaddr;
6850 u32 csum = ~(u32)0; 6825 u32 csum = ~(u32)0;
6851 u64 private = ~(u32)0;
6852 unsigned long flags; 6826 unsigned long flags;
6853 6827
6854 if (get_state_private(&BTRFS_I(inode)->io_tree,
6855 start, &private))
6856 goto failed;
6857 local_irq_save(flags); 6828 local_irq_save(flags);
6858 kaddr = kmap_atomic(page); 6829 kaddr = kmap_atomic(page);
6859 csum = btrfs_csum_data(kaddr + bvec->bv_offset, 6830 csum = btrfs_csum_data(kaddr + bvec->bv_offset,
@@ -6863,18 +6834,18 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
6863 local_irq_restore(flags); 6834 local_irq_restore(flags);
6864 6835
6865 flush_dcache_page(bvec->bv_page); 6836 flush_dcache_page(bvec->bv_page);
6866 if (csum != private) { 6837 if (csum != csums[index]) {
6867failed: 6838 btrfs_err(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u",
6868 btrfs_err(root->fs_info, "csum failed ino %llu off %llu csum %u private %u", 6839 (unsigned long long)btrfs_ino(inode),
6869 (unsigned long long)btrfs_ino(inode), 6840 (unsigned long long)start,
6870 (unsigned long long)start, 6841 csum, csums[index]);
6871 csum, (unsigned)private);
6872 err = -EIO; 6842 err = -EIO;
6873 } 6843 }
6874 } 6844 }
6875 6845
6876 start += bvec->bv_len; 6846 start += bvec->bv_len;
6877 bvec++; 6847 bvec++;
6848 index++;
6878 } while (bvec <= bvec_end); 6849 } while (bvec <= bvec_end);
6879 6850
6880 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, 6851 unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset,
@@ -6991,6 +6962,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
6991 int rw, u64 file_offset, int skip_sum, 6962 int rw, u64 file_offset, int skip_sum,
6992 int async_submit) 6963 int async_submit)
6993{ 6964{
6965 struct btrfs_dio_private *dip = bio->bi_private;
6994 int write = rw & REQ_WRITE; 6966 int write = rw & REQ_WRITE;
6995 struct btrfs_root *root = BTRFS_I(inode)->root; 6967 struct btrfs_root *root = BTRFS_I(inode)->root;
6996 int ret; 6968 int ret;
@@ -7025,7 +6997,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
7025 if (ret) 6997 if (ret)
7026 goto err; 6998 goto err;
7027 } else if (!skip_sum) { 6999 } else if (!skip_sum) {
7028 ret = btrfs_lookup_bio_sums_dio(root, inode, bio, file_offset); 7000 ret = btrfs_lookup_bio_sums_dio(root, inode, dip, bio,
7001 file_offset);
7029 if (ret) 7002 if (ret)
7030 goto err; 7003 goto err;
7031 } 7004 }
@@ -7060,6 +7033,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
7060 bio_put(orig_bio); 7033 bio_put(orig_bio);
7061 return -EIO; 7034 return -EIO;
7062 } 7035 }
7036
7063 if (map_length >= orig_bio->bi_size) { 7037 if (map_length >= orig_bio->bi_size) {
7064 bio = orig_bio; 7038 bio = orig_bio;
7065 goto submit; 7039 goto submit;
@@ -7155,19 +7129,28 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
7155 struct btrfs_dio_private *dip; 7129 struct btrfs_dio_private *dip;
7156 struct bio *io_bio; 7130 struct bio *io_bio;
7157 int skip_sum; 7131 int skip_sum;
7132 int sum_len;
7158 int write = rw & REQ_WRITE; 7133 int write = rw & REQ_WRITE;
7159 int ret = 0; 7134 int ret = 0;
7135 u16 csum_size;
7160 7136
7161 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 7137 skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
7162 7138
7163 io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS); 7139 io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS);
7164
7165 if (!io_bio) { 7140 if (!io_bio) {
7166 ret = -ENOMEM; 7141 ret = -ENOMEM;
7167 goto free_ordered; 7142 goto free_ordered;
7168 } 7143 }
7169 7144
7170 dip = kmalloc(sizeof(*dip), GFP_NOFS); 7145 if (!skip_sum && !write) {
7146 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
7147 sum_len = dio_bio->bi_size >> inode->i_sb->s_blocksize_bits;
7148 sum_len *= csum_size;
7149 } else {
7150 sum_len = 0;
7151 }
7152
7153 dip = kmalloc(sizeof(*dip) + sum_len, GFP_NOFS);
7171 if (!dip) { 7154 if (!dip) {
7172 ret = -ENOMEM; 7155 ret = -ENOMEM;
7173 goto free_io_bio; 7156 goto free_io_bio;