diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/btrfs/compression.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/btrfs/compression.c')
-rw-r--r-- | fs/btrfs/compression.c | 73 |
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 { | |||
85 | static inline int compressed_bio_size(struct btrfs_root *root, | 85 | static 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 | */ |
229 | static noinline void end_compressed_writeback(struct inode *inode, u64 start, | 228 | static 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 | ||
722 | fail2: | 711 | fail2: |
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); |
729 | fail1: | 716 | fail1: |
@@ -744,7 +731,7 @@ struct btrfs_compress_op *btrfs_compress_op[] = { | |||
744 | &btrfs_lzo_compress, | 731 | &btrfs_lzo_compress, |
745 | }; | 732 | }; |
746 | 733 | ||
747 | void __init btrfs_init_compress(void) | 734 | int __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); |
829 | wake: | 817 | wake: |
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; |