diff options
author | Theodore Ts'o <tytso@mit.edu> | 2011-04-30 13:47:24 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-04-30 13:47:24 -0400 |
commit | d9f34504e6952e909a6932c5b2d1857716606380 (patch) | |
tree | ae81b1df1d4d30606acea4e00fbca19307be4f29 /fs/ext4/mballoc.c | |
parent | 39db00f1c45e770856264bdb3ceca27980b01965 (diff) |
ext4: ignore errors when issuing discards
This is an effective revert of commit a30eec2a8: "ext4: stop issuing
discards if not supported by device". The problem is that there are
some devices that may return errors in response to a discard request
some times but not others. (One example would be a hybrid dm device
which concatenates an SSD and an HDD device).
By this logic, I also removed the error checking from ext4's FITRIM
code; so that an error from a discard will not stop the FITRIM from
trying to trim the rest of the file system.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r-- | fs/ext4/mballoc.c | 34 |
1 files changed, 9 insertions, 25 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 15bfa44abd29..730c1a72a959 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2661,7 +2661,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) | |||
2661 | struct super_block *sb = journal->j_private; | 2661 | struct super_block *sb = journal->j_private; |
2662 | struct ext4_buddy e4b; | 2662 | struct ext4_buddy e4b; |
2663 | struct ext4_group_info *db; | 2663 | struct ext4_group_info *db; |
2664 | int err, ret, count = 0, count2 = 0; | 2664 | int err, count = 0, count2 = 0; |
2665 | struct ext4_free_data *entry; | 2665 | struct ext4_free_data *entry; |
2666 | struct list_head *l, *ltmp; | 2666 | struct list_head *l, *ltmp; |
2667 | 2667 | ||
@@ -2671,15 +2671,9 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) | |||
2671 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", | 2671 | mb_debug(1, "gonna free %u blocks in group %u (0x%p):", |
2672 | entry->count, entry->group, entry); | 2672 | entry->count, entry->group, entry); |
2673 | 2673 | ||
2674 | if (test_opt(sb, DISCARD)) { | 2674 | if (test_opt(sb, DISCARD)) |
2675 | ret = ext4_issue_discard(sb, entry->group, | 2675 | ext4_issue_discard(sb, entry->group, |
2676 | entry->start_blk, entry->count); | 2676 | entry->start_blk, entry->count); |
2677 | if (unlikely(ret == -EOPNOTSUPP)) { | ||
2678 | ext4_warning(sb, "discard not supported, " | ||
2679 | "disabling"); | ||
2680 | clear_opt(sb, DISCARD); | ||
2681 | } | ||
2682 | } | ||
2683 | 2677 | ||
2684 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); | 2678 | err = ext4_mb_load_buddy(sb, entry->group, &e4b); |
2685 | /* we expect to find existing buddy because it's pinned */ | 2679 | /* we expect to find existing buddy because it's pinned */ |
@@ -4717,11 +4711,10 @@ error_return: | |||
4717 | * one will allocate those blocks, mark it as used in buddy bitmap. This must | 4711 | * one will allocate those blocks, mark it as used in buddy bitmap. This must |
4718 | * be called with under the group lock. | 4712 | * be called with under the group lock. |
4719 | */ | 4713 | */ |
4720 | static int ext4_trim_extent(struct super_block *sb, int start, int count, | 4714 | static void ext4_trim_extent(struct super_block *sb, int start, int count, |
4721 | ext4_group_t group, struct ext4_buddy *e4b) | 4715 | ext4_group_t group, struct ext4_buddy *e4b) |
4722 | { | 4716 | { |
4723 | struct ext4_free_extent ex; | 4717 | struct ext4_free_extent ex; |
4724 | int ret = 0; | ||
4725 | 4718 | ||
4726 | assert_spin_locked(ext4_group_lock_ptr(sb, group)); | 4719 | assert_spin_locked(ext4_group_lock_ptr(sb, group)); |
4727 | 4720 | ||
@@ -4735,12 +4728,9 @@ static int ext4_trim_extent(struct super_block *sb, int start, int count, | |||
4735 | */ | 4728 | */ |
4736 | mb_mark_used(e4b, &ex); | 4729 | mb_mark_used(e4b, &ex); |
4737 | ext4_unlock_group(sb, group); | 4730 | ext4_unlock_group(sb, group); |
4738 | 4731 | ext4_issue_discard(sb, group, start, count); | |
4739 | ret = ext4_issue_discard(sb, group, start, count); | ||
4740 | |||
4741 | ext4_lock_group(sb, group); | 4732 | ext4_lock_group(sb, group); |
4742 | mb_free_blocks(NULL, e4b, start, ex.fe_len); | 4733 | mb_free_blocks(NULL, e4b, start, ex.fe_len); |
4743 | return ret; | ||
4744 | } | 4734 | } |
4745 | 4735 | ||
4746 | /** | 4736 | /** |
@@ -4768,7 +4758,6 @@ ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | |||
4768 | void *bitmap; | 4758 | void *bitmap; |
4769 | ext4_grpblk_t next, count = 0; | 4759 | ext4_grpblk_t next, count = 0; |
4770 | ext4_group_t group; | 4760 | ext4_group_t group; |
4771 | int ret = 0; | ||
4772 | 4761 | ||
4773 | BUG_ON(e4b == NULL); | 4762 | BUG_ON(e4b == NULL); |
4774 | 4763 | ||
@@ -4785,10 +4774,8 @@ ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | |||
4785 | next = mb_find_next_bit(bitmap, max, start); | 4774 | next = mb_find_next_bit(bitmap, max, start); |
4786 | 4775 | ||
4787 | if ((next - start) >= minblocks) { | 4776 | if ((next - start) >= minblocks) { |
4788 | ret = ext4_trim_extent(sb, start, | 4777 | ext4_trim_extent(sb, start, |
4789 | next - start, group, e4b); | 4778 | next - start, group, e4b); |
4790 | if (ret < 0) | ||
4791 | break; | ||
4792 | count += next - start; | 4779 | count += next - start; |
4793 | } | 4780 | } |
4794 | start = next + 1; | 4781 | start = next + 1; |
@@ -4812,9 +4799,6 @@ ext4_trim_all_free(struct super_block *sb, struct ext4_buddy *e4b, | |||
4812 | ext4_debug("trimmed %d blocks in the group %d\n", | 4799 | ext4_debug("trimmed %d blocks in the group %d\n", |
4813 | count, group); | 4800 | count, group); |
4814 | 4801 | ||
4815 | if (ret < 0) | ||
4816 | count = ret; | ||
4817 | |||
4818 | return count; | 4802 | return count; |
4819 | } | 4803 | } |
4820 | 4804 | ||