On Thu, Nov 27, 2025 at 04:26:51PM +0100, Martin Wilck wrote:
> On Fri, 2025-11-21 at 18:48 -0500, Benjamin Marzinski wrote:
> > If scsi_dh_attached_handler_name() fails to allocate the handler
> > name,
> > dm-multipath (its only caller) assumes there is no attached device
> > handler, and sets the device up incorrectly. Return an error pointer
> > instead, so multipath can distinguish between failure and success
> > where
> > there is no attached device handler.
> >
> > Signed-off-by: Benjamin Marzinski <[email protected]>
> > ---
> > drivers/md/dm-mpath.c | 8 ++++++++
> > drivers/scsi/scsi_dh.c | 8 +++++---
> > 2 files changed, 13 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
> > index c18358271618..063dc526fe04 100644
> > --- a/drivers/md/dm-mpath.c
> > +++ b/drivers/md/dm-mpath.c
> > @@ -950,6 +950,14 @@ static struct pgpath *parse_path(struct
> > dm_arg_set *as, struct path_selector *ps
> >
> > q = bdev_get_queue(p->path.dev->bdev);
> > attached_handler_name = scsi_dh_attached_handler_name(q,
> > GFP_KERNEL);
> > + if (IS_ERR(attached_handler_name)) {
> > + if (PTR_ERR(attached_handler_name) == -ENODEV)
> > + attached_handler_name = NULL;
>
> What's the point of continuing here if we know that the SCSI device
> doesn't exist?
we just know that it's not a SCSI device, so we clear
attached_handler_name. I suppose we could add another check to error
out here if m->hw_handler_name is set. But if it is, the setup_scsi_dh()
call just below will fail anyways, so there's not much difference.
But if you think adding that extra check makes things clearer, I'm fine
with that.
-Ben
> Thanks,
> Martin
>
> > + else {
> > + r = PTR_ERR(attached_handler_name);
> > + goto bad;
> > + }
> > + }
> > if (attached_handler_name || m->hw_handler_name) {
> > INIT_DELAYED_WORK(&p->activate_path,
> > activate_path_work);
> > r = setup_scsi_dh(p->path.dev->bdev, m,
> > &attached_handler_name, &ti->error);
> > diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
> > index 7b56e00c7df6..b9d805317814 100644
> > --- a/drivers/scsi/scsi_dh.c
> > +++ b/drivers/scsi/scsi_dh.c
> > @@ -353,7 +353,8 @@ EXPORT_SYMBOL_GPL(scsi_dh_attach);
> > * that may have a device handler attached
> > * @gfp - the GFP mask used in the kmalloc() call when allocating
> > memory
> > *
> > - * Returns name of attached handler, NULL if no handler is attached.
> > + * Returns name of attached handler, NULL if no handler is attached,
> > or
> > + * and error pointer if an error occurred.
> > * Caller must take care to free the returned string.
> > */
> > const char *scsi_dh_attached_handler_name(struct request_queue *q,
> > gfp_t gfp)
> > @@ -363,10 +364,11 @@ const char
> > *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
> >
> > sdev = scsi_device_from_queue(q);
> > if (!sdev)
> > - return NULL;
> > + return ERR_PTR(-ENODEV);
> >
> > if (sdev->handler)
> > - handler_name = kstrdup(sdev->handler->name, gfp);
> > + handler_name = kstrdup(sdev->handler->name, gfp) ? :
> > + ERR_PTR(-ENOMEM);
> > put_device(&sdev->sdev_gendev);
> > return handler_name;
> > }