|
@@ -1533,18 +1533,14 @@ out:
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
|
|
-static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
|
|
|
|
- unsigned long arg)
|
|
|
|
|
|
+static int multipath_prepare_ioctl(struct dm_target *ti,
|
|
|
|
+ struct block_device **bdev, fmode_t *mode)
|
|
{
|
|
{
|
|
struct multipath *m = ti->private;
|
|
struct multipath *m = ti->private;
|
|
struct pgpath *pgpath;
|
|
struct pgpath *pgpath;
|
|
- struct block_device *bdev;
|
|
|
|
- fmode_t mode;
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int r;
|
|
int r;
|
|
|
|
|
|
- bdev = NULL;
|
|
|
|
- mode = 0;
|
|
|
|
r = 0;
|
|
r = 0;
|
|
|
|
|
|
spin_lock_irqsave(&m->lock, flags);
|
|
spin_lock_irqsave(&m->lock, flags);
|
|
@@ -1555,23 +1551,17 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
|
|
pgpath = m->current_pgpath;
|
|
pgpath = m->current_pgpath;
|
|
|
|
|
|
if (pgpath) {
|
|
if (pgpath) {
|
|
- bdev = pgpath->path.dev->bdev;
|
|
|
|
- mode = pgpath->path.dev->mode;
|
|
|
|
|
|
+ *bdev = pgpath->path.dev->bdev;
|
|
|
|
+ *mode = pgpath->path.dev->mode;
|
|
}
|
|
}
|
|
|
|
|
|
if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
|
|
if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
|
|
r = -ENOTCONN;
|
|
r = -ENOTCONN;
|
|
- else if (!bdev)
|
|
|
|
|
|
+ else if (!*bdev)
|
|
r = -EIO;
|
|
r = -EIO;
|
|
|
|
|
|
spin_unlock_irqrestore(&m->lock, flags);
|
|
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);
|
|
|
|
-
|
|
|
|
if (r == -ENOTCONN && !fatal_signal_pending(current)) {
|
|
if (r == -ENOTCONN && !fatal_signal_pending(current)) {
|
|
spin_lock_irqsave(&m->lock, flags);
|
|
spin_lock_irqsave(&m->lock, flags);
|
|
if (!m->current_pg) {
|
|
if (!m->current_pg) {
|
|
@@ -1584,7 +1574,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
|
|
dm_table_run_md_queue_async(m->ti->table);
|
|
dm_table_run_md_queue_async(m->ti->table);
|
|
}
|
|
}
|
|
|
|
|
|
- return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Only pass ioctls through if the device sizes match exactly.
|
|
|
|
+ */
|
|
|
|
+ if (!r && ti->len != i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT)
|
|
|
|
+ return 1;
|
|
|
|
+ return r;
|
|
}
|
|
}
|
|
|
|
|
|
static int multipath_iterate_devices(struct dm_target *ti,
|
|
static int multipath_iterate_devices(struct dm_target *ti,
|
|
@@ -1700,7 +1695,7 @@ static struct target_type multipath_target = {
|
|
.resume = multipath_resume,
|
|
.resume = multipath_resume,
|
|
.status = multipath_status,
|
|
.status = multipath_status,
|
|
.message = multipath_message,
|
|
.message = multipath_message,
|
|
- .ioctl = multipath_ioctl,
|
|
|
|
|
|
+ .prepare_ioctl = multipath_prepare_ioctl,
|
|
.iterate_devices = multipath_iterate_devices,
|
|
.iterate_devices = multipath_iterate_devices,
|
|
.busy = multipath_busy,
|
|
.busy = multipath_busy,
|
|
};
|
|
};
|