aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2012-11-08 14:04:52 -0500
committerTheodore Ts'o <tytso@mit.edu>2012-11-08 14:04:52 -0500
commitd71c1ae23aa3e7822715c63dc242de6d73002541 (patch)
tree61612cbcf814402d4e82f5f452d59e4d7547bd68 /fs
parent79add3a3f795e688e35d5e703d5a8cfa8ef923ac (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.c47
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 */
4857static void ext4_trim_extent(struct super_block *sb, int start, int count, 4873static 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 }
4958out: 4981out:
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/**