aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/mballoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r--fs/ext4/mballoc.c80
1 files changed, 56 insertions, 24 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index dd0fcfcb35ce..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
630static 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
646static inline int mb_test_bit(int bit, void *addr) 644static 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
656static inline void mb_set_bit(int bit, void *addr) 654static 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
662static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) 660static 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
668static inline void mb_clear_bit(int bit, void *addr) 666static 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
674static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) 672static 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
678static 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
688static 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
680static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) 698static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
681{ 699{
682 char *bb; 700 char *bb;
@@ -906,7 +924,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
906 unsigned short chunk; 924 unsigned short chunk;
907 unsigned short border; 925 unsigned short border;
908 926
909 BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); 927 BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb));
910 928
911 border = 2 << sb->s_blocksize_bits; 929 border = 2 << sb->s_blocksize_bits;
912 930
@@ -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
@@ -967,6 +985,10 @@ static void ext4_mb_generate_buddy(struct super_block *sb,
967 ext4_error(sb, __FUNCTION__, 985 ext4_error(sb, __FUNCTION__,
968 "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", 986 "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
969 group, free, grp->bb_free); 987 group, free, grp->bb_free);
988 /*
989 * If we intent to continue, we consider group descritor
990 * corrupt and update bb_free using bitmap value
991 */
970 grp->bb_free = free; 992 grp->bb_free = free;
971 } 993 }
972 994
@@ -1778,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
1778 buddy = mb_find_buddy(e4b, i, &max); 1800 buddy = mb_find_buddy(e4b, i, &max);
1779 BUG_ON(buddy == NULL); 1801 BUG_ON(buddy == NULL);
1780 1802
1781 k = ext4_find_next_zero_bit(buddy, max, 0); 1803 k = mb_find_next_zero_bit(buddy, max, 0);
1782 BUG_ON(k >= max); 1804 BUG_ON(k >= max);
1783 1805
1784 ac->ac_found++; 1806 ac->ac_found++;
@@ -1818,11 +1840,11 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
1818 i = e4b->bd_info->bb_first_free; 1840 i = e4b->bd_info->bb_first_free;
1819 1841
1820 while (free && ac->ac_status == AC_STATUS_CONTINUE) { 1842 while (free && ac->ac_status == AC_STATUS_CONTINUE) {
1821 i = ext4_find_next_zero_bit(bitmap, 1843 i = mb_find_next_zero_bit(bitmap,
1822 EXT4_BLOCKS_PER_GROUP(sb), i); 1844 EXT4_BLOCKS_PER_GROUP(sb), i);
1823 if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { 1845 if (i >= EXT4_BLOCKS_PER_GROUP(sb)) {
1824 /* 1846 /*
1825 * IF we corrupt the bitmap we won't find any 1847 * IF we have corrupt bitmap, we won't find any
1826 * free blocks even though group info says we 1848 * free blocks even though group info says we
1827 * we have free blocks 1849 * we have free blocks
1828 */ 1850 */
@@ -1838,6 +1860,12 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
1838 ext4_error(sb, __FUNCTION__, "%d free blocks as per " 1860 ext4_error(sb, __FUNCTION__, "%d free blocks as per "
1839 "group info. But got %d blocks\n", 1861 "group info. But got %d blocks\n",
1840 free, ex.fe_len); 1862 free, ex.fe_len);
1863 /*
1864 * The number of free blocks differs. This mostly
1865 * indicate that the bitmap is corrupt. So exit
1866 * without claiming the space.
1867 */
1868 break;
1841 } 1869 }
1842 1870
1843 ext4_mb_measure_extent(ac, &ex, e4b); 1871 ext4_mb_measure_extent(ac, &ex, e4b);
@@ -3740,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b,
3740 } 3768 }
3741 3769
3742 while (bit < end) { 3770 while (bit < end) {
3743 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);
3744 if (bit >= end) 3772 if (bit >= end)
3745 break; 3773 break;
3746 next = ext4_find_next_bit(bitmap_bh->b_data, end, bit); 3774 next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
3747 if (next > end) 3775 if (next > end)
3748 next = end; 3776 next = end;
3749 start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + 3777 start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
@@ -3771,6 +3799,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b,
3771 (unsigned long) pa->pa_len); 3799 (unsigned long) pa->pa_len);
3772 ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n", 3800 ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n",
3773 free, pa->pa_free); 3801 free, pa->pa_free);
3802 /*
3803 * pa is already deleted so we use the value obtained
3804 * from the bitmap and continue.
3805 */
3774 } 3806 }
3775 atomic_add(free, &sbi->s_mb_discarded); 3807 atomic_add(free, &sbi->s_mb_discarded);
3776 if (ac) 3808 if (ac)