* [PATCH v3 2/3] ext4: Try to initialize all groups we can in case of failure on ppc64
2015-06-02 17:30 [PATCH v3 1/3] ext4: Verify block bitmap even after fresh initialization Lukas Czerner
@ 2015-06-02 17:30 ` Lukas Czerner
2015-06-08 15:39 ` Theodore Ts'o
2015-06-02 17:30 ` [PATCH v3 3/3] ext4: Return error code from ext4_mb_good_group() Lukas Czerner
1 sibling, 1 reply; 5+ messages in thread
From: Lukas Czerner @ 2015-06-02 17:30 UTC (permalink / raw)
To: linux-ext4; +Cc: Lukas Czerner
Currently on the machines with page size > block size when initializing
block group buddy cache we initialize it for all the block group bitmaps
in the page. However in the case of read error, checksum error, or if
a single bitmap is in any way corrupted we would fail to initialize all
of the bitmaps. This is problematic because we will not have access to
the other allocation groups even though those might be perfectly fine
and usable.
Fix this by reading all the bitmaps instead of error out on the first
problem and simply skip the bitmaps which were either not read properly,
or are not valid.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
---
v2: remove unnecessary else in condition
v3: nothing changed
fs/ext4/mballoc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 8d1e602..df02951 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -882,10 +882,8 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
/* wait for I/O completion */
for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
- if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i])) {
+ if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i]))
err = -EIO;
- goto out;
- }
}
first_block = page->index * blocks_per_page;
@@ -898,6 +896,11 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
/* skip initialized uptodate buddy */
continue;
+ if (!buffer_verified(bh[group - first_group]))
+ /* Skip faulty bitmaps */
+ continue;
+ err = 0;
+
/*
* data carry information regarding this
* particular group in the format specified
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 3/3] ext4: Return error code from ext4_mb_good_group()
2015-06-02 17:30 [PATCH v3 1/3] ext4: Verify block bitmap even after fresh initialization Lukas Czerner
2015-06-02 17:30 ` [PATCH v3 2/3] ext4: Try to initialize all groups we can in case of failure on ppc64 Lukas Czerner
@ 2015-06-02 17:30 ` Lukas Czerner
2015-06-08 15:42 ` Theodore Ts'o
1 sibling, 1 reply; 5+ messages in thread
From: Lukas Czerner @ 2015-06-02 17:30 UTC (permalink / raw)
To: linux-ext4; +Cc: Lukas Czerner
Currently ext4_mb_good_group() only returns 0 or 1 depending on whether
the allocation group is suitable for use or not. However we might get
various errors and fail while initializing new group including -EIO
which would never get propagated up the call chain. This might lead to
an endless loop at writeback when we're trying to find a good group to
allocate from and we fail to initialize new group (read error for
example).
Fix this by returning proper error code from ext4_mb_good_group() and
using it in ext4_mb_regular_allocator(). In ext4_mb_regular_allocator()
we will always return only the first occurred error from
ext4_mb_good_group() and we only propagate it back to the caller if we
do not get any other errors and we fail to allocate any blocks.
Note that with other modes than errors=continue, we will fail
immediately in ext4_mb_good_group() in case of error, however with
errors=continue we should try to continue using the file system, that's
why we're not going to fail immediately when we see an error from
ext4_mb_good_group(), but rather when we fail to find a suitable block
group to allocate from due to an problem in group initialization.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
v2: nothing changed
v3: update comments in ext4_mb_good_group()
fs/ext4/mballoc.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index df02951..78e58f7 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2011,7 +2011,12 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
}
}
-/* This is now called BEFORE we load the buddy bitmap. */
+/*
+ * This is now called BEFORE we load the buddy bitmap.
+ * Returns either 1 or 0 indicating that the group is either suitable
+ * for the allocation or not. In addition it can also return negative
+ * error code when something goes wrong.
+ */
static int ext4_mb_good_group(struct ext4_allocation_context *ac,
ext4_group_t group, int cr)
{
@@ -2034,7 +2039,7 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
int ret = ext4_mb_init_group(ac->ac_sb, group);
if (ret)
- return 0;
+ return ret;
}
fragments = grp->bb_fragments;
@@ -2081,7 +2086,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
{
ext4_group_t ngroups, group, i;
int cr;
- int err = 0;
+ int err = 0, first_err = 0;
struct ext4_sb_info *sbi;
struct super_block *sb;
struct ext4_buddy e4b;
@@ -2148,6 +2153,7 @@ repeat:
group = ac->ac_g_ex.fe_group;
for (i = 0; i < ngroups; group++, i++) {
+ int ret = 0;
cond_resched();
/*
* Artificially restricted ngroups for non-extent
@@ -2157,8 +2163,12 @@ repeat:
group = 0;
/* This now checks without needing the buddy page */
- if (!ext4_mb_good_group(ac, group, cr))
+ ret = ext4_mb_good_group(ac, group, cr);
+ if (ret <= 0) {
+ if (!first_err)
+ first_err = ret;
continue;
+ }
err = ext4_mb_load_buddy(sb, group, &e4b);
if (err)
@@ -2170,9 +2180,12 @@ repeat:
* We need to check again after locking the
* block group
*/
- if (!ext4_mb_good_group(ac, group, cr)) {
+ ret = ext4_mb_good_group(ac, group, cr);
+ if (ret <= 0) {
ext4_unlock_group(sb, group);
ext4_mb_unload_buddy(&e4b);
+ if (!first_err)
+ first_err = ret;
continue;
}
@@ -2219,6 +2232,8 @@ repeat:
}
}
out:
+ if (!err && ac->ac_status != AC_STATUS_FOUND && first_err)
+ err = first_err;
return err;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread