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 f8b389fda2537..42f6065c7d48b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1320,6 +1320,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 61fa2e4cdfdab..b4d9d6518b4fe 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 ed5c77d568843..520e4761fa0f1 100644 --- a/include/scsi/scsi_multipath.h +++ b/include/scsi/scsi_multipath.h @@ -45,6 +45,7 @@ struct scsi_mpath_device { #define to_scsi_mpath_head(d) \ container_of(d, struct scsi_mpath_head, mpath_head) +blk_status_t scsi_mpath_setup_scsi_cmnd(struct scsi_cmnd *scmd); int scsi_mpath_dev_alloc(struct scsi_device *sdev); void scsi_mpath_dev_release(struct scsi_device *sdev); int scsi_multipath_init(void); @@ -64,6 +65,10 @@ struct scsi_mpath_head { struct scsi_mpath_device { }; +static inline blk_status_t scsi_mpath_setup_scsi_cmnd(struct scsi_cmnd *scmd) +{ + return BLK_STS_OK; +} static inline int scsi_mpath_dev_alloc(struct scsi_device *sdev) { return 0; -- 2.43.7

