diff options
-rw-r--r-- | fs/ext4/mballoc.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 254f1f9fc4eb..38a11bf79329 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -4810,19 +4810,25 @@ static void ext4_trim_extent(struct super_block *sb, int start, int count, | |||
4810 | * the group buddy bitmap. This is done until whole group is scanned. | 4810 | * the group buddy bitmap. This is done until whole group is scanned. |
4811 | */ | 4811 | */ |
4812 | static ext4_grpblk_t | 4812 | static ext4_grpblk_t |
4813 | ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | 4813 | ext4_trim_all_free(struct super_block *sb, ext4_group_t group, |
4814 | ext4_grpblk_t start, ext4_grpblk_t max, ext4_grpblk_t minblocks) | 4814 | ext4_grpblk_t start, ext4_grpblk_t max, |
4815 | ext4_grpblk_t minblocks) | ||
4815 | { | 4816 | { |
4816 | void *bitmap; | 4817 | void *bitmap; |
4817 | ext4_grpblk_t next, count = 0; | 4818 | ext4_grpblk_t next, count = 0; |
4818 | ext4_group_t group; | 4819 | struct ext4_buddy e4b; |
4820 | int ret; | ||
4819 | 4821 | ||
4820 | BUG_ON(e4b == NULL); | 4822 | ret = ext4_mb_load_buddy(sb, group, &e4b); |
4823 | if (ret) { | ||
4824 | ext4_error(sb, "Error in loading buddy " | ||
4825 | "information for %u", group); | ||
4826 | return ret; | ||
4827 | } | ||
4821 | 4828 | ||
4822 | bitmap = e4b->bd_bitmap; | 4829 | bitmap = e4b.bd_bitmap; |
4823 | group = e4b->bd_group; | 4830 | start = (e4b.bd_info->bb_first_free > start) ? |
4824 | start = (e4b->bd_info->bb_first_free > start) ? | 4831 | e4b.bd_info->bb_first_free : start; |
4825 | e4b->bd_info->bb_first_free : start; | ||
4826 | ext4_lock_group(sb, group); | 4832 | ext4_lock_group(sb, group); |
4827 | 4833 | ||
4828 | while (start < max) { | 4834 | while (start < max) { |
@@ -4833,7 +4839,7 @@ ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | |||
4833 | 4839 | ||
4834 | if ((next - start) >= minblocks) { | 4840 | if ((next - start) >= minblocks) { |
4835 | ext4_trim_extent(sb, start, | 4841 | ext4_trim_extent(sb, start, |
4836 | next - start, group, e4b); | 4842 | next - start, group, &e4b); |
4837 | count += next - start; | 4843 | count += next - start; |
4838 | } | 4844 | } |
4839 | start = next + 1; | 4845 | start = next + 1; |
@@ -4849,10 +4855,11 @@ ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | |||
4849 | ext4_lock_group(sb, group); | 4855 | ext4_lock_group(sb, group); |
4850 | } | 4856 | } |
4851 | 4857 | ||
4852 | if ((e4b->bd_info->bb_free - count) < minblocks) | 4858 | if ((e4b.bd_info->bb_free - count) < minblocks) |
4853 | break; | 4859 | break; |
4854 | } | 4860 | } |
4855 | ext4_unlock_group(sb, group); | 4861 | ext4_unlock_group(sb, group); |
4862 | ext4_mb_unload_buddy(&e4b); | ||
4856 | 4863 | ||
4857 | ext4_debug("trimmed %d blocks in the group %d\n", | 4864 | ext4_debug("trimmed %d blocks in the group %d\n", |
4858 | count, group); | 4865 | count, group); |
@@ -4874,11 +4881,11 @@ ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | |||
4874 | */ | 4881 | */ |
4875 | int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | 4882 | int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) |
4876 | { | 4883 | { |
4877 | struct ext4_buddy e4b; | 4884 | struct ext4_group_info *grp; |
4878 | ext4_group_t first_group, last_group; | 4885 | ext4_group_t first_group, last_group; |
4879 | ext4_group_t group, ngroups = ext4_get_groups_count(sb); | 4886 | ext4_group_t group, ngroups = ext4_get_groups_count(sb); |
4880 | ext4_grpblk_t cnt = 0, first_block, last_block; | 4887 | ext4_grpblk_t cnt = 0, first_block, last_block; |
4881 | uint64_t start, len, minlen, trimmed; | 4888 | uint64_t start, len, minlen, trimmed = 0; |
4882 | ext4_fsblk_t first_data_blk = | 4889 | ext4_fsblk_t first_data_blk = |
4883 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); | 4890 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); |
4884 | int ret = 0; | 4891 | int ret = 0; |
@@ -4886,7 +4893,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
4886 | start = range->start >> sb->s_blocksize_bits; | 4893 | start = range->start >> sb->s_blocksize_bits; |
4887 | len = range->len >> sb->s_blocksize_bits; | 4894 | len = range->len >> sb->s_blocksize_bits; |
4888 | minlen = range->minlen >> sb->s_blocksize_bits; | 4895 | minlen = range->minlen >> sb->s_blocksize_bits; |
4889 | trimmed = 0; | ||
4890 | 4896 | ||
4891 | if (unlikely(minlen > EXT4_BLOCKS_PER_GROUP(sb))) | 4897 | if (unlikely(minlen > EXT4_BLOCKS_PER_GROUP(sb))) |
4892 | return -EINVAL; | 4898 | return -EINVAL; |
@@ -4907,11 +4913,12 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
4907 | return -EINVAL; | 4913 | return -EINVAL; |
4908 | 4914 | ||
4909 | for (group = first_group; group <= last_group; group++) { | 4915 | for (group = first_group; group <= last_group; group++) { |
4910 | ret = ext4_mb_load_buddy(sb, group, &e4b); | 4916 | grp = ext4_get_group_info(sb, group); |
4911 | if (ret) { | 4917 | /* We only do this if the grp has never been initialized */ |
4912 | ext4_error(sb, "Error in loading buddy " | 4918 | if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) { |
4913 | "information for %u", group); | 4919 | ret = ext4_mb_init_group(sb, group); |
4914 | break; | 4920 | if (ret) |
4921 | break; | ||
4915 | } | 4922 | } |
4916 | 4923 | ||
4917 | /* | 4924 | /* |
@@ -4924,16 +4931,14 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
4924 | last_block = first_block + len; | 4931 | last_block = first_block + len; |
4925 | len -= last_block - first_block; | 4932 | len -= last_block - first_block; |
4926 | 4933 | ||
4927 | if (e4b.bd_info->bb_free >= minlen) { | 4934 | if (grp->bb_free >= minlen) { |
4928 | cnt = ext4_trim_all_free(sb, &e4b, first_block, | 4935 | cnt = ext4_trim_all_free(sb, group, first_block, |
4929 | last_block, minlen); | 4936 | last_block, minlen); |
4930 | if (cnt < 0) { | 4937 | if (cnt < 0) { |
4931 | ret = cnt; | 4938 | ret = cnt; |
4932 | ext4_mb_unload_buddy(&e4b); | ||
4933 | break; | 4939 | break; |
4934 | } | 4940 | } |
4935 | } | 4941 | } |
4936 | ext4_mb_unload_buddy(&e4b); | ||
4937 | trimmed += cnt; | 4942 | trimmed += cnt; |
4938 | first_block = 0; | 4943 | first_block = 0; |
4939 | } | 4944 | } |