aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/compression.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/btrfs/compression.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r--fs/btrfs/compression.c73
1 files changed, 30 insertions, 43 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 94ab2f80e7e..8ec5d86f173 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -85,8 +85,7 @@ struct compressed_bio {
85static inline int compressed_bio_size(struct btrfs_root *root, 85static inline int compressed_bio_size(struct btrfs_root *root,
86 unsigned long disk_size) 86 unsigned long disk_size)
87{ 87{
88 u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); 88 u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy);
89
90 return sizeof(struct compressed_bio) + 89 return sizeof(struct compressed_bio) +
91 ((disk_size + root->sectorsize - 1) / root->sectorsize) * 90 ((disk_size + root->sectorsize - 1) / root->sectorsize) *
92 csum_size; 91 csum_size;
@@ -120,10 +119,10 @@ static int check_compressed_csum(struct inode *inode,
120 page = cb->compressed_pages[i]; 119 page = cb->compressed_pages[i];
121 csum = ~(u32)0; 120 csum = ~(u32)0;
122 121
123 kaddr = kmap_atomic(page); 122 kaddr = kmap_atomic(page, KM_USER0);
124 csum = btrfs_csum_data(root, kaddr, csum, PAGE_CACHE_SIZE); 123 csum = btrfs_csum_data(root, kaddr, csum, PAGE_CACHE_SIZE);
125 btrfs_csum_final(csum, (char *)&csum); 124 btrfs_csum_final(csum, (char *)&csum);
126 kunmap_atomic(kaddr); 125 kunmap_atomic(kaddr, KM_USER0);
127 126
128 if (csum != *cb_sum) { 127 if (csum != *cb_sum) {
129 printk(KERN_INFO "btrfs csum failed ino %llu " 128 printk(KERN_INFO "btrfs csum failed ino %llu "
@@ -226,8 +225,8 @@ out:
226 * Clear the writeback bits on all of the file 225 * Clear the writeback bits on all of the file
227 * pages for a compressed write 226 * pages for a compressed write
228 */ 227 */
229static noinline void end_compressed_writeback(struct inode *inode, u64 start, 228static noinline int end_compressed_writeback(struct inode *inode, u64 start,
230 unsigned long ram_size) 229 unsigned long ram_size)
231{ 230{
232 unsigned long index = start >> PAGE_CACHE_SHIFT; 231 unsigned long index = start >> PAGE_CACHE_SHIFT;
233 unsigned long end_index = (start + ram_size - 1) >> PAGE_CACHE_SHIFT; 232 unsigned long end_index = (start + ram_size - 1) >> PAGE_CACHE_SHIFT;
@@ -253,6 +252,7 @@ static noinline void end_compressed_writeback(struct inode *inode, u64 start,
253 index += ret; 252 index += ret;
254 } 253 }
255 /* the inode may be gone now */ 254 /* the inode may be gone now */
255 return 0;
256} 256}
257 257
258/* 258/*
@@ -391,21 +391,20 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
391 */ 391 */
392 atomic_inc(&cb->pending_bios); 392 atomic_inc(&cb->pending_bios);
393 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); 393 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
394 BUG_ON(ret); /* -ENOMEM */ 394 BUG_ON(ret);
395 395
396 if (!skip_sum) { 396 if (!skip_sum) {
397 ret = btrfs_csum_one_bio(root, inode, bio, 397 ret = btrfs_csum_one_bio(root, inode, bio,
398 start, 1); 398 start, 1);
399 BUG_ON(ret); /* -ENOMEM */ 399 BUG_ON(ret);
400 } 400 }
401 401
402 ret = btrfs_map_bio(root, WRITE, bio, 0, 1); 402 ret = btrfs_map_bio(root, WRITE, bio, 0, 1);
403 BUG_ON(ret); /* -ENOMEM */ 403 BUG_ON(ret);
404 404
405 bio_put(bio); 405 bio_put(bio);
406 406
407 bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); 407 bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
408 BUG_ON(!bio);
409 bio->bi_private = cb; 408 bio->bi_private = cb;
410 bio->bi_end_io = end_compressed_bio_write; 409 bio->bi_end_io = end_compressed_bio_write;
411 bio_add_page(bio, page, PAGE_CACHE_SIZE, 0); 410 bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
@@ -421,15 +420,15 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
421 bio_get(bio); 420 bio_get(bio);
422 421
423 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); 422 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
424 BUG_ON(ret); /* -ENOMEM */ 423 BUG_ON(ret);
425 424
426 if (!skip_sum) { 425 if (!skip_sum) {
427 ret = btrfs_csum_one_bio(root, inode, bio, start, 1); 426 ret = btrfs_csum_one_bio(root, inode, bio, start, 1);
428 BUG_ON(ret); /* -ENOMEM */ 427 BUG_ON(ret);
429 } 428 }
430 429
431 ret = btrfs_map_bio(root, WRITE, bio, 0, 1); 430 ret = btrfs_map_bio(root, WRITE, bio, 0, 1);
432 BUG_ON(ret); /* -ENOMEM */ 431 BUG_ON(ret);
433 432
434 bio_put(bio); 433 bio_put(bio);
435 return 0; 434 return 0;
@@ -497,7 +496,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
497 * sure they map to this compressed extent on disk. 496 * sure they map to this compressed extent on disk.
498 */ 497 */
499 set_page_extent_mapped(page); 498 set_page_extent_mapped(page);
500 lock_extent(tree, last_offset, end); 499 lock_extent(tree, last_offset, end, GFP_NOFS);
501 read_lock(&em_tree->lock); 500 read_lock(&em_tree->lock);
502 em = lookup_extent_mapping(em_tree, last_offset, 501 em = lookup_extent_mapping(em_tree, last_offset,
503 PAGE_CACHE_SIZE); 502 PAGE_CACHE_SIZE);
@@ -507,7 +506,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
507 (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) || 506 (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) ||
508 (em->block_start >> 9) != cb->orig_bio->bi_sector) { 507 (em->block_start >> 9) != cb->orig_bio->bi_sector) {
509 free_extent_map(em); 508 free_extent_map(em);
510 unlock_extent(tree, last_offset, end); 509 unlock_extent(tree, last_offset, end, GFP_NOFS);
511 unlock_page(page); 510 unlock_page(page);
512 page_cache_release(page); 511 page_cache_release(page);
513 break; 512 break;
@@ -521,10 +520,10 @@ static noinline int add_ra_bio_pages(struct inode *inode,
521 if (zero_offset) { 520 if (zero_offset) {
522 int zeros; 521 int zeros;
523 zeros = PAGE_CACHE_SIZE - zero_offset; 522 zeros = PAGE_CACHE_SIZE - zero_offset;
524 userpage = kmap_atomic(page); 523 userpage = kmap_atomic(page, KM_USER0);
525 memset(userpage + zero_offset, 0, zeros); 524 memset(userpage + zero_offset, 0, zeros);
526 flush_dcache_page(page); 525 flush_dcache_page(page);
527 kunmap_atomic(userpage); 526 kunmap_atomic(userpage, KM_USER0);
528 } 527 }
529 } 528 }
530 529
@@ -535,7 +534,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
535 nr_pages++; 534 nr_pages++;
536 page_cache_release(page); 535 page_cache_release(page);
537 } else { 536 } else {
538 unlock_extent(tree, last_offset, end); 537 unlock_extent(tree, last_offset, end, GFP_NOFS);
539 unlock_page(page); 538 unlock_page(page);
540 page_cache_release(page); 539 page_cache_release(page);
541 break; 540 break;
@@ -577,7 +576,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
577 u64 em_start; 576 u64 em_start;
578 struct extent_map *em; 577 struct extent_map *em;
579 int ret = -ENOMEM; 578 int ret = -ENOMEM;
580 int faili = 0;
581 u32 *sums; 579 u32 *sums;
582 580
583 tree = &BTRFS_I(inode)->io_tree; 581 tree = &BTRFS_I(inode)->io_tree;
@@ -589,8 +587,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
589 page_offset(bio->bi_io_vec->bv_page), 587 page_offset(bio->bi_io_vec->bv_page),
590 PAGE_CACHE_SIZE); 588 PAGE_CACHE_SIZE);
591 read_unlock(&em_tree->lock); 589 read_unlock(&em_tree->lock);
592 if (!em)
593 return -EIO;
594 590
595 compressed_len = em->block_len; 591 compressed_len = em->block_len;
596 cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); 592 cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS);
@@ -627,13 +623,9 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
627 for (pg_index = 0; pg_index < nr_pages; pg_index++) { 623 for (pg_index = 0; pg_index < nr_pages; pg_index++) {
628 cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS | 624 cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS |
629 __GFP_HIGHMEM); 625 __GFP_HIGHMEM);
630 if (!cb->compressed_pages[pg_index]) { 626 if (!cb->compressed_pages[pg_index])
631 faili = pg_index - 1;
632 ret = -ENOMEM;
633 goto fail2; 627 goto fail2;
634 }
635 } 628 }
636 faili = nr_pages - 1;
637 cb->nr_pages = nr_pages; 629 cb->nr_pages = nr_pages;
638 630
639 add_ra_bio_pages(inode, em_start + em_len, cb); 631 add_ra_bio_pages(inode, em_start + em_len, cb);
@@ -667,7 +659,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
667 bio_get(comp_bio); 659 bio_get(comp_bio);
668 660
669 ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); 661 ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0);
670 BUG_ON(ret); /* -ENOMEM */ 662 BUG_ON(ret);
671 663
672 /* 664 /*
673 * inc the count before we submit the bio so 665 * inc the count before we submit the bio so
@@ -680,21 +672,19 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
680 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { 672 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
681 ret = btrfs_lookup_bio_sums(root, inode, 673 ret = btrfs_lookup_bio_sums(root, inode,
682 comp_bio, sums); 674 comp_bio, sums);
683 BUG_ON(ret); /* -ENOMEM */ 675 BUG_ON(ret);
684 } 676 }
685 sums += (comp_bio->bi_size + root->sectorsize - 1) / 677 sums += (comp_bio->bi_size + root->sectorsize - 1) /
686 root->sectorsize; 678 root->sectorsize;
687 679
688 ret = btrfs_map_bio(root, READ, comp_bio, 680 ret = btrfs_map_bio(root, READ, comp_bio,
689 mirror_num, 0); 681 mirror_num, 0);
690 if (ret) 682 BUG_ON(ret);
691 bio_endio(comp_bio, ret);
692 683
693 bio_put(comp_bio); 684 bio_put(comp_bio);
694 685
695 comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, 686 comp_bio = compressed_bio_alloc(bdev, cur_disk_byte,
696 GFP_NOFS); 687 GFP_NOFS);
697 BUG_ON(!comp_bio);
698 comp_bio->bi_private = cb; 688 comp_bio->bi_private = cb;
699 comp_bio->bi_end_io = end_compressed_bio_read; 689 comp_bio->bi_end_io = end_compressed_bio_read;
700 690
@@ -705,25 +695,22 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
705 bio_get(comp_bio); 695 bio_get(comp_bio);
706 696
707 ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); 697 ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0);
708 BUG_ON(ret); /* -ENOMEM */ 698 BUG_ON(ret);
709 699
710 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { 700 if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
711 ret = btrfs_lookup_bio_sums(root, inode, comp_bio, sums); 701 ret = btrfs_lookup_bio_sums(root, inode, comp_bio, sums);
712 BUG_ON(ret); /* -ENOMEM */ 702 BUG_ON(ret);
713 } 703 }
714 704
715 ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); 705 ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0);
716 if (ret) 706 BUG_ON(ret);
717 bio_endio(comp_bio, ret);
718 707
719 bio_put(comp_bio); 708 bio_put(comp_bio);
720 return 0; 709 return 0;
721 710
722fail2: 711fail2:
723 while (faili >= 0) { 712 for (pg_index = 0; pg_index < nr_pages; pg_index++)
724 __free_page(cb->compressed_pages[faili]); 713 free_page((unsigned long)cb->compressed_pages[pg_index]);
725 faili--;
726 }
727 714
728 kfree(cb->compressed_pages); 715 kfree(cb->compressed_pages);
729fail1: 716fail1:
@@ -744,7 +731,7 @@ struct btrfs_compress_op *btrfs_compress_op[] = {
744 &btrfs_lzo_compress, 731 &btrfs_lzo_compress,
745}; 732};
746 733
747void __init btrfs_init_compress(void) 734int __init btrfs_init_compress(void)
748{ 735{
749 int i; 736 int i;
750 737
@@ -754,6 +741,7 @@ void __init btrfs_init_compress(void)
754 atomic_set(&comp_alloc_workspace[i], 0); 741 atomic_set(&comp_alloc_workspace[i], 0);
755 init_waitqueue_head(&comp_workspace_wait[i]); 742 init_waitqueue_head(&comp_workspace_wait[i]);
756 } 743 }
744 return 0;
757} 745}
758 746
759/* 747/*
@@ -827,7 +815,6 @@ static void free_workspace(int type, struct list_head *workspace)
827 btrfs_compress_op[idx]->free_workspace(workspace); 815 btrfs_compress_op[idx]->free_workspace(workspace);
828 atomic_dec(alloc_workspace); 816 atomic_dec(alloc_workspace);
829wake: 817wake:
830 smp_mb();
831 if (waitqueue_active(workspace_wait)) 818 if (waitqueue_active(workspace_wait))
832 wake_up(workspace_wait); 819 wake_up(workspace_wait);
833} 820}
@@ -1003,9 +990,9 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
1003 bytes = min(PAGE_CACHE_SIZE - *pg_offset, 990 bytes = min(PAGE_CACHE_SIZE - *pg_offset,
1004 PAGE_CACHE_SIZE - buf_offset); 991 PAGE_CACHE_SIZE - buf_offset);
1005 bytes = min(bytes, working_bytes); 992 bytes = min(bytes, working_bytes);
1006 kaddr = kmap_atomic(page_out); 993 kaddr = kmap_atomic(page_out, KM_USER0);
1007 memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); 994 memcpy(kaddr + *pg_offset, buf + buf_offset, bytes);
1008 kunmap_atomic(kaddr); 995 kunmap_atomic(kaddr, KM_USER0);
1009 flush_dcache_page(page_out); 996 flush_dcache_page(page_out);
1010 997
1011 *pg_offset += bytes; 998 *pg_offset += bytes;