aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file-item.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r--fs/btrfs/file-item.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 9b99886562d0..a562a250ae77 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/bio.h> 19#include <linux/bio.h>
20#include <linux/slab.h>
20#include <linux/pagemap.h> 21#include <linux/pagemap.h>
21#include <linux/highmem.h> 22#include <linux/highmem.h>
22#include "ctree.h" 23#include "ctree.h"
@@ -148,13 +149,14 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
148} 149}
149 150
150 151
151int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode, 152static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
152 struct bio *bio, u32 *dst) 153 struct inode *inode, struct bio *bio,
154 u64 logical_offset, u32 *dst, int dio)
153{ 155{
154 u32 sum; 156 u32 sum;
155 struct bio_vec *bvec = bio->bi_io_vec; 157 struct bio_vec *bvec = bio->bi_io_vec;
156 int bio_index = 0; 158 int bio_index = 0;
157 u64 offset; 159 u64 offset = 0;
158 u64 item_start_offset = 0; 160 u64 item_start_offset = 0;
159 u64 item_last_offset = 0; 161 u64 item_last_offset = 0;
160 u64 disk_bytenr; 162 u64 disk_bytenr;
@@ -173,8 +175,11 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
173 WARN_ON(bio->bi_vcnt <= 0); 175 WARN_ON(bio->bi_vcnt <= 0);
174 176
175 disk_bytenr = (u64)bio->bi_sector << 9; 177 disk_bytenr = (u64)bio->bi_sector << 9;
178 if (dio)
179 offset = logical_offset;
176 while (bio_index < bio->bi_vcnt) { 180 while (bio_index < bio->bi_vcnt) {
177 offset = page_offset(bvec->bv_page) + bvec->bv_offset; 181 if (!dio)
182 offset = page_offset(bvec->bv_page) + bvec->bv_offset;
178 ret = btrfs_find_ordered_sum(inode, offset, disk_bytenr, &sum); 183 ret = btrfs_find_ordered_sum(inode, offset, disk_bytenr, &sum);
179 if (ret == 0) 184 if (ret == 0)
180 goto found; 185 goto found;
@@ -237,6 +242,7 @@ found:
237 else 242 else
238 set_state_private(io_tree, offset, sum); 243 set_state_private(io_tree, offset, sum);
239 disk_bytenr += bvec->bv_len; 244 disk_bytenr += bvec->bv_len;
245 offset += bvec->bv_len;
240 bio_index++; 246 bio_index++;
241 bvec++; 247 bvec++;
242 } 248 }
@@ -244,6 +250,18 @@ found:
244 return 0; 250 return 0;
245} 251}
246 252
253int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,
254 struct bio *bio, u32 *dst)
255{
256 return __btrfs_lookup_bio_sums(root, inode, bio, 0, dst, 0);
257}
258
259int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode,
260 struct bio *bio, u64 offset, u32 *dst)
261{
262 return __btrfs_lookup_bio_sums(root, inode, bio, offset, dst, 1);
263}
264
247int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, 265int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
248 struct list_head *list) 266 struct list_head *list)
249{ 267{
@@ -656,6 +674,9 @@ again:
656 goto found; 674 goto found;
657 } 675 }
658 ret = PTR_ERR(item); 676 ret = PTR_ERR(item);
677 if (ret != -EFBIG && ret != -ENOENT)
678 goto fail_unlock;
679
659 if (ret == -EFBIG) { 680 if (ret == -EFBIG) {
660 u32 item_size; 681 u32 item_size;
661 /* we found one, but it isn't big enough yet */ 682 /* we found one, but it isn't big enough yet */