mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 23:00:21 +00:00
Just one fix for md in 3.8
dmraid assess redundancy and replacements slightly inaccurately which could lead to some degraded arrays failing to assemble. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIVAwUAUQb0OTnsnt1WYoG5AQJ4qg/8DIs0eWaJWF5lqF8qJBeMQrUDkqe7glqe ezwVlO48uxVzJUxCMd1aZdxjTI/AIvqZ1U5DBC62SlB/RqWlrwIQIIok5odWfnG4 eAII5hUnktWqL4Ksqz4mgdI+WWwSc3JR7verqS4wOvcsN4qU5t8vL6dj2b0cNYCQ I7B+fkMZE1KE4Y2DOf8dEO9gbNIO1ZllZapLRolrsGOr8Ggo1prEoMxBYF5HZNoE J1As2N6NA7/kadtsfkCSs+f//5t1uMZluMjEUe4lDmgeqzqz/93kFmJ2OfSdqO4J wuuTHbCL+NSjjAZuByluSO98O0h87xXGVMv/c7gadVQtOn6I1DA2i4wTaiHOzr4K cdALvbteVCAPYLMA+s8ee6YYbB5pnlblT8FShG+3O6ae1KmbqKex1LlZLpwEoS8y VxI1WCSQbBr/ejAnhxLFQPo5OAcoeHomlZHKPtCBSbwQ0f0pOHHPYlZyX2PtX6hF U9bmtMq0XZulDORdLmIsEEpwzRKQ+b89+RrYXM7AhkJTxRP59RVwqFHy9SybcFBS S5XFKqpCE+ioBvLp9HK189xMe0Nel2g7KWd34v5LcvQ21rzATezAh5TsWIzN3oV8 9/phd6nZa0hhcELykOTmK5b6+ks2tBfEN2FuyKfSq4Z2nz46rfD4wYVTY2+Qjh+D hmUDBgguejo= =bJyL -----END PGP SIGNATURE----- Merge tag 'md-3.8-fixes' of git://neil.brown.name/md Pull dmraid fix from NeilBrown: "Just one fix for md in 3.8 dmraid assess redundancy and replacements slightly inaccurately which could lead to some degraded arrays failing to assemble." * tag 'md-3.8-fixes' of git://neil.brown.name/md: DM-RAID: Fix RAID10's check for sufficient redundancy
This commit is contained in:
commit
f94d4fe0b5
@ -141,3 +141,4 @@ Version History
|
|||||||
1.2.0 Handle creation of arrays that contain failed devices.
|
1.2.0 Handle creation of arrays that contain failed devices.
|
||||||
1.3.0 Added support for RAID 10
|
1.3.0 Added support for RAID 10
|
||||||
1.3.1 Allow device replacement/rebuild for RAID 10
|
1.3.1 Allow device replacement/rebuild for RAID 10
|
||||||
|
1.3.2 Fix/improve redundancy checking for RAID10
|
||||||
|
@ -340,24 +340,22 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* validate_rebuild_devices
|
* validate_raid_redundancy
|
||||||
* @rs
|
* @rs
|
||||||
*
|
*
|
||||||
* Determine if the devices specified for rebuild can result in a valid
|
* Determine if there are enough devices in the array that haven't
|
||||||
* usable array that is capable of rebuilding the given devices.
|
* failed (or are being rebuilt) to form a usable array.
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -EINVAL on failure.
|
* Returns: 0 on success, -EINVAL on failure.
|
||||||
*/
|
*/
|
||||||
static int validate_rebuild_devices(struct raid_set *rs)
|
static int validate_raid_redundancy(struct raid_set *rs)
|
||||||
{
|
{
|
||||||
unsigned i, rebuild_cnt = 0;
|
unsigned i, rebuild_cnt = 0;
|
||||||
unsigned rebuilds_per_group, copies, d;
|
unsigned rebuilds_per_group, copies, d;
|
||||||
|
|
||||||
if (!(rs->print_flags & DMPF_REBUILD))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < rs->md.raid_disks; i++)
|
for (i = 0; i < rs->md.raid_disks; i++)
|
||||||
if (!test_bit(In_sync, &rs->dev[i].rdev.flags))
|
if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
|
||||||
|
!rs->dev[i].rdev.sb_page)
|
||||||
rebuild_cnt++;
|
rebuild_cnt++;
|
||||||
|
|
||||||
switch (rs->raid_type->level) {
|
switch (rs->raid_type->level) {
|
||||||
@ -393,27 +391,24 @@ static int validate_rebuild_devices(struct raid_set *rs)
|
|||||||
* A A B B C
|
* A A B B C
|
||||||
* C D D E E
|
* C D D E E
|
||||||
*/
|
*/
|
||||||
rebuilds_per_group = 0;
|
|
||||||
for (i = 0; i < rs->md.raid_disks * copies; i++) {
|
for (i = 0; i < rs->md.raid_disks * copies; i++) {
|
||||||
|
if (!(i % copies))
|
||||||
|
rebuilds_per_group = 0;
|
||||||
d = i % rs->md.raid_disks;
|
d = i % rs->md.raid_disks;
|
||||||
if (!test_bit(In_sync, &rs->dev[d].rdev.flags) &&
|
if ((!rs->dev[d].rdev.sb_page ||
|
||||||
|
!test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
|
||||||
(++rebuilds_per_group >= copies))
|
(++rebuilds_per_group >= copies))
|
||||||
goto too_many;
|
goto too_many;
|
||||||
if (!((i + 1) % copies))
|
|
||||||
rebuilds_per_group = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DMERR("The rebuild parameter is not supported for %s",
|
if (rebuild_cnt)
|
||||||
rs->raid_type->name);
|
return -EINVAL;
|
||||||
rs->ti->error = "Rebuild not supported for this RAID type";
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
too_many:
|
too_many:
|
||||||
rs->ti->error = "Too many rebuild devices specified";
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,9 +659,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
|
|||||||
}
|
}
|
||||||
rs->md.dev_sectors = sectors_per_dev;
|
rs->md.dev_sectors = sectors_per_dev;
|
||||||
|
|
||||||
if (validate_rebuild_devices(rs))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Assume there are no metadata devices until the drives are parsed */
|
/* Assume there are no metadata devices until the drives are parsed */
|
||||||
rs->md.persistent = 0;
|
rs->md.persistent = 0;
|
||||||
rs->md.external = 1;
|
rs->md.external = 1;
|
||||||
@ -995,28 +987,10 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev)
|
|||||||
static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
|
static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned redundancy = 0;
|
|
||||||
struct raid_dev *dev;
|
struct raid_dev *dev;
|
||||||
struct md_rdev *rdev, *tmp, *freshest;
|
struct md_rdev *rdev, *tmp, *freshest;
|
||||||
struct mddev *mddev = &rs->md;
|
struct mddev *mddev = &rs->md;
|
||||||
|
|
||||||
switch (rs->raid_type->level) {
|
|
||||||
case 1:
|
|
||||||
redundancy = rs->md.raid_disks - 1;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
redundancy = rs->raid_type->parity_devs;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
redundancy = raid10_md_layout_to_copies(mddev->layout) - 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ti->error = "Unknown RAID type";
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
freshest = NULL;
|
freshest = NULL;
|
||||||
rdev_for_each_safe(rdev, tmp, mddev) {
|
rdev_for_each_safe(rdev, tmp, mddev) {
|
||||||
/*
|
/*
|
||||||
@ -1045,44 +1019,43 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev = container_of(rdev, struct raid_dev, rdev);
|
dev = container_of(rdev, struct raid_dev, rdev);
|
||||||
if (redundancy--) {
|
if (dev->meta_dev)
|
||||||
if (dev->meta_dev)
|
dm_put_device(ti, dev->meta_dev);
|
||||||
dm_put_device(ti, dev->meta_dev);
|
|
||||||
|
|
||||||
dev->meta_dev = NULL;
|
dev->meta_dev = NULL;
|
||||||
rdev->meta_bdev = NULL;
|
rdev->meta_bdev = NULL;
|
||||||
|
|
||||||
if (rdev->sb_page)
|
if (rdev->sb_page)
|
||||||
put_page(rdev->sb_page);
|
put_page(rdev->sb_page);
|
||||||
|
|
||||||
rdev->sb_page = NULL;
|
rdev->sb_page = NULL;
|
||||||
|
|
||||||
rdev->sb_loaded = 0;
|
rdev->sb_loaded = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We might be able to salvage the data device
|
* We might be able to salvage the data device
|
||||||
* even though the meta device has failed. For
|
* even though the meta device has failed. For
|
||||||
* now, we behave as though '- -' had been
|
* now, we behave as though '- -' had been
|
||||||
* set for this device in the table.
|
* set for this device in the table.
|
||||||
*/
|
*/
|
||||||
if (dev->data_dev)
|
if (dev->data_dev)
|
||||||
dm_put_device(ti, dev->data_dev);
|
dm_put_device(ti, dev->data_dev);
|
||||||
|
|
||||||
dev->data_dev = NULL;
|
dev->data_dev = NULL;
|
||||||
rdev->bdev = NULL;
|
rdev->bdev = NULL;
|
||||||
|
|
||||||
list_del(&rdev->same_set);
|
list_del(&rdev->same_set);
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ti->error = "Failed to load superblock";
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!freshest)
|
if (!freshest)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (validate_raid_redundancy(rs)) {
|
||||||
|
rs->ti->error = "Insufficient redundancy to activate array";
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validation of the freshest device provides the source of
|
* Validation of the freshest device provides the source of
|
||||||
* validation for the remaining devices.
|
* validation for the remaining devices.
|
||||||
@ -1432,7 +1405,7 @@ static void raid_resume(struct dm_target *ti)
|
|||||||
|
|
||||||
static struct target_type raid_target = {
|
static struct target_type raid_target = {
|
||||||
.name = "raid",
|
.name = "raid",
|
||||||
.version = {1, 4, 0},
|
.version = {1, 4, 1},
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.ctr = raid_ctr,
|
.ctr = raid_ctr,
|
||||||
.dtr = raid_dtr,
|
.dtr = raid_dtr,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user