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.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 3ebbc058d082..3f0e71b0e5d9 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -16,6 +16,9 @@
16 * Boston, MA 021110-1307, USA. 16 * Boston, MA 021110-1307, USA.
17 */ 17 */
18 18
19#include <linux/bio.h>
20#include <linux/pagemap.h>
21#include <linux/highmem.h>
19#include "ctree.h" 22#include "ctree.h"
20#include "disk-io.h" 23#include "disk-io.h"
21#include "transaction.h" 24#include "transaction.h"
@@ -131,28 +134,35 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
131 return ret; 134 return ret;
132} 135}
133 136
134int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 137int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
135 struct btrfs_root *root, 138 struct btrfs_root *root, struct inode *inode,
136 struct inode *inode, 139 struct bio *bio)
137 u64 objectid, u64 offset,
138 char *data, size_t len)
139{ 140{
141 u64 objectid = inode->i_ino;
142 u64 offset;
140 int ret; 143 int ret;
141 struct btrfs_key file_key; 144 struct btrfs_key file_key;
142 struct btrfs_key found_key; 145 struct btrfs_key found_key;
143 u64 next_offset = (u64)-1; 146 u64 next_offset;
144 int found_next = 0; 147 int found_next;
145 struct btrfs_path *path; 148 struct btrfs_path *path;
146 struct btrfs_csum_item *item; 149 struct btrfs_csum_item *item;
150 struct btrfs_csum_item *item_end;
147 struct extent_buffer *leaf = NULL; 151 struct extent_buffer *leaf = NULL;
148 u64 csum_offset; 152 u64 csum_offset;
149 u32 csum_result = ~(u32)0; 153 u32 csum_result;
150 u32 nritems; 154 u32 nritems;
151 u32 ins_size; 155 u32 ins_size;
156 int bio_index = 0;
157 struct bio_vec *bvec = bio->bi_io_vec;
158 char *data;
152 159
153 path = btrfs_alloc_path(); 160 path = btrfs_alloc_path();
154 BUG_ON(!path); 161 BUG_ON(!path);
155 162again:
163 next_offset = (u64)-1;
164 found_next = 0;
165 offset = page_offset(bvec->bv_page) + bvec->bv_offset;
156 file_key.objectid = objectid; 166 file_key.objectid = objectid;
157 file_key.offset = offset; 167 file_key.offset = offset;
158 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); 168 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
@@ -259,7 +269,15 @@ csum:
259 item = (struct btrfs_csum_item *)((unsigned char *)item + 269 item = (struct btrfs_csum_item *)((unsigned char *)item +
260 csum_offset * BTRFS_CRC32_SIZE); 270 csum_offset * BTRFS_CRC32_SIZE);
261found: 271found:
262 csum_result = btrfs_csum_data(root, data, csum_result, len); 272 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
273 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end +
274 btrfs_item_size_nr(leaf, path->slots[0]));
275next_bvec:
276 data = kmap_atomic(bvec->bv_page, KM_IRQ0);
277 csum_result = ~(u32)0;
278 csum_result = btrfs_csum_data(root, data + bvec->bv_offset,
279 csum_result, bvec->bv_len);
280 kunmap_atomic(data, KM_IRQ0);
263 btrfs_csum_final(csum_result, (char *)&csum_result); 281 btrfs_csum_final(csum_result, (char *)&csum_result);
264 if (csum_result == 0) { 282 if (csum_result == 0) {
265 printk("csum result is 0 for inode %lu offset %Lu\n", inode->i_ino, offset); 283 printk("csum result is 0 for inode %lu offset %Lu\n", inode->i_ino, offset);
@@ -267,9 +285,19 @@ found:
267 285
268 write_extent_buffer(leaf, &csum_result, (unsigned long)item, 286 write_extent_buffer(leaf, &csum_result, (unsigned long)item,
269 BTRFS_CRC32_SIZE); 287 BTRFS_CRC32_SIZE);
288 bio_index++;
289 bvec++;
290 if (bio_index < bio->bi_vcnt) {
291 item = (struct btrfs_csum_item *)((char *)item + BTRFS_CRC32_SIZE);
292 if (item < item_end)
293 goto next_bvec;
294 }
270 btrfs_mark_buffer_dirty(path->nodes[0]); 295 btrfs_mark_buffer_dirty(path->nodes[0]);
296 if (bio_index < bio->bi_vcnt) {
297 btrfs_release_path(root, path);
298 goto again;
299 }
271fail: 300fail:
272 btrfs_release_path(root, path);
273 btrfs_free_path(path); 301 btrfs_free_path(path);
274 return ret; 302 return ret;
275} 303}