diff options
author | Lukas Czerner <lczerner@redhat.com> | 2012-11-08 14:04:52 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-11-08 14:04:52 -0500 |
commit | d71c1ae23aa3e7822715c63dc242de6d73002541 (patch) | |
tree | 61612cbcf814402d4e82f5f452d59e4d7547bd68 /fs | |
parent | 79add3a3f795e688e35d5e703d5a8cfa8ef923ac (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/mballoc.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 442caae80a98..1bf6fe785c4f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2607,9 +2607,17 @@ static void ext4_free_data_callback(struct super_block *sb, | |||
2607 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", | 2607 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", |
2608 | entry->efd_count, entry->efd_group, entry); | 2608 | entry->efd_count, entry->efd_group, entry); |
2609 | 2609 | ||
2610 | if (test_opt(sb, DISCARD)) | 2610 | if (test_opt(sb, DISCARD)) { |
2611 | ext4_issue_discard(sb, entry->efd_group, | 2611 | err = ext4_issue_discard(sb, entry->efd_group, |
2612 | entry->efd_start_cluster, entry->efd_count); | 2612 | entry->efd_start_cluster, |
2613 | entry->efd_count); | ||
2614 | if (err && err != -EOPNOTSUPP) | ||
2615 | ext4_msg(sb, KERN_WARNING, "discard request in" | ||
2616 | " group:%d block:%d count:%d failed" | ||
2617 | " with %d", entry->efd_group, | ||
2618 | entry->efd_start_cluster, | ||
2619 | entry->efd_count, err); | ||
2620 | } | ||
2613 | 2621 | ||
2614 | err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b); | 2622 | err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b); |
2615 | /* we expect to find existing buddy because it's pinned */ | 2623 | /* we expect to find existing buddy because it's pinned */ |
@@ -4659,8 +4667,16 @@ do_more: | |||
4659 | * with group lock held. generate_buddy look at | 4667 | * with group lock held. generate_buddy look at |
4660 | * them with group lock_held | 4668 | * them with group lock_held |
4661 | */ | 4669 | */ |
4662 | if (test_opt(sb, DISCARD)) | 4670 | if (test_opt(sb, DISCARD)) { |
4663 | ext4_issue_discard(sb, block_group, bit, count); | 4671 | err = ext4_issue_discard(sb, block_group, bit, count); |
4672 | if (err && err != -EOPNOTSUPP) | ||
4673 | ext4_msg(sb, KERN_WARNING, "discard request in" | ||
4674 | " group:%d block:%d count:%lu failed" | ||
4675 | " with %d", block_group, bit, count, | ||
4676 | err); | ||
4677 | } | ||
4678 | |||
4679 | |||
4664 | ext4_lock_group(sb, block_group); | 4680 | ext4_lock_group(sb, block_group); |
4665 | mb_clear_bits(bitmap_bh->b_data, bit, count_clusters); | 4681 | mb_clear_bits(bitmap_bh->b_data, bit, count_clusters); |
4666 | mb_free_blocks(inode, &e4b, bit, count_clusters); | 4682 | mb_free_blocks(inode, &e4b, bit, count_clusters); |
@@ -4854,10 +4870,11 @@ error_return: | |||
4854 | * one will allocate those blocks, mark it as used in buddy bitmap. This must | 4870 | * one will allocate those blocks, mark it as used in buddy bitmap. This must |
4855 | * be called with under the group lock. | 4871 | * be called with under the group lock. |
4856 | */ | 4872 | */ |
4857 | static void ext4_trim_extent(struct super_block *sb, int start, int count, | 4873 | static int ext4_trim_extent(struct super_block *sb, int start, int count, |
4858 | ext4_group_t group, struct ext4_buddy *e4b) | 4874 | ext4_group_t group, struct ext4_buddy *e4b) |
4859 | { | 4875 | { |
4860 | struct ext4_free_extent ex; | 4876 | struct ext4_free_extent ex; |
4877 | int ret = 0; | ||
4861 | 4878 | ||
4862 | trace_ext4_trim_extent(sb, group, start, count); | 4879 | trace_ext4_trim_extent(sb, group, start, count); |
4863 | 4880 | ||
@@ -4873,9 +4890,10 @@ static void ext4_trim_extent(struct super_block *sb, int start, int count, | |||
4873 | */ | 4890 | */ |
4874 | mb_mark_used(e4b, &ex); | 4891 | mb_mark_used(e4b, &ex); |
4875 | ext4_unlock_group(sb, group); | 4892 | ext4_unlock_group(sb, group); |
4876 | ext4_issue_discard(sb, group, start, count); | 4893 | ret = ext4_issue_discard(sb, group, start, count); |
4877 | ext4_lock_group(sb, group); | 4894 | ext4_lock_group(sb, group); |
4878 | mb_free_blocks(NULL, e4b, start, ex.fe_len); | 4895 | mb_free_blocks(NULL, e4b, start, ex.fe_len); |
4896 | return ret; | ||
4879 | } | 4897 | } |
4880 | 4898 | ||
4881 | /** | 4899 | /** |
@@ -4904,7 +4922,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, | |||
4904 | void *bitmap; | 4922 | void *bitmap; |
4905 | ext4_grpblk_t next, count = 0, free_count = 0; | 4923 | ext4_grpblk_t next, count = 0, free_count = 0; |
4906 | struct ext4_buddy e4b; | 4924 | struct ext4_buddy e4b; |
4907 | int ret; | 4925 | int ret = 0; |
4908 | 4926 | ||
4909 | trace_ext4_trim_all_free(sb, group, start, max); | 4927 | trace_ext4_trim_all_free(sb, group, start, max); |
4910 | 4928 | ||
@@ -4931,8 +4949,11 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, | |||
4931 | next = mb_find_next_bit(bitmap, max + 1, start); | 4949 | next = mb_find_next_bit(bitmap, max + 1, start); |
4932 | 4950 | ||
4933 | if ((next - start) >= minblocks) { | 4951 | if ((next - start) >= minblocks) { |
4934 | ext4_trim_extent(sb, start, | 4952 | ret = ext4_trim_extent(sb, start, |
4935 | next - start, group, &e4b); | 4953 | next - start, group, &e4b); |
4954 | if (ret && ret != -EOPNOTSUPP) | ||
4955 | break; | ||
4956 | ret = 0; | ||
4936 | count += next - start; | 4957 | count += next - start; |
4937 | } | 4958 | } |
4938 | free_count += next - start; | 4959 | free_count += next - start; |
@@ -4953,8 +4974,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, | |||
4953 | break; | 4974 | break; |
4954 | } | 4975 | } |
4955 | 4976 | ||
4956 | if (!ret) | 4977 | if (!ret) { |
4978 | ret = count; | ||
4957 | EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); | 4979 | EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); |
4980 | } | ||
4958 | out: | 4981 | out: |
4959 | ext4_unlock_group(sb, group); | 4982 | ext4_unlock_group(sb, group); |
4960 | ext4_mb_unload_buddy(&e4b); | 4983 | ext4_mb_unload_buddy(&e4b); |
@@ -4962,7 +4985,7 @@ out: | |||
4962 | ext4_debug("trimmed %d blocks in the group %d\n", | 4985 | ext4_debug("trimmed %d blocks in the group %d\n", |
4963 | count, group); | 4986 | count, group); |
4964 | 4987 | ||
4965 | return count; | 4988 | return ret; |
4966 | } | 4989 | } |
4967 | 4990 | ||
4968 | /** | 4991 | /** |