提交 dabc4ec6 编写于 作者: S shli@kernel.org 提交者: NeilBrown

raid5: handle expansion/resync case with stripe batching

expansion/resync can grab a stripe when the stripe is in batch list. Since all
stripes in batch list must be in the same state, we can't allow some stripes
run into expansion/resync. So we delay expansion/resync for stripe in batch
list.
Signed-off-by: NShaohua Li <shli@fusionio.com>
Signed-off-by: NNeilBrown <neilb@suse.de>
上级 72ac7330
...@@ -3440,8 +3440,10 @@ static void handle_stripe_clean_event(struct r5conf *conf, ...@@ -3440,8 +3440,10 @@ static void handle_stripe_clean_event(struct r5conf *conf,
struct stripe_head, batch_list); struct stripe_head, batch_list);
list_del_init(&sh->batch_list); list_del_init(&sh->batch_list);
sh->state = head_sh->state & (~((1 << STRIPE_ACTIVE) | set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
(1 << STRIPE_PREREAD_ACTIVE))); head_sh->state & ~((1 << STRIPE_ACTIVE) |
(1 << STRIPE_PREREAD_ACTIVE) |
STRIPE_EXPAND_SYNC_FLAG));
sh->check_state = head_sh->check_state; sh->check_state = head_sh->check_state;
sh->reconstruct_state = head_sh->reconstruct_state; sh->reconstruct_state = head_sh->reconstruct_state;
for (i = 0; i < sh->disks; i++) { for (i = 0; i < sh->disks; i++) {
...@@ -3453,6 +3455,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, ...@@ -3453,6 +3455,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
spin_lock_irq(&sh->stripe_lock); spin_lock_irq(&sh->stripe_lock);
sh->batch_head = NULL; sh->batch_head = NULL;
spin_unlock_irq(&sh->stripe_lock); spin_unlock_irq(&sh->stripe_lock);
if (sh->state & STRIPE_EXPAND_SYNC_FLAG)
set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh); release_stripe(sh);
} }
...@@ -3460,6 +3464,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, ...@@ -3460,6 +3464,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
head_sh->batch_head = NULL; head_sh->batch_head = NULL;
spin_unlock_irq(&head_sh->stripe_lock); spin_unlock_irq(&head_sh->stripe_lock);
wake_up_nr(&conf->wait_for_overlap, wakeup_nr); wake_up_nr(&conf->wait_for_overlap, wakeup_nr);
if (head_sh->state & STRIPE_EXPAND_SYNC_FLAG)
set_bit(STRIPE_HANDLE, &head_sh->state);
} }
static void handle_stripe_dirtying(struct r5conf *conf, static void handle_stripe_dirtying(struct r5conf *conf,
...@@ -3927,8 +3933,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) ...@@ -3927,8 +3933,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); s->expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state) && !sh->batch_head;
s->expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); s->expanded = test_bit(STRIPE_EXPAND_READY, &sh->state) && !sh->batch_head;
s->failed_num[0] = -1; s->failed_num[0] = -1;
s->failed_num[1] = -1; s->failed_num[1] = -1;
...@@ -4150,9 +4156,11 @@ static void check_break_stripe_batch_list(struct stripe_head *sh) ...@@ -4150,9 +4156,11 @@ static void check_break_stripe_batch_list(struct stripe_head *sh)
struct stripe_head, batch_list); struct stripe_head, batch_list);
list_del_init(&sh->batch_list); list_del_init(&sh->batch_list);
sh->state = head_sh->state & ~((1 << STRIPE_ACTIVE) | set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
(1 << STRIPE_PREREAD_ACTIVE) | head_sh->state & ~((1 << STRIPE_ACTIVE) |
(1 << STRIPE_DEGRADED)); (1 << STRIPE_PREREAD_ACTIVE) |
(1 << STRIPE_DEGRADED) |
STRIPE_EXPAND_SYNC_FLAG));
sh->check_state = head_sh->check_state; sh->check_state = head_sh->check_state;
sh->reconstruct_state = head_sh->reconstruct_state; sh->reconstruct_state = head_sh->reconstruct_state;
for (i = 0; i < sh->disks; i++) for (i = 0; i < sh->disks; i++)
...@@ -4194,7 +4202,7 @@ static void handle_stripe(struct stripe_head *sh) ...@@ -4194,7 +4202,7 @@ static void handle_stripe(struct stripe_head *sh)
check_break_stripe_batch_list(sh); check_break_stripe_batch_list(sh);
if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) {
spin_lock(&sh->stripe_lock); spin_lock(&sh->stripe_lock);
/* Cannot process 'sync' concurrently with 'discard' */ /* Cannot process 'sync' concurrently with 'discard' */
if (!test_bit(STRIPE_DISCARD, &sh->state) && if (!test_bit(STRIPE_DISCARD, &sh->state) &&
......
...@@ -339,6 +339,11 @@ enum { ...@@ -339,6 +339,11 @@ enum {
STRIPE_BATCH_ERR, STRIPE_BATCH_ERR,
}; };
#define STRIPE_EXPAND_SYNC_FLAG \
((1 << STRIPE_EXPAND_SOURCE) |\
(1 << STRIPE_EXPAND_READY) |\
(1 << STRIPE_EXPANDING) |\
(1 << STRIPE_SYNC_REQUESTED))
/* /*
* Operation request flags * Operation request flags
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册