]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
md/r5cache: simplify handling of sh->log_start in recovery
authorSong Liu <songliubraving@fb.com>
Wed, 14 Dec 2016 23:38:01 +0000 (15:38 -0800)
committerShaohua Li <shli@fb.com>
Thu, 5 Jan 2017 19:44:38 +0000 (11:44 -0800)
We only need to update sh->log_start at the end of recovery,
which is r5c_recovery_rewrite_data_only_stripes(), so it is not
necessary to set it before that. In this patch, log_start is
removed from r5c_recovery_alloc_stripe().

After updating all sh->log_start, rewrite_data_only_stripes()
also updates log->next_checkpoints to the last sh->log_start.

Signed-off-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Shaohua Li <shli@fb.com>
drivers/md/raid5-cache.c

index 49aea423108484f63b5eb80ae00587aac15e0e0b..b178a8fef26643b0c63aa3066912039f8f4ccef3 100644 (file)
@@ -1682,8 +1682,7 @@ out:
 
 static struct stripe_head *
 r5c_recovery_alloc_stripe(struct r5conf *conf,
-                         sector_t stripe_sect,
-                         sector_t log_start)
+                         sector_t stripe_sect)
 {
        struct stripe_head *sh;
 
@@ -1692,7 +1691,6 @@ r5c_recovery_alloc_stripe(struct r5conf *conf,
                return NULL;  /* no more stripe available */
 
        r5l_recovery_reset_stripe(sh);
-       sh->log_start = log_start;
 
        return sh;
 }
@@ -1862,7 +1860,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
                                                stripe_sect);
 
                if (!sh) {
-                       sh = r5c_recovery_alloc_stripe(conf, stripe_sect, ctx->pos);
+                       sh = r5c_recovery_alloc_stripe(conf, stripe_sect);
                        /*
                         * cannot get stripe from raid5_get_active_stripe
                         * try replay some stripes
@@ -1871,7 +1869,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
                                r5c_recovery_replay_stripes(
                                        cached_stripe_list, ctx);
                                sh = r5c_recovery_alloc_stripe(
-                                       conf, stripe_sect, ctx->pos);
+                                       conf, stripe_sect);
                        }
                        if (!sh) {
                                pr_debug("md/raid:%s: Increasing stripe cache size to %d to recovery data on journal.\n",
@@ -1879,8 +1877,8 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
                                        conf->min_nr_stripes * 2);
                                raid5_set_cache_size(mddev,
                                                     conf->min_nr_stripes * 2);
-                               sh = r5c_recovery_alloc_stripe(
-                                       conf, stripe_sect, ctx->pos);
+                               sh = r5c_recovery_alloc_stripe(conf,
+                                                              stripe_sect);
                        }
                        if (!sh) {
                                pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n",
@@ -1894,7 +1892,6 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
                        if (!test_bit(STRIPE_R5C_CACHING, &sh->state) &&
                            test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) {
                                r5l_recovery_replay_one_stripe(conf, sh, ctx);
-                               sh->log_start = ctx->pos;
                                list_move_tail(&sh->lru, cached_stripe_list);
                        }
                        r5l_recovery_load_data(log, sh, ctx, payload,
@@ -1933,8 +1930,6 @@ static void r5c_recovery_load_one_stripe(struct r5l_log *log,
                        set_bit(R5_UPTODATE, &dev->flags);
                }
        }
-       list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
-       atomic_inc(&log->stripe_in_journal_count);
 }
 
 /*
@@ -2070,6 +2065,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
        struct stripe_head *sh, *next;
        struct mddev *mddev = log->rdev->mddev;
        struct page *page;
+       sector_t next_checkpoint = MaxSector;
 
        page = alloc_page(GFP_KERNEL);
        if (!page) {
@@ -2078,6 +2074,8 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
                return -ENOMEM;
        }
 
+       WARN_ON(list_empty(&ctx->cached_list));
+
        list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
                struct r5l_meta_block *mb;
                int i;
@@ -2123,12 +2121,15 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
                sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page,
                             REQ_OP_WRITE, REQ_FUA, false);
                sh->log_start = ctx->pos;
+               list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
+               atomic_inc(&log->stripe_in_journal_count);
                ctx->pos = write_pos;
                ctx->seq += 1;
-
+               next_checkpoint = sh->log_start;
                list_del_init(&sh->lru);
                raid5_release_stripe(sh);
        }
+       log->next_checkpoint = next_checkpoint;
        __free_page(page);
        return 0;
 }
@@ -2139,7 +2140,6 @@ static int r5l_recovery_log(struct r5l_log *log)
        struct r5l_recovery_ctx ctx;
        int ret;
        sector_t pos;
-       struct stripe_head *sh;
 
        ctx.pos = log->last_checkpoint;
        ctx.seq = log->last_cp_seq;
@@ -2164,9 +2164,6 @@ static int r5l_recovery_log(struct r5l_log *log)
                log->next_checkpoint = ctx.pos;
                r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++);
                ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS);
-       } else {
-               sh = list_last_entry(&ctx.cached_list, struct stripe_head, lru);
-               log->next_checkpoint = sh->log_start;
        }
 
        if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0))