aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSong Liu <songliubraving@fb.com>2016-12-14 18:38:01 -0500
committerShaohua Li <shli@fb.com>2017-01-05 14:44:38 -0500
commit3c66abbaaf69671dfd3eb9fa7740b5d7ec688231 (patch)
tree63f3110203923120a46c9b052a97a16feaf22b39
parent28ca833ecf89c585a9543fb21aef6b2bdbbaa48a (diff)
md/r5cache: simplify handling of sh->log_start in recovery
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>
-rw-r--r--drivers/md/raid5-cache.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 49aea4231084..b178a8fef266 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -1682,8 +1682,7 @@ out:
1682 1682
1683static struct stripe_head * 1683static struct stripe_head *
1684r5c_recovery_alloc_stripe(struct r5conf *conf, 1684r5c_recovery_alloc_stripe(struct r5conf *conf,
1685 sector_t stripe_sect, 1685 sector_t stripe_sect)
1686 sector_t log_start)
1687{ 1686{
1688 struct stripe_head *sh; 1687 struct stripe_head *sh;
1689 1688
@@ -1692,7 +1691,6 @@ r5c_recovery_alloc_stripe(struct r5conf *conf,
1692 return NULL; /* no more stripe available */ 1691 return NULL; /* no more stripe available */
1693 1692
1694 r5l_recovery_reset_stripe(sh); 1693 r5l_recovery_reset_stripe(sh);
1695 sh->log_start = log_start;
1696 1694
1697 return sh; 1695 return sh;
1698} 1696}
@@ -1862,7 +1860,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
1862 stripe_sect); 1860 stripe_sect);
1863 1861
1864 if (!sh) { 1862 if (!sh) {
1865 sh = r5c_recovery_alloc_stripe(conf, stripe_sect, ctx->pos); 1863 sh = r5c_recovery_alloc_stripe(conf, stripe_sect);
1866 /* 1864 /*
1867 * cannot get stripe from raid5_get_active_stripe 1865 * cannot get stripe from raid5_get_active_stripe
1868 * try replay some stripes 1866 * try replay some stripes
@@ -1871,7 +1869,7 @@ r5c_recovery_analyze_meta_block(struct r5l_log *log,
1871 r5c_recovery_replay_stripes( 1869 r5c_recovery_replay_stripes(
1872 cached_stripe_list, ctx); 1870 cached_stripe_list, ctx);
1873 sh = r5c_recovery_alloc_stripe( 1871 sh = r5c_recovery_alloc_stripe(
1874 conf, stripe_sect, ctx->pos); 1872 conf, stripe_sect);
1875 } 1873 }
1876 if (!sh) { 1874 if (!sh) {
1877 pr_debug("md/raid:%s: Increasing stripe cache size to %d to recovery data on journal.\n", 1875 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,
1879 conf->min_nr_stripes * 2); 1877 conf->min_nr_stripes * 2);
1880 raid5_set_cache_size(mddev, 1878 raid5_set_cache_size(mddev,
1881 conf->min_nr_stripes * 2); 1879 conf->min_nr_stripes * 2);
1882 sh = r5c_recovery_alloc_stripe( 1880 sh = r5c_recovery_alloc_stripe(conf,
1883 conf, stripe_sect, ctx->pos); 1881 stripe_sect);
1884 } 1882 }
1885 if (!sh) { 1883 if (!sh) {
1886 pr_err("md/raid:%s: Cannot get enough stripes due to memory pressure. Recovery failed.\n", 1884 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,
1894 if (!test_bit(STRIPE_R5C_CACHING, &sh->state) && 1892 if (!test_bit(STRIPE_R5C_CACHING, &sh->state) &&
1895 test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) { 1893 test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags)) {
1896 r5l_recovery_replay_one_stripe(conf, sh, ctx); 1894 r5l_recovery_replay_one_stripe(conf, sh, ctx);
1897 sh->log_start = ctx->pos;
1898 list_move_tail(&sh->lru, cached_stripe_list); 1895 list_move_tail(&sh->lru, cached_stripe_list);
1899 } 1896 }
1900 r5l_recovery_load_data(log, sh, ctx, payload, 1897 r5l_recovery_load_data(log, sh, ctx, payload,
@@ -1933,8 +1930,6 @@ static void r5c_recovery_load_one_stripe(struct r5l_log *log,
1933 set_bit(R5_UPTODATE, &dev->flags); 1930 set_bit(R5_UPTODATE, &dev->flags);
1934 } 1931 }
1935 } 1932 }
1936 list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
1937 atomic_inc(&log->stripe_in_journal_count);
1938} 1933}
1939 1934
1940/* 1935/*
@@ -2070,6 +2065,7 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
2070 struct stripe_head *sh, *next; 2065 struct stripe_head *sh, *next;
2071 struct mddev *mddev = log->rdev->mddev; 2066 struct mddev *mddev = log->rdev->mddev;
2072 struct page *page; 2067 struct page *page;
2068 sector_t next_checkpoint = MaxSector;
2073 2069
2074 page = alloc_page(GFP_KERNEL); 2070 page = alloc_page(GFP_KERNEL);
2075 if (!page) { 2071 if (!page) {
@@ -2078,6 +2074,8 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
2078 return -ENOMEM; 2074 return -ENOMEM;
2079 } 2075 }
2080 2076
2077 WARN_ON(list_empty(&ctx->cached_list));
2078
2081 list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) { 2079 list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
2082 struct r5l_meta_block *mb; 2080 struct r5l_meta_block *mb;
2083 int i; 2081 int i;
@@ -2123,12 +2121,15 @@ r5c_recovery_rewrite_data_only_stripes(struct r5l_log *log,
2123 sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page, 2121 sync_page_io(log->rdev, ctx->pos, PAGE_SIZE, page,
2124 REQ_OP_WRITE, REQ_FUA, false); 2122 REQ_OP_WRITE, REQ_FUA, false);
2125 sh->log_start = ctx->pos; 2123 sh->log_start = ctx->pos;
2124 list_add_tail(&sh->r5c, &log->stripe_in_journal_list);
2125 atomic_inc(&log->stripe_in_journal_count);
2126 ctx->pos = write_pos; 2126 ctx->pos = write_pos;
2127 ctx->seq += 1; 2127 ctx->seq += 1;
2128 2128 next_checkpoint = sh->log_start;
2129 list_del_init(&sh->lru); 2129 list_del_init(&sh->lru);
2130 raid5_release_stripe(sh); 2130 raid5_release_stripe(sh);
2131 } 2131 }
2132 log->next_checkpoint = next_checkpoint;
2132 __free_page(page); 2133 __free_page(page);
2133 return 0; 2134 return 0;
2134} 2135}
@@ -2139,7 +2140,6 @@ static int r5l_recovery_log(struct r5l_log *log)
2139 struct r5l_recovery_ctx ctx; 2140 struct r5l_recovery_ctx ctx;
2140 int ret; 2141 int ret;
2141 sector_t pos; 2142 sector_t pos;
2142 struct stripe_head *sh;
2143 2143
2144 ctx.pos = log->last_checkpoint; 2144 ctx.pos = log->last_checkpoint;
2145 ctx.seq = log->last_cp_seq; 2145 ctx.seq = log->last_cp_seq;
@@ -2164,9 +2164,6 @@ static int r5l_recovery_log(struct r5l_log *log)
2164 log->next_checkpoint = ctx.pos; 2164 log->next_checkpoint = ctx.pos;
2165 r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++); 2165 r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq++);
2166 ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS); 2166 ctx.pos = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS);
2167 } else {
2168 sh = list_last_entry(&ctx.cached_list, struct stripe_head, lru);
2169 log->next_checkpoint = sh->log_start;
2170 } 2167 }
2171 2168
2172 if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0)) 2169 if ((ctx.data_only_stripes == 0) && (ctx.data_parity_stripes == 0))