diff options
author | David S. Miller <davem@davemloft.net> | 2011-10-07 13:38:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-07 13:38:43 -0400 |
commit | 88c5100c28b02c4b2b2c6f6fafbbd76d90f698b9 (patch) | |
tree | 08c4399e0341f7eb0ccb24e15f2cab687275c2a4 /drivers/md | |
parent | 8083f0fc969d9b5353061a7a6f963405057e26b1 (diff) | |
parent | 3ee72ca99288f1de95ec9c570e43f531c8799f06 (diff) |
Merge branch 'master' of github.com:davem330/net
Conflicts:
net/batman-adv/soft-interface.c
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-crypt.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-flakey.c | 4 | ||||
-rw-r--r-- | drivers/md/dm-raid.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 32 | ||||
-rw-r--r-- | drivers/md/md.c | 22 | ||||
-rw-r--r-- | drivers/md/md.h | 2 | ||||
-rw-r--r-- | drivers/md/multipath.c | 3 | ||||
-rw-r--r-- | drivers/md/raid1.c | 3 | ||||
-rw-r--r-- | drivers/md/raid10.c | 5 | ||||
-rw-r--r-- | drivers/md/raid5.c | 6 |
10 files changed, 58 insertions, 23 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 49da55c1528..8c2a000cf3f 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -1698,6 +1698,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1698 | } | 1698 | } |
1699 | 1699 | ||
1700 | ti->num_flush_requests = 1; | 1700 | ti->num_flush_requests = 1; |
1701 | ti->discard_zeroes_data_unsupported = 1; | ||
1702 | |||
1701 | return 0; | 1703 | return 0; |
1702 | 1704 | ||
1703 | bad: | 1705 | bad: |
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 89f73ca22cf..f84c08029b2 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
@@ -81,8 +81,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, | |||
81 | * corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags> | 81 | * corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags> |
82 | */ | 82 | */ |
83 | if (!strcasecmp(arg_name, "corrupt_bio_byte")) { | 83 | if (!strcasecmp(arg_name, "corrupt_bio_byte")) { |
84 | if (!argc) | 84 | if (!argc) { |
85 | ti->error = "Feature corrupt_bio_byte requires parameters"; | 85 | ti->error = "Feature corrupt_bio_byte requires parameters"; |
86 | return -EINVAL; | ||
87 | } | ||
86 | 88 | ||
87 | r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error); | 89 | r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error); |
88 | if (r) | 90 | if (r) |
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index a002dd85db1..86df8b2cf92 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -449,7 +449,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, | |||
449 | rs->ti->error = "write_mostly option is only valid for RAID1"; | 449 | rs->ti->error = "write_mostly option is only valid for RAID1"; |
450 | return -EINVAL; | 450 | return -EINVAL; |
451 | } | 451 | } |
452 | if (value > rs->md.raid_disks) { | 452 | if (value >= rs->md.raid_disks) { |
453 | rs->ti->error = "Invalid write_mostly drive index given"; | 453 | rs->ti->error = "Invalid write_mostly drive index given"; |
454 | return -EINVAL; | 454 | return -EINVAL; |
455 | } | 455 | } |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 986b8754bb0..bc04518e9d8 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -1238,14 +1238,15 @@ static void dm_table_set_integrity(struct dm_table *t) | |||
1238 | return; | 1238 | return; |
1239 | 1239 | ||
1240 | template_disk = dm_table_get_integrity_disk(t, true); | 1240 | template_disk = dm_table_get_integrity_disk(t, true); |
1241 | if (!template_disk && | 1241 | if (template_disk) |
1242 | blk_integrity_is_initialized(dm_disk(t->md))) { | 1242 | blk_integrity_register(dm_disk(t->md), |
1243 | blk_get_integrity(template_disk)); | ||
1244 | else if (blk_integrity_is_initialized(dm_disk(t->md))) | ||
1243 | DMWARN("%s: device no longer has a valid integrity profile", | 1245 | DMWARN("%s: device no longer has a valid integrity profile", |
1244 | dm_device_name(t->md)); | 1246 | dm_device_name(t->md)); |
1245 | return; | 1247 | else |
1246 | } | 1248 | DMWARN("%s: unable to establish an integrity profile", |
1247 | blk_integrity_register(dm_disk(t->md), | 1249 | dm_device_name(t->md)); |
1248 | blk_get_integrity(template_disk)); | ||
1249 | } | 1250 | } |
1250 | 1251 | ||
1251 | static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev, | 1252 | static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev, |
@@ -1282,6 +1283,22 @@ static bool dm_table_supports_flush(struct dm_table *t, unsigned flush) | |||
1282 | return 0; | 1283 | return 0; |
1283 | } | 1284 | } |
1284 | 1285 | ||
1286 | static bool dm_table_discard_zeroes_data(struct dm_table *t) | ||
1287 | { | ||
1288 | struct dm_target *ti; | ||
1289 | unsigned i = 0; | ||
1290 | |||
1291 | /* Ensure that all targets supports discard_zeroes_data. */ | ||
1292 | while (i < dm_table_get_num_targets(t)) { | ||
1293 | ti = dm_table_get_target(t, i++); | ||
1294 | |||
1295 | if (ti->discard_zeroes_data_unsupported) | ||
1296 | return 0; | ||
1297 | } | ||
1298 | |||
1299 | return 1; | ||
1300 | } | ||
1301 | |||
1285 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | 1302 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
1286 | struct queue_limits *limits) | 1303 | struct queue_limits *limits) |
1287 | { | 1304 | { |
@@ -1304,6 +1321,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
1304 | } | 1321 | } |
1305 | blk_queue_flush(q, flush); | 1322 | blk_queue_flush(q, flush); |
1306 | 1323 | ||
1324 | if (!dm_table_discard_zeroes_data(t)) | ||
1325 | q->limits.discard_zeroes_data = 0; | ||
1326 | |||
1307 | dm_table_set_integrity(t); | 1327 | dm_table_set_integrity(t); |
1308 | 1328 | ||
1309 | /* | 1329 | /* |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 5404b229582..5c95ccb5950 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -61,6 +61,11 @@ | |||
61 | static void autostart_arrays(int part); | 61 | static void autostart_arrays(int part); |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | /* pers_list is a list of registered personalities protected | ||
65 | * by pers_lock. | ||
66 | * pers_lock does extra service to protect accesses to | ||
67 | * mddev->thread when the mutex cannot be held. | ||
68 | */ | ||
64 | static LIST_HEAD(pers_list); | 69 | static LIST_HEAD(pers_list); |
65 | static DEFINE_SPINLOCK(pers_lock); | 70 | static DEFINE_SPINLOCK(pers_lock); |
66 | 71 | ||
@@ -739,7 +744,12 @@ static void mddev_unlock(mddev_t * mddev) | |||
739 | } else | 744 | } else |
740 | mutex_unlock(&mddev->reconfig_mutex); | 745 | mutex_unlock(&mddev->reconfig_mutex); |
741 | 746 | ||
747 | /* was we've dropped the mutex we need a spinlock to | ||
748 | * make sur the thread doesn't disappear | ||
749 | */ | ||
750 | spin_lock(&pers_lock); | ||
742 | md_wakeup_thread(mddev->thread); | 751 | md_wakeup_thread(mddev->thread); |
752 | spin_unlock(&pers_lock); | ||
743 | } | 753 | } |
744 | 754 | ||
745 | static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) | 755 | static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) |
@@ -6429,11 +6439,18 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, | |||
6429 | return thread; | 6439 | return thread; |
6430 | } | 6440 | } |
6431 | 6441 | ||
6432 | void md_unregister_thread(mdk_thread_t *thread) | 6442 | void md_unregister_thread(mdk_thread_t **threadp) |
6433 | { | 6443 | { |
6444 | mdk_thread_t *thread = *threadp; | ||
6434 | if (!thread) | 6445 | if (!thread) |
6435 | return; | 6446 | return; |
6436 | dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); | 6447 | dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); |
6448 | /* Locking ensures that mddev_unlock does not wake_up a | ||
6449 | * non-existent thread | ||
6450 | */ | ||
6451 | spin_lock(&pers_lock); | ||
6452 | *threadp = NULL; | ||
6453 | spin_unlock(&pers_lock); | ||
6437 | 6454 | ||
6438 | kthread_stop(thread->tsk); | 6455 | kthread_stop(thread->tsk); |
6439 | kfree(thread); | 6456 | kfree(thread); |
@@ -7340,8 +7357,7 @@ static void reap_sync_thread(mddev_t *mddev) | |||
7340 | mdk_rdev_t *rdev; | 7357 | mdk_rdev_t *rdev; |
7341 | 7358 | ||
7342 | /* resync has finished, collect result */ | 7359 | /* resync has finished, collect result */ |
7343 | md_unregister_thread(mddev->sync_thread); | 7360 | md_unregister_thread(&mddev->sync_thread); |
7344 | mddev->sync_thread = NULL; | ||
7345 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && | 7361 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
7346 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | 7362 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { |
7347 | /* success...*/ | 7363 | /* success...*/ |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 1e586bb4452..0a309dc29b4 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -560,7 +560,7 @@ extern int register_md_personality(struct mdk_personality *p); | |||
560 | extern int unregister_md_personality(struct mdk_personality *p); | 560 | extern int unregister_md_personality(struct mdk_personality *p); |
561 | extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), | 561 | extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), |
562 | mddev_t *mddev, const char *name); | 562 | mddev_t *mddev, const char *name); |
563 | extern void md_unregister_thread(mdk_thread_t *thread); | 563 | extern void md_unregister_thread(mdk_thread_t **threadp); |
564 | extern void md_wakeup_thread(mdk_thread_t *thread); | 564 | extern void md_wakeup_thread(mdk_thread_t *thread); |
565 | extern void md_check_recovery(mddev_t *mddev); | 565 | extern void md_check_recovery(mddev_t *mddev); |
566 | extern void md_write_start(mddev_t *mddev, struct bio *bi); | 566 | extern void md_write_start(mddev_t *mddev, struct bio *bi); |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 3535c23af28..d5b5fb30017 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -514,8 +514,7 @@ static int multipath_stop (mddev_t *mddev) | |||
514 | { | 514 | { |
515 | multipath_conf_t *conf = mddev->private; | 515 | multipath_conf_t *conf = mddev->private; |
516 | 516 | ||
517 | md_unregister_thread(mddev->thread); | 517 | md_unregister_thread(&mddev->thread); |
518 | mddev->thread = NULL; | ||
519 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 518 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
520 | mempool_destroy(conf->pool); | 519 | mempool_destroy(conf->pool); |
521 | kfree(conf->multipaths); | 520 | kfree(conf->multipaths); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f4622dd8fc5..d9587dffe53 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -2562,8 +2562,7 @@ static int stop(mddev_t *mddev) | |||
2562 | raise_barrier(conf); | 2562 | raise_barrier(conf); |
2563 | lower_barrier(conf); | 2563 | lower_barrier(conf); |
2564 | 2564 | ||
2565 | md_unregister_thread(mddev->thread); | 2565 | md_unregister_thread(&mddev->thread); |
2566 | mddev->thread = NULL; | ||
2567 | if (conf->r1bio_pool) | 2566 | if (conf->r1bio_pool) |
2568 | mempool_destroy(conf->r1bio_pool); | 2567 | mempool_destroy(conf->r1bio_pool); |
2569 | kfree(conf->mirrors); | 2568 | kfree(conf->mirrors); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d7a8468ddea..0cd9672cf9c 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -2955,7 +2955,7 @@ static int run(mddev_t *mddev) | |||
2955 | return 0; | 2955 | return 0; |
2956 | 2956 | ||
2957 | out_free_conf: | 2957 | out_free_conf: |
2958 | md_unregister_thread(mddev->thread); | 2958 | md_unregister_thread(&mddev->thread); |
2959 | if (conf->r10bio_pool) | 2959 | if (conf->r10bio_pool) |
2960 | mempool_destroy(conf->r10bio_pool); | 2960 | mempool_destroy(conf->r10bio_pool); |
2961 | safe_put_page(conf->tmppage); | 2961 | safe_put_page(conf->tmppage); |
@@ -2973,8 +2973,7 @@ static int stop(mddev_t *mddev) | |||
2973 | raise_barrier(conf, 0); | 2973 | raise_barrier(conf, 0); |
2974 | lower_barrier(conf); | 2974 | lower_barrier(conf); |
2975 | 2975 | ||
2976 | md_unregister_thread(mddev->thread); | 2976 | md_unregister_thread(&mddev->thread); |
2977 | mddev->thread = NULL; | ||
2978 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 2977 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
2979 | if (conf->r10bio_pool) | 2978 | if (conf->r10bio_pool) |
2980 | mempool_destroy(conf->r10bio_pool); | 2979 | mempool_destroy(conf->r10bio_pool); |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 43709fa6b6d..ac5e8b57e50 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -4941,8 +4941,7 @@ static int run(mddev_t *mddev) | |||
4941 | 4941 | ||
4942 | return 0; | 4942 | return 0; |
4943 | abort: | 4943 | abort: |
4944 | md_unregister_thread(mddev->thread); | 4944 | md_unregister_thread(&mddev->thread); |
4945 | mddev->thread = NULL; | ||
4946 | if (conf) { | 4945 | if (conf) { |
4947 | print_raid5_conf(conf); | 4946 | print_raid5_conf(conf); |
4948 | free_conf(conf); | 4947 | free_conf(conf); |
@@ -4956,8 +4955,7 @@ static int stop(mddev_t *mddev) | |||
4956 | { | 4955 | { |
4957 | raid5_conf_t *conf = mddev->private; | 4956 | raid5_conf_t *conf = mddev->private; |
4958 | 4957 | ||
4959 | md_unregister_thread(mddev->thread); | 4958 | md_unregister_thread(&mddev->thread); |
4960 | mddev->thread = NULL; | ||
4961 | if (mddev->queue) | 4959 | if (mddev->queue) |
4962 | mddev->queue->backing_dev_info.congested_fn = NULL; | 4960 | mddev->queue->backing_dev_info.congested_fn = NULL; |
4963 | free_conf(conf); | 4961 | free_conf(conf); |