add patch use-swap-in-mext_page_double_lock
[ext4-patch-queue.git] / return-error-code-from-ext4_mb_good_group
blob6b0d2a33e6fe26894cfe2c4bc6cdb9e2c683e00f
1 ext4: return error code from ext4_mb_good_group()
3 From: Lukas Czerner <lczerner@redhat.com>
5 Currently ext4_mb_good_group() only returns 0 or 1 depending on whether
6 the allocation group is suitable for use or not. However we might get
7 various errors and fail while initializing new group including -EIO
8 which would never get propagated up the call chain. This might lead to
9 an endless loop at writeback when we're trying to find a good group to
10 allocate from and we fail to initialize new group (read error for
11 example).
13 Fix this by returning proper error code from ext4_mb_good_group() and
14 using it in ext4_mb_regular_allocator(). In ext4_mb_regular_allocator()
15 we will always return only the first occurred error from
16 ext4_mb_good_group() and we only propagate it back  to the caller if we
17 do not get any other errors and we fail to allocate any blocks.
19 Note that with other modes than errors=continue, we will fail
20 immediately in ext4_mb_good_group() in case of error, however with
21 errors=continue we should try to continue using the file system, that's
22 why we're not going to fail immediately when we see an error from
23 ext4_mb_good_group(), but rather when we fail to find a suitable block
24 group to allocate from due to an problem in group initialization.
26 Signed-off-by: Lukas Czerner <lczerner@redhat.com>
27 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
28 Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
29 ---
30 v2: nothing changed
31 v3: update comments in ext4_mb_good_group()
33  fs/ext4/mballoc.c | 25 ++++++++++++++++++++-----
34  1 file changed, 20 insertions(+), 5 deletions(-)
36 diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
37 index df02951..78e58f7 100644
38 --- a/fs/ext4/mballoc.c
39 +++ b/fs/ext4/mballoc.c
40 @@ -2011,7 +2011,12 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
41         }
42  }
44 -/* This is now called BEFORE we load the buddy bitmap. */
45 +/*
46 + * This is now called BEFORE we load the buddy bitmap.
47 + * Returns either 1 or 0 indicating that the group is either suitable
48 + * for the allocation or not. In addition it can also return negative
49 + * error code when something goes wrong.
50 + */
51  static int ext4_mb_good_group(struct ext4_allocation_context *ac,
52                                 ext4_group_t group, int cr)
53  {
54 @@ -2034,7 +2039,7 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
55         if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
56                 int ret = ext4_mb_init_group(ac->ac_sb, group);
57                 if (ret)
58 -                       return 0;
59 +                       return ret;
60         }
62         fragments = grp->bb_fragments;
63 @@ -2081,7 +2086,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
64  {
65         ext4_group_t ngroups, group, i;
66         int cr;
67 -       int err = 0;
68 +       int err = 0, first_err = 0;
69         struct ext4_sb_info *sbi;
70         struct super_block *sb;
71         struct ext4_buddy e4b;
72 @@ -2148,6 +2153,7 @@ repeat:
73                 group = ac->ac_g_ex.fe_group;
75                 for (i = 0; i < ngroups; group++, i++) {
76 +                       int ret = 0;
77                         cond_resched();
78                         /*
79                          * Artificially restricted ngroups for non-extent
80 @@ -2157,8 +2163,12 @@ repeat:
81                                 group = 0;
83                         /* This now checks without needing the buddy page */
84 -                       if (!ext4_mb_good_group(ac, group, cr))
85 +                       ret = ext4_mb_good_group(ac, group, cr);
86 +                       if (ret <= 0) {
87 +                               if (!first_err)
88 +                                       first_err = ret;
89                                 continue;
90 +                       }
92                         err = ext4_mb_load_buddy(sb, group, &e4b);
93                         if (err)
94 @@ -2170,9 +2180,12 @@ repeat:
95                          * We need to check again after locking the
96                          * block group
97                          */
98 -                       if (!ext4_mb_good_group(ac, group, cr)) {
99 +                       ret = ext4_mb_good_group(ac, group, cr);
100 +                       if (ret <= 0) {
101                                 ext4_unlock_group(sb, group);
102                                 ext4_mb_unload_buddy(&e4b);
103 +                               if (!first_err)
104 +                                       first_err = ret;
105                                 continue;
106                         }
108 @@ -2219,6 +2232,8 @@ repeat:
109                 }
110         }
111  out:
112 +       if (!err && ac->ac_status != AC_STATUS_FOUND && first_err)
113 +               err = first_err;
114         return err;
117 -- 
118 1.8.3.1
121 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
122 the body of a message to majordomo@vger.kernel.org
123 More majordomo info at  http://vger.kernel.org/majordomo-info.html