diff options
author | Yufen Yu <yuyufen@huawei.com> | 2020-08-20 09:22:13 -0400 |
---|---|---|
committer | Song Liu <songliubraving@fb.com> | 2020-09-24 16:44:45 -0700 |
commit | f16acaf328c5615fdaea74f9bd0b4019544532d6 (patch) | |
tree | bb3aafd61bba64753865924e939cb851911dd9e8 | |
parent | 046169f048cdea84fd327469239e2dfa317981b5 (diff) | |
download | linux-f16acaf328c5615fdaea74f9bd0b4019544532d6.tar.gz linux-f16acaf328c5615fdaea74f9bd0b4019544532d6.tar.bz2 linux-f16acaf328c5615fdaea74f9bd0b4019544532d6.zip |
md/raid5: resize stripe_head when reshape array
When reshape array, we try to reuse shared pages of old stripe_head,
and allocate more for the new one if needed.
Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
-rw-r--r-- | drivers/md/raid5.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ea1e56e21a31..c23e408f7623 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2535,6 +2535,12 @@ static int resize_stripes(struct r5conf *conf, int newsize) osh = get_free_stripe(conf, hash); unlock_device_hash_lock(conf, hash); +#if PAGE_SIZE != DEFAULT_STRIPE_SIZE + for (i = 0; i < osh->nr_pages; i++) { + nsh->pages[i] = osh->pages[i]; + osh->pages[i] = NULL; + } +#endif for(i=0; i<conf->pool_size; i++) { nsh->dev[i].page = osh->dev[i].page; nsh->dev[i].orig_page = osh->dev[i].page; @@ -2589,6 +2595,23 @@ static int resize_stripes(struct r5conf *conf, int newsize) nsh = list_entry(newstripes.next, struct stripe_head, lru); list_del_init(&nsh->lru); +#if PAGE_SIZE != DEFAULT_STRIPE_SIZE + for (i = 0; i < nsh->nr_pages; i++) { + if (nsh->pages[i]) + continue; + nsh->pages[i] = alloc_page(GFP_NOIO); + if (!nsh->pages[i]) + err = -ENOMEM; + } + + for (i = conf->raid_disks; i < newsize; i++) { + if (nsh->dev[i].page) + continue; + nsh->dev[i].page = raid5_get_dev_page(nsh, i); + nsh->dev[i].orig_page = nsh->dev[i].page; + nsh->dev[i].offset = raid5_get_page_offset(nsh, i); + } +#else for (i=conf->raid_disks; i < newsize; i++) if (nsh->dev[i].page == NULL) { struct page *p = alloc_page(GFP_NOIO); @@ -2598,6 +2621,7 @@ static int resize_stripes(struct r5conf *conf, int newsize) if (!p) err = -ENOMEM; } +#endif raid5_release_stripe(nsh); } /* critical section pass, GFP_NOIO no longer needed */ |