aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file-item.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-02-20 12:07:25 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit6e92f5e651a34f24ab31ebdf3f113c7d23a36000 (patch)
tree57695b87c3a86c418cb4ba65de53ca809e7b5e60 /fs/btrfs/file-item.c
parent065631f6dccea07bfad48d8981369f6d9cfd6e2b (diff)
Btrfs: While doing checksums on bios, cache the extent_buffer mapping
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file-item.c')
-rw-r--r--fs/btrfs/file-item.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 3f0e71b0e5d9..ee25e50e7c04 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -156,6 +156,11 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
156 int bio_index = 0; 156 int bio_index = 0;
157 struct bio_vec *bvec = bio->bi_io_vec; 157 struct bio_vec *bvec = bio->bi_io_vec;
158 char *data; 158 char *data;
159 char *eb_map;
160 char *eb_token;
161 unsigned long map_len;
162 unsigned long map_start;
163
159 164
160 path = btrfs_alloc_path(); 165 path = btrfs_alloc_path();
161 BUG_ON(!path); 166 BUG_ON(!path);
@@ -272,6 +277,7 @@ found:
272 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item); 277 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
273 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end + 278 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end +
274 btrfs_item_size_nr(leaf, path->slots[0])); 279 btrfs_item_size_nr(leaf, path->slots[0]));
280 eb_token = NULL;
275next_bvec: 281next_bvec:
276 data = kmap_atomic(bvec->bv_page, KM_IRQ0); 282 data = kmap_atomic(bvec->bv_page, KM_IRQ0);
277 csum_result = ~(u32)0; 283 csum_result = ~(u32)0;
@@ -283,15 +289,39 @@ next_bvec:
283 printk("csum result is 0 for inode %lu offset %Lu\n", inode->i_ino, offset); 289 printk("csum result is 0 for inode %lu offset %Lu\n", inode->i_ino, offset);
284 } 290 }
285 291
286 write_extent_buffer(leaf, &csum_result, (unsigned long)item, 292 if (!eb_token ||
287 BTRFS_CRC32_SIZE); 293 (unsigned long)item + BTRFS_CRC32_SIZE >= map_start + map_len) {
294 int err;
295
296 if (eb_token)
297 unmap_extent_buffer(leaf, eb_token, KM_IRQ1);
298 eb_token = NULL;
299 err = map_private_extent_buffer(leaf, (unsigned long)item,
300 BTRFS_CRC32_SIZE,
301 &eb_token, &eb_map,
302 &map_start, &map_len, KM_IRQ1);
303 if (err)
304 eb_token = NULL;
305 }
306 if (eb_token) {
307 memcpy(eb_token + ((unsigned long)item & (PAGE_CACHE_SIZE - 1)),
308 &csum_result, BTRFS_CRC32_SIZE);
309 } else {
310 write_extent_buffer(leaf, &csum_result, (unsigned long)item,
311 BTRFS_CRC32_SIZE);
312 }
288 bio_index++; 313 bio_index++;
289 bvec++; 314 bvec++;
290 if (bio_index < bio->bi_vcnt) { 315 if (bio_index < bio->bi_vcnt) {
291 item = (struct btrfs_csum_item *)((char *)item + BTRFS_CRC32_SIZE); 316 item = (struct btrfs_csum_item *)((char *)item +
317 BTRFS_CRC32_SIZE);
292 if (item < item_end) 318 if (item < item_end)
293 goto next_bvec; 319 goto next_bvec;
294 } 320 }
321 if (eb_token) {
322 unmap_extent_buffer(leaf, eb_token, KM_IRQ1);
323 eb_token = NULL;
324 }
295 btrfs_mark_buffer_dirty(path->nodes[0]); 325 btrfs_mark_buffer_dirty(path->nodes[0]);
296 if (bio_index < bio->bi_vcnt) { 326 if (bio_index < bio->bi_vcnt) {
297 btrfs_release_path(root, path); 327 btrfs_release_path(root, path);