summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-28 09:51:39 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-28 09:51:39 -0800
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)
if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
return;
if ( ! (
- (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) ||
+ (mddev->flags & MD_UPDATE_SB_FLAGS & ~ (1<<MD_CHANGE_PENDING)) ||
test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
(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,
} else
init_stripe(sh, sector, previous);
} else {
+ spin_lock(&conf->device_lock);
if (atomic_read(&sh->count)) {
BUG_ON(!list_empty(&sh->lru)
&& !test_bit(STRIPE_EXPANDING, &sh->state)
&& !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)
- && !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state));
+ );
} else {
- spin_lock(&conf->device_lock);
if (!test_bit(STRIPE_HANDLE, &sh->state))
atomic_inc(&conf->active_stripes);
- if (list_empty(&sh->lru) &&
- !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state) &&
- !test_bit(STRIPE_EXPANDING, &sh->state))
- BUG();
+ BUG_ON(list_empty(&sh->lru));
list_del_init(&sh->lru);
if (sh->group) {
sh->group->stripes_cnt--;
sh->group = NULL;
}
- spin_unlock(&conf->device_lock);
}
+ spin_unlock(&conf->device_lock);
}
} while (sh == NULL);
@@ -5471,7 +5468,7 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt,
for (i = 0; i < *group_cnt; i++) {
struct r5worker_group *group;
- group = worker_groups[i];
+ group = &(*worker_groups)[i];
INIT_LIST_HEAD(&group->handle_list);
group->conf = conf;
group->workers = workers + i * cnt;