mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 15:14:18 +08:00
ext4: warn when discard request fails other than EOPNOTSUPP
We should warn user then the discard request fails. However we need to exclude -EOPNOTSUPP case since parts of the device might not support it while other parts can. So print the kernel warning when the error != -EOPNOTSUPP is returned from ext4_issue_discard(). We should also handle error cases in batched discard, again excluding EOPNOTSUPP. Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Signed-off-by: Lukas Czerner <lczerner@redhat.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
79add3a3f7
commit
d71c1ae23a
@ -2607,9 +2607,17 @@ static void ext4_free_data_callback(struct super_block *sb,
|
|||||||
mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
|
mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
|
||||||
entry->efd_count, entry->efd_group, entry);
|
entry->efd_count, entry->efd_group, entry);
|
||||||
|
|
||||||
if (test_opt(sb, DISCARD))
|
if (test_opt(sb, DISCARD)) {
|
||||||
ext4_issue_discard(sb, entry->efd_group,
|
err = ext4_issue_discard(sb, entry->efd_group,
|
||||||
entry->efd_start_cluster, entry->efd_count);
|
entry->efd_start_cluster,
|
||||||
|
entry->efd_count);
|
||||||
|
if (err && err != -EOPNOTSUPP)
|
||||||
|
ext4_msg(sb, KERN_WARNING, "discard request in"
|
||||||
|
" group:%d block:%d count:%d failed"
|
||||||
|
" with %d", entry->efd_group,
|
||||||
|
entry->efd_start_cluster,
|
||||||
|
entry->efd_count, err);
|
||||||
|
}
|
||||||
|
|
||||||
err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
|
err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
|
||||||
/* we expect to find existing buddy because it's pinned */
|
/* we expect to find existing buddy because it's pinned */
|
||||||
@ -4659,8 +4667,16 @@ do_more:
|
|||||||
* with group lock held. generate_buddy look at
|
* with group lock held. generate_buddy look at
|
||||||
* them with group lock_held
|
* them with group lock_held
|
||||||
*/
|
*/
|
||||||
if (test_opt(sb, DISCARD))
|
if (test_opt(sb, DISCARD)) {
|
||||||
ext4_issue_discard(sb, block_group, bit, count);
|
err = ext4_issue_discard(sb, block_group, bit, count);
|
||||||
|
if (err && err != -EOPNOTSUPP)
|
||||||
|
ext4_msg(sb, KERN_WARNING, "discard request in"
|
||||||
|
" group:%d block:%d count:%lu failed"
|
||||||
|
" with %d", block_group, bit, count,
|
||||||
|
err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ext4_lock_group(sb, block_group);
|
ext4_lock_group(sb, block_group);
|
||||||
mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
|
mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
|
||||||
mb_free_blocks(inode, &e4b, bit, count_clusters);
|
mb_free_blocks(inode, &e4b, bit, count_clusters);
|
||||||
@ -4854,10 +4870,11 @@ error_return:
|
|||||||
* one will allocate those blocks, mark it as used in buddy bitmap. This must
|
* one will allocate those blocks, mark it as used in buddy bitmap. This must
|
||||||
* be called with under the group lock.
|
* be called with under the group lock.
|
||||||
*/
|
*/
|
||||||
static void ext4_trim_extent(struct super_block *sb, int start, int count,
|
static int ext4_trim_extent(struct super_block *sb, int start, int count,
|
||||||
ext4_group_t group, struct ext4_buddy *e4b)
|
ext4_group_t group, struct ext4_buddy *e4b)
|
||||||
{
|
{
|
||||||
struct ext4_free_extent ex;
|
struct ext4_free_extent ex;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
trace_ext4_trim_extent(sb, group, start, count);
|
trace_ext4_trim_extent(sb, group, start, count);
|
||||||
|
|
||||||
@ -4873,9 +4890,10 @@ static void ext4_trim_extent(struct super_block *sb, int start, int count,
|
|||||||
*/
|
*/
|
||||||
mb_mark_used(e4b, &ex);
|
mb_mark_used(e4b, &ex);
|
||||||
ext4_unlock_group(sb, group);
|
ext4_unlock_group(sb, group);
|
||||||
ext4_issue_discard(sb, group, start, count);
|
ret = ext4_issue_discard(sb, group, start, count);
|
||||||
ext4_lock_group(sb, group);
|
ext4_lock_group(sb, group);
|
||||||
mb_free_blocks(NULL, e4b, start, ex.fe_len);
|
mb_free_blocks(NULL, e4b, start, ex.fe_len);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4904,7 +4922,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
|
|||||||
void *bitmap;
|
void *bitmap;
|
||||||
ext4_grpblk_t next, count = 0, free_count = 0;
|
ext4_grpblk_t next, count = 0, free_count = 0;
|
||||||
struct ext4_buddy e4b;
|
struct ext4_buddy e4b;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
trace_ext4_trim_all_free(sb, group, start, max);
|
trace_ext4_trim_all_free(sb, group, start, max);
|
||||||
|
|
||||||
@ -4931,8 +4949,11 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
|
|||||||
next = mb_find_next_bit(bitmap, max + 1, start);
|
next = mb_find_next_bit(bitmap, max + 1, start);
|
||||||
|
|
||||||
if ((next - start) >= minblocks) {
|
if ((next - start) >= minblocks) {
|
||||||
ext4_trim_extent(sb, start,
|
ret = ext4_trim_extent(sb, start,
|
||||||
next - start, group, &e4b);
|
next - start, group, &e4b);
|
||||||
|
if (ret && ret != -EOPNOTSUPP)
|
||||||
|
break;
|
||||||
|
ret = 0;
|
||||||
count += next - start;
|
count += next - start;
|
||||||
}
|
}
|
||||||
free_count += next - start;
|
free_count += next - start;
|
||||||
@ -4953,8 +4974,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
|
ret = count;
|
||||||
EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
|
EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
ext4_unlock_group(sb, group);
|
ext4_unlock_group(sb, group);
|
||||||
ext4_mb_unload_buddy(&e4b);
|
ext4_mb_unload_buddy(&e4b);
|
||||||
@ -4962,7 +4985,7 @@ out:
|
|||||||
ext4_debug("trimmed %d blocks in the group %d\n",
|
ext4_debug("trimmed %d blocks in the group %d\n",
|
||||||
count, group);
|
count, group);
|
||||||
|
|
||||||
return count;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user