aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-28 12:51:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-28 12:51:39 -0500
commit962ba26326ba02ca5c67f18c6979c3adfd7c2097 (patch)
treeb460ef885521484d20554fd8270515625154f62c
parent3bad8bb5cd3048a67df43ac6b1e2f191f19d9ff0 (diff)
parent6d183de4077191d1201283a9035ce57a9b05254d (diff)
Merge tag 'md/3.13-fixes' of git://neil.brown.name/md
Pull md fixes from Neil Brown: "Three bug fixes for md in 3.13-rc All recent regressions, one in 3.12 so marked for -stable" * tag 'md/3.13-fixes' of git://neil.brown.name/md: md/raid5: fix newly-broken locking in get_active_stripe. md: test mddev->flags more safely in md_check_recovery. md/raid5: fix new memory-reference bug in alloc_thread_groups.
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/raid5.c13
2 files changed, 6 insertions, 9 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index b6b7a2866c9e..e60cebf3f519 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7777,7 +7777,7 @@ void md_check_recovery(struct mddev *mddev)
7777 if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) 7777 if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
7778 return; 7778 return;
7779 if ( ! ( 7779 if ( ! (
7780 (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) || 7780 (mddev->flags & MD_UPDATE_SB_FLAGS & ~ (1<<MD_CHANGE_PENDING)) ||
7781 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || 7781 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
7782 test_bit(MD_RECOVERY_DONE, &mddev->recovery) || 7782 test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
7783 (mddev->external == 0 && mddev->safemode == 1) || 7783 (mddev->external == 0 && mddev->safemode == 1) ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 47da0af6322b..cc055da02e2a 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -678,26 +678,23 @@ get_active_stripe(struct r5conf *conf, sector_t sector,
678 } else 678 } else
679 init_stripe(sh, sector, previous); 679 init_stripe(sh, sector, previous);
680 } else { 680 } else {
681 spin_lock(&conf->device_lock);
681 if (atomic_read(&sh->count)) { 682 if (atomic_read(&sh->count)) {
682 BUG_ON(!list_empty(&sh->lru) 683 BUG_ON(!list_empty(&sh->lru)
683 && !test_bit(STRIPE_EXPANDING, &sh->state) 684 && !test_bit(STRIPE_EXPANDING, &sh->state)
684 && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state) 685 && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)
685 && !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state)); 686 );
686 } else { 687 } else {
687 spin_lock(&conf->device_lock);
688 if (!test_bit(STRIPE_HANDLE, &sh->state)) 688 if (!test_bit(STRIPE_HANDLE, &sh->state))
689 atomic_inc(&conf->active_stripes); 689 atomic_inc(&conf->active_stripes);
690 if (list_empty(&sh->lru) && 690 BUG_ON(list_empty(&sh->lru));
691 !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state) &&
692 !test_bit(STRIPE_EXPANDING, &sh->state))
693 BUG();
694 list_del_init(&sh->lru); 691 list_del_init(&sh->lru);
695 if (sh->group) { 692 if (sh->group) {
696 sh->group->stripes_cnt--; 693 sh->group->stripes_cnt--;
697 sh->group = NULL; 694 sh->group = NULL;
698 } 695 }
699 spin_unlock(&conf->device_lock);
700 } 696 }
697 spin_unlock(&conf->device_lock);
701 } 698 }
702 } while (sh == NULL); 699 } while (sh == NULL);
703 700
@@ -5471,7 +5468,7 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt,
5471 for (i = 0; i < *group_cnt; i++) { 5468 for (i = 0; i < *group_cnt; i++) {
5472 struct r5worker_group *group; 5469 struct r5worker_group *group;
5473 5470
5474 group = worker_groups[i]; 5471 group = &(*worker_groups)[i];
5475 INIT_LIST_HEAD(&group->handle_list); 5472 INIT_LIST_HEAD(&group->handle_list);
5476 group->conf = conf; 5473 group->conf = conf;
5477 group->workers = workers + i * cnt; 5474 group->workers = workers + i * cnt;