Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 156199
b: refs/heads/master
c: ac5e711
h: refs/heads/master
i:
  156197: 198369a
  156195: 396451e
  156191: 6ed6f50
v: v3
  • Loading branch information
Andre Noll authored and NeilBrown committed Aug 3, 2009
1 parent c536a20 commit d54e9bf
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 95fc17aac45300f45968aacd97a536ddd8db8101
refs/heads/master: ac5e7113e74872928844d00085bd47c988f12728
1 change: 1 addition & 0 deletions trunk/drivers/md/linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ static int linear_run (mddev_t *mddev)
mddev->queue->unplug_fn = linear_unplug;
mddev->queue->backing_dev_info.congested_fn = linear_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
md_integrity_register(mddev);
return 0;
}

Expand Down
94 changes: 64 additions & 30 deletions trunk/drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -1487,37 +1487,76 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)

static LIST_HEAD(pending_raid_disks);

static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
/*
* Try to register data integrity profile for an mddev
*
* This is called when an array is started and after a disk has been kicked
* from the array. It only succeeds if all working and active component devices
* are integrity capable with matching profiles.
*/
int md_integrity_register(mddev_t *mddev)
{
mdk_rdev_t *rdev, *reference = NULL;

if (list_empty(&mddev->disks))
return 0; /* nothing to do */
if (blk_get_integrity(mddev->gendisk))
return 0; /* already registered */
list_for_each_entry(rdev, &mddev->disks, same_set) {
/* skip spares and non-functional disks */
if (test_bit(Faulty, &rdev->flags))
continue;
if (rdev->raid_disk < 0)
continue;
/*
* If at least one rdev is not integrity capable, we can not
* enable data integrity for the md device.
*/
if (!bdev_get_integrity(rdev->bdev))
return -EINVAL;
if (!reference) {
/* Use the first rdev as the reference */
reference = rdev;
continue;
}
/* does this rdev's profile match the reference profile? */
if (blk_integrity_compare(reference->bdev->bd_disk,
rdev->bdev->bd_disk) < 0)
return -EINVAL;
}
/*
* All component devices are integrity capable and have matching
* profiles, register the common profile for the md device.
*/
if (blk_integrity_register(mddev->gendisk,
bdev_get_integrity(reference->bdev)) != 0) {
printk(KERN_ERR "md: failed to register integrity for %s\n",
mdname(mddev));
return -EINVAL;
}
printk(KERN_NOTICE "md: data integrity on %s enabled\n",
mdname(mddev));
return 0;
}
EXPORT_SYMBOL(md_integrity_register);

/* Disable data integrity if non-capable/non-matching disk is being added */
void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
{
struct mdk_personality *pers = mddev->pers;
struct gendisk *disk = mddev->gendisk;
struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
struct blk_integrity *bi_mddev = blk_get_integrity(disk);
struct blk_integrity *bi_mddev = blk_get_integrity(mddev->gendisk);

/* Data integrity passthrough not supported on RAID 4, 5 and 6 */
if (pers && pers->level >= 4 && pers->level <= 6)
if (!bi_mddev) /* nothing to do */
return;

/* If rdev is integrity capable, register profile for mddev */
if (!bi_mddev && bi_rdev) {
if (blk_integrity_register(disk, bi_rdev))
printk(KERN_ERR "%s: %s Could not register integrity!\n",
__func__, disk->disk_name);
else
printk(KERN_NOTICE "Enabling data integrity on %s\n",
disk->disk_name);
if (rdev->raid_disk < 0) /* skip spares */
return;
}

/* Check that mddev and rdev have matching profiles */
if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
disk->disk_name, rdev->bdev->bd_disk->disk_name);
printk(KERN_NOTICE "Disabling data integrity on %s\n",
disk->disk_name);
blk_integrity_unregister(disk);
}
if (bi_rdev && blk_integrity_compare(mddev->gendisk,
rdev->bdev->bd_disk) >= 0)
return;
printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev));
blk_integrity_unregister(mddev->gendisk);
}
EXPORT_SYMBOL(md_integrity_add_rdev);

static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
Expand Down Expand Up @@ -1591,7 +1630,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
/* May as well allow recovery to be retried once */
mddev->recovery_disabled = 0;

md_integrity_check(rdev, mddev);
return 0;

fail:
Expand Down Expand Up @@ -4048,10 +4086,6 @@ static int do_md_run(mddev_t * mddev)
}
strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));

if (pers->level >= 4 && pers->level <= 6)
/* Cannot support integrity (yet) */
blk_integrity_unregister(mddev->gendisk);

if (mddev->reshape_position != MaxSector &&
pers->start_reshape == NULL) {
/* This personality cannot handle reshaping... */
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/md/md.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,5 +431,7 @@ extern int md_allow_write(mddev_t *mddev);
extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
extern int md_check_no_bitmap(mddev_t *mddev);
extern int md_integrity_register(mddev_t *mddev);
void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev);

#endif /* _MD_MD_H */
5 changes: 4 additions & 1 deletion trunk/drivers/md/multipath.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
set_bit(In_sync, &rdev->flags);
rcu_assign_pointer(p->rdev, rdev);
err = 0;
md_integrity_add_rdev(rdev, mddev);
break;
}

Expand Down Expand Up @@ -345,7 +346,9 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
/* lost the race, try later */
err = -EBUSY;
p->rdev = rdev;
goto abort;
}
md_integrity_register(mddev);
}
abort:

Expand Down Expand Up @@ -519,7 +522,7 @@ static int multipath_run (mddev_t *mddev)
mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->backing_dev_info.congested_fn = multipath_congested;
mddev->queue->backing_dev_info.congested_data = mddev;

md_integrity_register(mddev);
return 0;

out_free_conf:
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/md/raid0.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ static int raid0_run(mddev_t *mddev)

blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec);
dump_zones(mddev);
md_integrity_register(mddev);
return 0;
}

Expand Down
6 changes: 4 additions & 2 deletions trunk/drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
rcu_assign_pointer(p->rdev, rdev);
break;
}

md_integrity_add_rdev(rdev, mddev);
print_conf(conf);
return err;
}
Expand Down Expand Up @@ -1178,7 +1178,9 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
/* lost the race, try later */
err = -EBUSY;
p->rdev = rdev;
goto abort;
}
md_integrity_register(mddev);
}
abort:

Expand Down Expand Up @@ -2067,7 +2069,7 @@ static int run(mddev_t *mddev)
mddev->queue->unplug_fn = raid1_unplug;
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
mddev->queue->backing_dev_info.congested_data = mddev;

md_integrity_register(mddev);
return 0;

out_no_mem:
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
break;
}

md_integrity_add_rdev(rdev, mddev);
print_conf(conf);
return err;
}
Expand Down Expand Up @@ -1203,7 +1204,9 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
/* lost the race, try later */
err = -EBUSY;
p->rdev = rdev;
goto abort;
}
md_integrity_register(mddev);
}
abort:

Expand Down Expand Up @@ -2225,6 +2228,7 @@ static int run(mddev_t *mddev)

if (conf->near_copies < mddev->raid_disks)
blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec);
md_integrity_register(mddev);
return 0;

out_free_conf:
Expand Down

0 comments on commit d54e9bf

Please sign in to comment.