diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-08 20:21:51 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-08 20:21:51 -0500 |
| commit | 5d0edf29151bb5ba372784b7e369f42cf23a94eb (patch) | |
| tree | 847eee159ac3387fd6ad1c385341d70fc45ea13b | |
| parent | 4f262acfde22b63498b5e4f165e53d3bb4e96400 (diff) | |
| parent | 0ca93de9b789e0eb05e103f0c04de72df13da73a (diff) | |
Merge tag 'dm-3.3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm
Pull device-mapper fixes for 3.3 from Alasdair Kergon
Eight small device-mapper bug fixes.
* tag 'dm-3.3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm:
dm raid: fix flush support
dm raid: set MD_CHANGE_DEVS when rebuilding
dm thin metadata: decrement counter after removing mapped block
dm thin metadata: unlock superblock in init_pmd error path
dm thin metadata: remove incorrect close_device on creation error paths
dm flakey: fix crash on read when corrupt_bio_byte not set
dm io: fix discard support
dm ioctl: do not leak argv if target message only contains whitespace
| -rw-r--r-- | drivers/md/dm-flakey.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-io.c | 23 | ||||
| -rw-r--r-- | drivers/md/dm-ioctl.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-raid.c | 17 | ||||
| -rw-r--r-- | drivers/md/dm-thin-metadata.c | 25 |
5 files changed, 49 insertions, 20 deletions
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 9fb18c147825..b280c433e4a0 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
| @@ -323,7 +323,7 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, | |||
| 323 | * Corrupt successful READs while in down state. | 323 | * Corrupt successful READs while in down state. |
| 324 | * If flags were specified, only corrupt those that match. | 324 | * If flags were specified, only corrupt those that match. |
| 325 | */ | 325 | */ |
| 326 | if (!error && bio_submitted_while_down && | 326 | if (fc->corrupt_bio_byte && !error && bio_submitted_while_down && |
| 327 | (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) && | 327 | (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) && |
| 328 | all_corrupt_bio_flags_match(bio, fc)) | 328 | all_corrupt_bio_flags_match(bio, fc)) |
| 329 | corrupt_bio_data(bio, fc); | 329 | corrupt_bio_data(bio, fc); |
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index ad2eba40e319..ea5dd289fe2a 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
| @@ -296,6 +296,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | |||
| 296 | unsigned offset; | 296 | unsigned offset; |
| 297 | unsigned num_bvecs; | 297 | unsigned num_bvecs; |
| 298 | sector_t remaining = where->count; | 298 | sector_t remaining = where->count; |
| 299 | struct request_queue *q = bdev_get_queue(where->bdev); | ||
| 300 | sector_t discard_sectors; | ||
| 299 | 301 | ||
| 300 | /* | 302 | /* |
| 301 | * where->count may be zero if rw holds a flush and we need to | 303 | * where->count may be zero if rw holds a flush and we need to |
| @@ -305,9 +307,12 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | |||
| 305 | /* | 307 | /* |
| 306 | * Allocate a suitably sized-bio. | 308 | * Allocate a suitably sized-bio. |
| 307 | */ | 309 | */ |
| 308 | num_bvecs = dm_sector_div_up(remaining, | 310 | if (rw & REQ_DISCARD) |
| 309 | (PAGE_SIZE >> SECTOR_SHIFT)); | 311 | num_bvecs = 1; |
| 310 | num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); | 312 | else |
| 313 | num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), | ||
| 314 | dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT))); | ||
| 315 | |||
| 311 | bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); | 316 | bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); |
| 312 | bio->bi_sector = where->sector + (where->count - remaining); | 317 | bio->bi_sector = where->sector + (where->count - remaining); |
| 313 | bio->bi_bdev = where->bdev; | 318 | bio->bi_bdev = where->bdev; |
| @@ -315,10 +320,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | |||
| 315 | bio->bi_destructor = dm_bio_destructor; | 320 | bio->bi_destructor = dm_bio_destructor; |
| 316 | store_io_and_region_in_bio(bio, io, region); | 321 | store_io_and_region_in_bio(bio, io, region); |
| 317 | 322 | ||
| 318 | /* | 323 | if (rw & REQ_DISCARD) { |
| 319 | * Try and add as many pages as possible. | 324 | discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining); |
| 320 | */ | 325 | bio->bi_size = discard_sectors << SECTOR_SHIFT; |
| 321 | while (remaining) { | 326 | remaining -= discard_sectors; |
| 327 | } else while (remaining) { | ||
| 328 | /* | ||
| 329 | * Try and add as many pages as possible. | ||
| 330 | */ | ||
| 322 | dp->get_page(dp, &page, &len, &offset); | 331 | dp->get_page(dp, &page, &len, &offset); |
| 323 | len = min(len, to_bytes(remaining)); | 332 | len = min(len, to_bytes(remaining)); |
| 324 | if (!bio_add_page(bio, page, len, offset)) | 333 | if (!bio_add_page(bio, page, len, offset)) |
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 31c2dc25886d..1ce84ed0b765 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
| @@ -1437,7 +1437,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size) | |||
| 1437 | 1437 | ||
| 1438 | if (!argc) { | 1438 | if (!argc) { |
| 1439 | DMWARN("Empty message received."); | 1439 | DMWARN("Empty message received."); |
| 1440 | goto out; | 1440 | goto out_argv; |
| 1441 | } | 1441 | } |
| 1442 | 1442 | ||
| 1443 | table = dm_get_live_table(md); | 1443 | table = dm_get_live_table(md); |
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 86cb7e5d83d5..787022c18187 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
| @@ -668,7 +668,14 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev) | |||
| 668 | return ret; | 668 | return ret; |
| 669 | 669 | ||
| 670 | sb = page_address(rdev->sb_page); | 670 | sb = page_address(rdev->sb_page); |
| 671 | if (sb->magic != cpu_to_le32(DM_RAID_MAGIC)) { | 671 | |
| 672 | /* | ||
| 673 | * Two cases that we want to write new superblocks and rebuild: | ||
| 674 | * 1) New device (no matching magic number) | ||
| 675 | * 2) Device specified for rebuild (!In_sync w/ offset == 0) | ||
| 676 | */ | ||
| 677 | if ((sb->magic != cpu_to_le32(DM_RAID_MAGIC)) || | ||
| 678 | (!test_bit(In_sync, &rdev->flags) && !rdev->recovery_offset)) { | ||
| 672 | super_sync(rdev->mddev, rdev); | 679 | super_sync(rdev->mddev, rdev); |
| 673 | 680 | ||
| 674 | set_bit(FirstUse, &rdev->flags); | 681 | set_bit(FirstUse, &rdev->flags); |
| @@ -745,11 +752,8 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev) | |||
| 745 | */ | 752 | */ |
| 746 | rdev_for_each(r, t, mddev) { | 753 | rdev_for_each(r, t, mddev) { |
| 747 | if (!test_bit(In_sync, &r->flags)) { | 754 | if (!test_bit(In_sync, &r->flags)) { |
| 748 | if (!test_bit(FirstUse, &r->flags)) | 755 | DMINFO("Device %d specified for rebuild: " |
| 749 | DMERR("Superblock area of " | 756 | "Clearing superblock", r->raid_disk); |
| 750 | "rebuild device %d should have been " | ||
| 751 | "cleared.", r->raid_disk); | ||
| 752 | set_bit(FirstUse, &r->flags); | ||
| 753 | rebuilds++; | 757 | rebuilds++; |
| 754 | } else if (test_bit(FirstUse, &r->flags)) | 758 | } else if (test_bit(FirstUse, &r->flags)) |
| 755 | new_devs++; | 759 | new_devs++; |
| @@ -971,6 +975,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
| 971 | 975 | ||
| 972 | INIT_WORK(&rs->md.event_work, do_table_event); | 976 | INIT_WORK(&rs->md.event_work, do_table_event); |
| 973 | ti->private = rs; | 977 | ti->private = rs; |
| 978 | ti->num_flush_requests = 1; | ||
| 974 | 979 | ||
| 975 | mutex_lock(&rs->md.reconfig_mutex); | 980 | mutex_lock(&rs->md.reconfig_mutex); |
| 976 | ret = md_run(&rs->md); | 981 | ret = md_run(&rs->md); |
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 59c4f0446ffa..237571af77fd 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
| @@ -385,6 +385,7 @@ static int init_pmd(struct dm_pool_metadata *pmd, | |||
| 385 | data_sm = dm_sm_disk_create(tm, nr_blocks); | 385 | data_sm = dm_sm_disk_create(tm, nr_blocks); |
| 386 | if (IS_ERR(data_sm)) { | 386 | if (IS_ERR(data_sm)) { |
| 387 | DMERR("sm_disk_create failed"); | 387 | DMERR("sm_disk_create failed"); |
| 388 | dm_tm_unlock(tm, sblock); | ||
| 388 | r = PTR_ERR(data_sm); | 389 | r = PTR_ERR(data_sm); |
| 389 | goto bad; | 390 | goto bad; |
| 390 | } | 391 | } |
| @@ -789,6 +790,11 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd) | |||
| 789 | return 0; | 790 | return 0; |
| 790 | } | 791 | } |
| 791 | 792 | ||
| 793 | /* | ||
| 794 | * __open_device: Returns @td corresponding to device with id @dev, | ||
| 795 | * creating it if @create is set and incrementing @td->open_count. | ||
| 796 | * On failure, @td is undefined. | ||
| 797 | */ | ||
| 792 | static int __open_device(struct dm_pool_metadata *pmd, | 798 | static int __open_device(struct dm_pool_metadata *pmd, |
| 793 | dm_thin_id dev, int create, | 799 | dm_thin_id dev, int create, |
| 794 | struct dm_thin_device **td) | 800 | struct dm_thin_device **td) |
| @@ -799,10 +805,16 @@ static int __open_device(struct dm_pool_metadata *pmd, | |||
| 799 | struct disk_device_details details_le; | 805 | struct disk_device_details details_le; |
| 800 | 806 | ||
| 801 | /* | 807 | /* |
| 802 | * Check the device isn't already open. | 808 | * If the device is already open, return it. |
| 803 | */ | 809 | */ |
| 804 | list_for_each_entry(td2, &pmd->thin_devices, list) | 810 | list_for_each_entry(td2, &pmd->thin_devices, list) |
| 805 | if (td2->id == dev) { | 811 | if (td2->id == dev) { |
| 812 | /* | ||
| 813 | * May not create an already-open device. | ||
| 814 | */ | ||
| 815 | if (create) | ||
| 816 | return -EEXIST; | ||
| 817 | |||
| 806 | td2->open_count++; | 818 | td2->open_count++; |
| 807 | *td = td2; | 819 | *td = td2; |
| 808 | return 0; | 820 | return 0; |
| @@ -817,6 +829,9 @@ static int __open_device(struct dm_pool_metadata *pmd, | |||
| 817 | if (r != -ENODATA || !create) | 829 | if (r != -ENODATA || !create) |
| 818 | return r; | 830 | return r; |
| 819 | 831 | ||
| 832 | /* | ||
| 833 | * Create new device. | ||
| 834 | */ | ||
| 820 | |||
