mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
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 <songliubraving@fb.com> Reviewed-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user