diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-flakey.c | 11 | ||||
-rw-r--r-- | drivers/md/dm-linear.c | 12 | ||||
-rw-r--r-- | drivers/md/dm-mpath.c | 6 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 6 | ||||
-rw-r--r-- | drivers/md/md.c | 7 | ||||
-rw-r--r-- | drivers/md/raid1.c | 11 |
6 files changed, 47 insertions, 6 deletions
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index f84c08029b21..9fb18c147825 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -368,8 +368,17 @@ static int flakey_status(struct dm_target *ti, status_type_t type, static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) { struct flakey_c *fc = ti->private; + struct dm_dev *dev = fc->dev; + int r = 0; - return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg); + /* + * Only pass ioctls through if the device sizes match exactly. + */ + if (fc->start || + ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT) + r = scsi_verify_blk_ioctl(NULL, cmd); + + return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg); } static int flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm, diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 3921e3bb43c1..9728839f844a 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -116,7 +116,17 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) { struct linear_c *lc = (struct linear_c *) ti->private; - return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg); + struct dm_dev *dev = lc->dev; + int r = 0; + + /* + * Only pass ioctls through if the device sizes match exactly. + */ + if (lc->start || + ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT) + r = scsi_verify_blk_ioctl(NULL, cmd); + + return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg); } static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm, diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 5e0090ef4182..801d92d237cf 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1520,6 +1520,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, spin_unlock_irqrestore(&m->lock, flags); + /* + * Only pass ioctls through if the device sizes match exactly. + */ + if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) + r = scsi_verify_blk_ioctl(NULL, cmd); + return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); } diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 8e9132130142..63cc54289aff 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -699,7 +699,7 @@ static int validate_hardware_logical_block_alignment(struct dm_table *table, while (i < dm_table_get_num_targets(table)) { ti = dm_table_get_target(table, i++); - blk_set_default_limits(&ti_limits); + blk_set_stacking_limits(&ti_limits); /* combine all target devices' limits */ if (ti->type->iterate_devices) @@ -1221,10 +1221,10 @@ int dm_calculate_queue_limits(struct dm_table *table, struct queue_limits ti_limits; unsigned i = 0; - blk_set_default_limits(limits); + blk_set_stacking_limits(limits); while (i < dm_table_get_num_targets(table)) { - blk_set_default_limits(&ti_limits); + blk_set_stacking_limits(&ti_limits); ti = dm_table_get_target(table, i++); diff --git a/drivers/md/md.c b/drivers/md/md.c index ca8527fe77eb..9417ae2fa0bb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4666,6 +4666,7 @@ static int md_alloc(dev_t dev, char *name) mddev->queue->queuedata = mddev; blk_queue_make_request(mddev->queue, md_make_request); + blk_set_stacking_limits(&mddev->queue->limits); disk = alloc_disk(1 << shift); if (!disk) { @@ -7382,6 +7383,7 @@ static int remove_and_add_spares(struct mddev *mddev) { struct md_rdev *rdev; int spares = 0; + int removed = 0; mddev->curr_resync_completed = 0; @@ -7395,8 +7397,13 @@ static int remove_and_add_spares(struct mddev *mddev) mddev, rdev) == 0) { sysfs_unlink_rdev(mddev, rdev); rdev->raid_disk = -1; + removed++; } } + if (removed) + sysfs_notify(&mddev->kobj, NULL, + "degraded"); + list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->raid_disk >= 0 && diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index cc24f0cb7ee3..a368db2431a5 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -531,8 +531,17 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect if (test_bit(WriteMostly, &rdev->flags)) { /* Don't balance among write-mostly, just * use the first as a last resort */ - if (best_disk < 0) + if (best_disk < 0) { + if (is_badblock(rdev, this_sector, sectors, + &first_bad, &bad_sectors)) { + if (first_bad < this_sector) + /* Cannot use this */ + continue; + best_good_sectors = first_bad - this_sector; + } else + best_good_sectors = sectors; best_disk = disk; + } continue; } /* This is a reasonable device to use. It might |