Commit d71c1ae2 authored by Lukas Czerner's avatar Lukas Czerner Committed by Theodore Ts'o

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: default avatarCarlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: default avatarLukas Czerner <lczerner@redhat.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 79add3a3
...@@ -2607,9 +2607,17 @@ static void ext4_free_data_callback(struct super_block *sb, ...@@ -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 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, ...@@ -4659,8 +4667,16 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
* 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 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, ...@@ -4854,10 +4870,11 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
* 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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, ...@@ -4962,7 +4985,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
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;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment