aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/compression.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r--fs/btrfs/compression.c150
1 files changed, 145 insertions, 5 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 354913177ba6..284f21025bcc 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -33,6 +33,7 @@
33#include <linux/writeback.h> 33#include <linux/writeback.h>
34#include <linux/bit_spinlock.h> 34#include <linux/bit_spinlock.h>
35#include <linux/version.h> 35#include <linux/version.h>
36#include <linux/pagevec.h>
36#include "ctree.h" 37#include "ctree.h"
37#include "disk-io.h" 38#include "disk-io.h"
38#include "transaction.h" 39#include "transaction.h"
@@ -145,9 +146,9 @@ static void end_compressed_bio_read(struct bio *bio, int err)
145 } 146 }
146 147
147 /* do io completion on the original bio */ 148 /* do io completion on the original bio */
148 if (cb->errors) 149 if (cb->errors) {
149 bio_io_error(cb->orig_bio); 150 bio_io_error(cb->orig_bio);
150 else 151 } else
151 bio_endio(cb->orig_bio, 0); 152 bio_endio(cb->orig_bio, 0);
152 153
153 /* finally free the cb struct */ 154 /* finally free the cb struct */
@@ -333,6 +334,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
333 } 334 }
334 bytes_left -= PAGE_CACHE_SIZE; 335 bytes_left -= PAGE_CACHE_SIZE;
335 first_byte += PAGE_CACHE_SIZE; 336 first_byte += PAGE_CACHE_SIZE;
337 cond_resched();
336 } 338 }
337 bio_get(bio); 339 bio_get(bio);
338 340
@@ -346,6 +348,130 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
346 return 0; 348 return 0;
347} 349}
348 350
351static noinline int add_ra_bio_pages(struct inode *inode,
352 u64 compressed_end,
353 struct compressed_bio *cb)
354{
355 unsigned long end_index;
356 unsigned long page_index;
357 u64 last_offset;
358 u64 isize = i_size_read(inode);
359 int ret;
360 struct page *page;
361 unsigned long nr_pages = 0;
362 struct extent_map *em;
363 struct address_space *mapping = inode->i_mapping;
364 struct pagevec pvec;
365 struct extent_map_tree *em_tree;
366 struct extent_io_tree *tree;
367 u64 end;
368 int misses = 0;
369
370 page = cb->orig_bio->bi_io_vec[cb->orig_bio->bi_vcnt - 1].bv_page;
371 last_offset = (page_offset(page) + PAGE_CACHE_SIZE);
372 em_tree = &BTRFS_I(inode)->extent_tree;
373 tree = &BTRFS_I(inode)->io_tree;
374
375 if (isize == 0)
376 return 0;
377
378 end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
379
380 pagevec_init(&pvec, 0);
381 while(last_offset < compressed_end) {
382 page_index = last_offset >> PAGE_CACHE_SHIFT;
383
384 if (page_index > end_index)
385 break;
386
387 rcu_read_lock();
388 page = radix_tree_lookup(&mapping->page_tree, page_index);
389 rcu_read_unlock();
390 if (page) {
391 misses++;
392 if (misses > 4)
393 break;
394 goto next;
395 }
396
397 page = alloc_page(mapping_gfp_mask(mapping) | GFP_NOFS);
398 if (!page)
399 break;
400
401 page->index = page_index;
402 /*
403 * what we want to do here is call add_to_page_cache_lru,
404 * but that isn't exported, so we reproduce it here
405 */
406 if (add_to_page_cache(page, mapping,
407 page->index, GFP_NOFS)) {
408 page_cache_release(page);
409 goto next;
410 }
411
412 /* open coding of lru_cache_add, also not exported */
413 page_cache_get(page);
414 if (!pagevec_add(&pvec, page))
415 __pagevec_lru_add(&pvec);
416
417 end = last_offset + PAGE_CACHE_SIZE - 1;
418 /*
419 * at this point, we have a locked page in the page cache
420 * for these bytes in the file. But, we have to make
421 * sure they map to this compressed extent on disk.
422 */
423 set_page_extent_mapped(page);
424 lock_extent(tree, last_offset, end, GFP_NOFS);
425 spin_lock(&em_tree->lock);
426 em = lookup_extent_mapping(em_tree, last_offset,
427 PAGE_CACHE_SIZE);
428 spin_unlock(&em_tree->lock);
429
430 if (!em || last_offset < em->start ||
431 (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) ||
432 (em->block_start >> 9) != cb->orig_bio->bi_sector) {
433 free_extent_map(em);
434 unlock_extent(tree, last_offset, end, GFP_NOFS);
435 unlock_page(page);
436 page_cache_release(page);
437 break;
438 }
439 free_extent_map(em);
440
441 if (page->index == end_index) {
442 char *userpage;
443 size_t zero_offset = isize & (PAGE_CACHE_SIZE - 1);
444
445 if (zero_offset) {
446 int zeros;
447 zeros = PAGE_CACHE_SIZE - zero_offset;
448 userpage = kmap_atomic(page, KM_USER0);
449 memset(userpage + zero_offset, 0, zeros);
450 flush_dcache_page(page);
451 kunmap_atomic(userpage, KM_USER0);
452 }
453 }
454
455 ret = bio_add_page(cb->orig_bio, page,
456 PAGE_CACHE_SIZE, 0);
457
458 if (ret == PAGE_CACHE_SIZE) {
459 nr_pages++;
460 page_cache_release(page);
461 } else {
462 unlock_extent(tree, last_offset, end, GFP_NOFS);
463 unlock_page(page);
464 page_cache_release(page);
465 break;
466 }
467next:
468 last_offset += PAGE_CACHE_SIZE;
469 }
470 if (pagevec_count(&pvec))
471 __pagevec_lru_add(&pvec);
472 return 0;
473}
474
349/* 475/*
350 * for a compressed read, the bio we get passed has all the inode pages 476 * for a compressed read, the bio we get passed has all the inode pages
351 * in it. We don't actually do IO on those pages but allocate new ones 477 * in it. We don't actually do IO on those pages but allocate new ones
@@ -373,6 +499,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
373 struct block_device *bdev; 499 struct block_device *bdev;
374 struct bio *comp_bio; 500 struct bio *comp_bio;
375 u64 cur_disk_byte = (u64)bio->bi_sector << 9; 501 u64 cur_disk_byte = (u64)bio->bi_sector << 9;
502 u64 em_len;
376 struct extent_map *em; 503 struct extent_map *em;
377 int ret; 504 int ret;
378 505
@@ -393,6 +520,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
393 520
394 cb->start = em->start; 521 cb->start = em->start;
395 compressed_len = em->block_len; 522 compressed_len = em->block_len;
523 em_len = em->len;
396 free_extent_map(em); 524 free_extent_map(em);
397 525
398 cb->len = uncompressed_len; 526 cb->len = uncompressed_len;
@@ -411,6 +539,17 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
411 } 539 }
412 cb->nr_pages = nr_pages; 540 cb->nr_pages = nr_pages;
413 541
542 add_ra_bio_pages(inode, cb->start + em_len, cb);
543
544 if (!btrfs_test_opt(root, NODATASUM) &&
545 !btrfs_test_flag(inode, NODATASUM)) {
546 btrfs_lookup_bio_sums(root, inode, cb->orig_bio);
547 }
548
549 /* include any pages we added in add_ra-bio_pages */
550 uncompressed_len = bio->bi_vcnt * PAGE_CACHE_SIZE;
551 cb->len = uncompressed_len;
552
414 comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); 553 comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS);
415 comp_bio->bi_private = cb; 554 comp_bio->bi_private = cb;
416 comp_bio->bi_end_io = end_compressed_bio_read; 555 comp_bio->bi_end_io = end_compressed_bio_read;
@@ -442,9 +581,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
442 comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, 581 comp_bio = compressed_bio_alloc(bdev, cur_disk_byte,
443 GFP_NOFS); 582 GFP_NOFS);
444 atomic_inc(&cb->pending_bios); 583 atomic_inc(&cb->pending_bios);
445 bio->bi_private = cb; 584 comp_bio->bi_private = cb;
446 bio->bi_end_io = end_compressed_bio_write; 585 comp_bio->bi_end_io = end_compressed_bio_read;
447 bio_add_page(bio, page, PAGE_CACHE_SIZE, 0); 586
587 bio_add_page(comp_bio, page, PAGE_CACHE_SIZE, 0);
448 } 588 }
449 cur_disk_byte += PAGE_CACHE_SIZE; 589 cur_disk_byte += PAGE_CACHE_SIZE;
450 } 590 }