diff options
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 054cfdd007d6..db8243627b08 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -1542,10 +1542,11 @@ static int mb_find_extent(struct ext4_buddy *e4b, int block, | |||
1542 | if (ex->fe_start + ex->fe_len > EXT4_CLUSTERS_PER_GROUP(e4b->bd_sb)) { | 1542 | if (ex->fe_start + ex->fe_len > EXT4_CLUSTERS_PER_GROUP(e4b->bd_sb)) { |
1543 | /* Should never happen! (but apparently sometimes does?!?) */ | 1543 | /* Should never happen! (but apparently sometimes does?!?) */ |
1544 | WARN_ON(1); | 1544 | WARN_ON(1); |
1545 | ext4_error(e4b->bd_sb, "corruption or bug in mb_find_extent " | 1545 | ext4_grp_locked_error(e4b->bd_sb, e4b->bd_group, 0, 0, |
1546 | "block=%d, order=%d needed=%d ex=%u/%d/%d@%u", | 1546 | "corruption or bug in mb_find_extent " |
1547 | block, order, needed, ex->fe_group, ex->fe_start, | 1547 | "block=%d, order=%d needed=%d ex=%u/%d/%d@%u", |
1548 | ex->fe_len, ex->fe_logical); | 1548 | block, order, needed, ex->fe_group, ex->fe_start, |
1549 | ex->fe_len, ex->fe_logical); | ||
1549 | ex->fe_len = 0; | 1550 | ex->fe_len = 0; |
1550 | ex->fe_start = 0; | 1551 | ex->fe_start = 0; |
1551 | ex->fe_group = 0; | 1552 | ex->fe_group = 0; |
@@ -2990,7 +2991,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2990 | block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); | 2991 | block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex); |
2991 | 2992 | ||
2992 | len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len); | 2993 | len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len); |
2993 | if (!ext4_data_block_valid(sbi, block, len)) { | 2994 | if (!ext4_inode_block_valid(ac->ac_inode, block, len)) { |
2994 | ext4_error(sb, "Allocating blocks %llu-%llu which overlap " | 2995 | ext4_error(sb, "Allocating blocks %llu-%llu which overlap " |
2995 | "fs metadata", block, block+len); | 2996 | "fs metadata", block, block+len); |
2996 | /* File system mounted not to panic on error | 2997 | /* File system mounted not to panic on error |
@@ -4690,6 +4691,7 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, | |||
4690 | ext4_group_first_block_no(sb, group) + | 4691 | ext4_group_first_block_no(sb, group) + |
4691 | EXT4_C2B(sbi, cluster), | 4692 | EXT4_C2B(sbi, cluster), |
4692 | "Block already on to-be-freed list"); | 4693 | "Block already on to-be-freed list"); |
4694 | kmem_cache_free(ext4_free_data_cachep, new_entry); | ||
4693 | return 0; | 4695 | return 0; |
4694 | } | 4696 | } |
4695 | } | 4697 | } |
@@ -4754,7 +4756,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
4754 | 4756 | ||
4755 | sbi = EXT4_SB(sb); | 4757 | sbi = EXT4_SB(sb); |
4756 | if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && | 4758 | if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) && |
4757 | !ext4_data_block_valid(sbi, block, count)) { | 4759 | !ext4_inode_block_valid(inode, block, count)) { |
4758 | ext4_error(sb, "Freeing blocks not in datazone - " | 4760 | ext4_error(sb, "Freeing blocks not in datazone - " |
4759 | "block = %llu, count = %lu", block, count); | 4761 | "block = %llu, count = %lu", block, count); |
4760 | goto error_return; | 4762 | goto error_return; |
@@ -5258,6 +5260,7 @@ out: | |||
5258 | */ | 5260 | */ |
5259 | int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | 5261 | int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) |
5260 | { | 5262 | { |
5263 | struct request_queue *q = bdev_get_queue(sb->s_bdev); | ||
5261 | struct ext4_group_info *grp; | 5264 | struct ext4_group_info *grp; |
5262 | ext4_group_t group, first_group, last_group; | 5265 | ext4_group_t group, first_group, last_group; |
5263 | ext4_grpblk_t cnt = 0, first_cluster, last_cluster; | 5266 | ext4_grpblk_t cnt = 0, first_cluster, last_cluster; |
@@ -5276,6 +5279,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) | |||
5276 | start >= max_blks || | 5279 | start >= max_blks || |
5277 | range->len < sb->s_blocksize) | 5280 | range->len < sb->s_blocksize) |
5278 | return -EINVAL; | 5281 | return -EINVAL; |
5282 | /* No point to try to trim less than discard granularity */ | ||
5283 | if (range->minlen < q->limits.discard_granularity) { | ||
5284 | minlen = EXT4_NUM_B2C(EXT4_SB(sb), | ||
5285 | q->limits.discard_granularity >> sb->s_blocksize_bits); | ||
5286 | if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) | ||
5287 | goto out; | ||
5288 | } | ||
5279 | if (end >= max_blks) | 5289 | if (end >= max_blks) |
5280 | end = max_blks - 1; | 5290 | end = max_blks - 1; |
5281 | if (end <= first_data_blk) | 5291 | if (end <= first_data_blk) |