As described by Benjamin in the following link, PR support for SCSI is quite complicated: https://lore.kernel.org/linux-scsi/[email protected]/
For initial scsi-multipath support, just don't support PRs. This means that we need to intercept PR SCSI commands for passthrough and reject them. Signed-off-by: John Garry <[email protected]> --- drivers/scsi/scsi_lib.c | 6 ++++++ drivers/scsi/scsi_multipath.c | 11 +++++++++++ include/scsi/scsi_multipath.h | 5 +++++ 3 files changed, 22 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 46ed669c41dc9..c3c6831af97dc 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1296,6 +1296,12 @@ static blk_status_t scsi_setup_scsi_cmnd(struct scsi_device *sdev, { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + if (sdev->scsi_mpath_dev) { + blk_status_t ret = scsi_mpath_setup_scsi_cmnd(cmd); + if (ret) + return ret; + } + /* * Passthrough requests may transfer data, in which case they must * a bio attached to them. Or they might contain a SCSI command diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c index a2a21793db895..e0670d353e59f 100644 --- a/drivers/scsi/scsi_multipath.c +++ b/drivers/scsi/scsi_multipath.c @@ -242,6 +242,17 @@ static int scsi_multipath_sdev_init(struct scsi_device *sdev) return 0; } +blk_status_t scsi_mpath_setup_scsi_cmnd(struct scsi_cmnd *scmd) +{ + switch (scmd->cmnd[0]) { + /* Special handling required which is not yet supported */ + case PERSISTENT_RESERVE_IN: + case PERSISTENT_RESERVE_OUT: + return BLK_STS_NOTSUPP; + } + return BLK_STS_OK; +} + static inline void bio_list_add_clone(struct bio_list *bl, struct bio *clone) { diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h index fdbdb0e5d02e0..52c80b0658d61 100644 --- a/include/scsi/scsi_multipath.h +++ b/include/scsi/scsi_multipath.h @@ -43,6 +43,7 @@ struct scsi_mpath_device { #define to_scsi_mpath_device(d) \ container_of(d, struct scsi_mpath_device, mpath_device) +blk_status_t scsi_mpath_setup_scsi_cmnd(struct scsi_cmnd *); int scsi_mpath_dev_alloc(struct scsi_device *sdev); void scsi_mpath_dev_release(struct scsi_device *sdev); int scsi_multipath_init(void); @@ -63,6 +64,10 @@ struct scsi_mpath_head { struct scsi_mpath_device { }; +static inline blk_status_t scsi_mpath_setup_scsi_cmnd(struct scsi_cmnd *) +{ + return BLK_STS_OK; +} static inline int scsi_mpath_dev_alloc(struct scsi_device *sdev) { return 0; -- 2.43.5

