From d7bd398e97f236a2353689eca5e8950f67cd34d5 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Wed, 23 Nov 2016 22:50:39 -0800 Subject: md/r5cache: handle alloc_page failure RMW of r5c write back cache uses an extra page to store old data for prexor. handle_stripe_dirtying() allocates this page by calling alloc_page(). However, alloc_page() may fail. To handle alloc_page() failures, this patch adds an extra page to disk_info. When alloc_page fails, handle_stripe() trys to use these pages. When these pages are used by other stripe (R5C_EXTRA_PAGE_IN_USE), the stripe is added to delayed_list. Signed-off-by: Song Liu Reviewed-by: NeilBrown Signed-off-by: Shaohua Li --- drivers/md/raid5.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/md/raid5.h') diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index d13fe45d6960..ed8e1362ab36 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h @@ -276,6 +276,7 @@ struct stripe_head_state { struct md_rdev *blocked_rdev; int handle_bad_blocks; int log_failed; + int waiting_extra_page; }; /* Flags for struct r5dev.flags */ @@ -439,6 +440,7 @@ enum { struct disk_info { struct md_rdev *rdev, *replacement; + struct page *extra_page; /* extra page to use in prexor */ }; /* @@ -559,6 +561,9 @@ enum r5_cache_state { * only process stripes that are already * occupying the log */ + R5C_EXTRA_PAGE_IN_USE, /* a stripe is using disk_info.extra_page + * for prexor + */ }; struct r5conf { @@ -765,6 +770,7 @@ extern void r5c_finish_stripe_write_out(struct r5conf *conf, struct stripe_head *sh, struct stripe_head_state *s); extern void r5c_release_extra_page(struct stripe_head *sh); +extern void r5c_use_extra_page(struct stripe_head *sh); extern void r5l_wake_reclaim(struct r5l_log *log, sector_t space); extern void r5c_handle_cached_data_endio(struct r5conf *conf, struct stripe_head *sh, int disks, struct bio_list *return_bi); -- cgit v1.2.3