diff options
| -rw-r--r-- | fs/ext4/mballoc.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 6968c53e62ad..ef97f19c2f9d 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, | |||
| 627 | return block; | 627 | return block; |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | static inline void *mb_correct_addr_and_bit(int *bit, void *addr) | ||
| 631 | { | ||
| 630 | #if BITS_PER_LONG == 64 | 632 | #if BITS_PER_LONG == 64 |
| 631 | #define mb_correct_addr_and_bit(bit, addr) \ | 633 | *bit += ((unsigned long) addr & 7UL) << 3; |
| 632 | { \ | 634 | addr = (void *) ((unsigned long) addr & ~7UL); |
| 633 | bit += ((unsigned long) addr & 7UL) << 3; \ | ||
| 634 | addr = (void *) ((unsigned long) addr & ~7UL); \ | ||
| 635 | } | ||
| 636 | #elif BITS_PER_LONG == 32 | 635 | #elif BITS_PER_LONG == 32 |
| 637 | #define mb_correct_addr_and_bit(bit, addr) \ | 636 | *bit += ((unsigned long) addr & 3UL) << 3; |
| 638 | { \ | 637 | addr = (void *) ((unsigned long) addr & ~3UL); |
| 639 | bit += ((unsigned long) addr & 3UL) << 3; \ | ||
| 640 | addr = (void *) ((unsigned long) addr & ~3UL); \ | ||
| 641 | } | ||
| 642 | #else | 638 | #else |
| 643 | #error "how many bits you are?!" | 639 | #error "how many bits you are?!" |
| 644 | #endif | 640 | #endif |
| 641 | return addr; | ||
| 642 | } | ||
| 645 | 643 | ||
| 646 | static inline int mb_test_bit(int bit, void *addr) | 644 | static inline int mb_test_bit(int bit, void *addr) |
| 647 | { | 645 | { |
| @@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, void *addr) | |||
| 649 | * ext4_test_bit on architecture like powerpc | 647 | * ext4_test_bit on architecture like powerpc |
| 650 | * needs unsigned long aligned address | 648 | * needs unsigned long aligned address |
| 651 | */ | 649 | */ |
| 652 | mb_correct_addr_and_bit(bit, addr); | 650 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 653 | return ext4_test_bit(bit, addr); | 651 | return ext4_test_bit(bit, addr); |
| 654 | } | 652 | } |
| 655 | 653 | ||
| 656 | static inline void mb_set_bit(int bit, void *addr) | 654 | static inline void mb_set_bit(int bit, void *addr) |
| 657 | { | 655 | { |
| 658 | mb_correct_addr_and_bit(bit, addr); | 656 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 659 | ext4_set_bit(bit, addr); | 657 | ext4_set_bit(bit, addr); |
| 660 | } | 658 | } |
| 661 | 659 | ||
| 662 | static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) | 660 | static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) |
| 663 | { | 661 | { |
| 664 | mb_correct_addr_and_bit(bit, addr); | 662 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 665 | ext4_set_bit_atomic(lock, bit, addr); | 663 | ext4_set_bit_atomic(lock, bit, addr); |
| 666 | } | 664 | } |
| 667 | 665 | ||
| 668 | static inline void mb_clear_bit(int bit, void *addr) | 666 | static inline void mb_clear_bit(int bit, void *addr) |
| 669 | { | 667 | { |
| 670 | mb_correct_addr_and_bit(bit, addr); | 668 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 671 | ext4_clear_bit(bit, addr); | 669 | ext4_clear_bit(bit, addr); |
| 672 | } | 670 | } |
| 673 | 671 | ||
| 674 | static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) | 672 | static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) |
| 675 | { | 673 | { |
| 676 | mb_correct_addr_and_bit(bit, addr); | 674 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 677 | ext4_clear_bit_atomic(lock, bit, addr); | 675 | ext4_clear_bit_atomic(lock, bit, addr); |
| 678 | } | 676 | } |
| 679 | 677 | ||
| 678 | static inline int mb_find_next_zero_bit(void *addr, int max, int start) | ||
| 679 | { | ||
| 680 | int fix = 0; | ||
| 681 | addr = mb_correct_addr_and_bit(&fix, addr); | ||
| 682 | max += fix; | ||
| 683 | start += fix; | ||
| 684 | |||
| 685 | return ext4_find_next_zero_bit(addr, max, start) - fix; | ||
| 686 | } | ||
| 687 | |||
| 688 | static inline int mb_find_next_bit(void *addr, int max, int start) | ||
| 689 | { | ||
| 690 | int fix = 0; | ||
| 691 | addr = mb_correct_addr_and_bit(&fix, addr); | ||
| 692 | max += fix; | ||
| 693 | start += fix; | ||
| 694 | |||
| 695 | return ext4_find_next_bit(addr, max, start) - fix; | ||
| 696 | } | ||
| 697 | |||
| 680 | static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) | 698 | static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) |
| 681 | { | 699 | { |
| 682 | char *bb; | 700 | char *bb; |
| @@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 946 | 964 | ||
| 947 | /* initialize buddy from bitmap which is aggregation | 965 | /* initialize buddy from bitmap which is aggregation |
| 948 | * of on-disk bitmap and preallocations */ | 966 | * of on-disk bitmap and preallocations */ |
| 949 | i = ext4_find_next_zero_bit(bitmap, max, 0); | 967 | i = mb_find_next_zero_bit(bitmap, max, 0); |
| 950 | grp->bb_first_free = i; | 968 | grp->bb_first_free = i; |
| 951 | while (i < max) { | 969 | while (i < max) { |
| 952 | fragments++; | 970 | fragments++; |
| 953 | first = i; | 971 | first = i; |
| 954 | i = ext4_find_next_bit(bitmap, max, i); | 972 | i = mb_find_next_bit(bitmap, max, i); |
| 955 | len = i - first; | 973 | len = i - first; |
| 956 | free += len; | 974 | free += len; |
| 957 | if (len > 1) | 975 | if (len > 1) |
| @@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 959 | else | 977 | else |
| 960 | grp->bb_counters[0]++; | 978 | grp->bb_counters[0]++; |
| 961 | if (i < max) | 979 | if (i < max) |
| 962 | i = ext4_find_next_zero_bit(bitmap, max, i); | 980 | i = mb_find_next_zero_bit(bitmap, max, i); |
| 963 | } | 981 | } |
| 964 | grp->bb_fragments = fragments; | 982 | grp->bb_fragments = fragments; |
| 965 | 983 | ||
| @@ -1782,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | |||
| 1782 | buddy = mb_find_buddy(e4b, i, &max); | 1800 | buddy = mb_find_buddy(e4b, i, &max); |
| 1783 | BUG_ON(buddy == NULL); | 1801 | BUG_ON(buddy == NULL); |
| 1784 | 1802 | ||
| 1785 | k = ext4_find_next_zero_bit(buddy, max, 0); | 1803 | k = mb_find_next_zero_bit(buddy, max, 0); |
| 1786 | BUG_ON(k >= max); | 1804 | BUG_ON(k >= max); |
| 1787 | 1805 | ||
| 1788 | ac->ac_found++; | 1806 | ac->ac_found++; |
| @@ -1822,7 +1840,7 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
| 1822 | i = e4b->bd_info->bb_first_free; | 1840 | i = e4b->bd_info->bb_first_free; |
| 1823 | 1841 | ||
| 1824 | while (free && ac->ac_status == AC_STATUS_CONTINUE) { | 1842 | while (free && ac->ac_status == AC_STATUS_CONTINUE) { |
| 1825 | i = ext4_find_next_zero_bit(bitmap, | 1843 | i = mb_find_next_zero_bit(bitmap, |
| 1826 | EXT4_BLOCKS_PER_GROUP(sb), i); | 1844 | EXT4_BLOCKS_PER_GROUP(sb), i); |
| 1827 | if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { | 1845 | if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { |
| 1828 | /* | 1846 | /* |
| @@ -3750,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, | |||
| 3750 | } | 3768 | } |
| 3751 | 3769 | ||
| 3752 | while (bit < end) { | 3770 | while (bit < end) { |
| 3753 | bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit); | 3771 | bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit); |
| 3754 | if (bit >= end) | 3772 | if (bit >= end) |
| 3755 | break; | 3773 | break; |
| 3756 | next = ext4_find_next_bit(bitmap_bh->b_data, end, bit); | 3774 | next = mb_find_next_bit(bitmap_bh->b_data, end, bit); |
| 3757 | if (next > end) | 3775 | if (next > end) |
| 3758 | next = end; | 3776 | next = end; |
| 3759 | start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + | 3777 | start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + |
