[{"id":3682447,"web_url":"http://patchwork.ozlabs.org/comment/3682447/","msgid":"<862142af-5620-4f9a-81b9-f13384e653ef@kernel.org>","list_archive_url":null,"date":"2026-04-26T23:25:15","subject":"Re: [PATCH v3 2/7] ata: libata-scsi: convert dev->sdev to per-LUN\n array","submitter":{"id":86188,"url":"http://patchwork.ozlabs.org/api/people/86188/","name":"Damien Le Moal","email":"dlemoal@kernel.org"},"content":"On 4/27/26 4:09 AM, Phil Pemberton wrote:\n> Multi-LUN ATAPI devices (PD/CD combos, CD changers) share a single\n> ata_device but expose multiple scsi_devices.  The previous single\n> dev->sdev pointer could only track one LUN, making all other LUNs\n> invisible to code that operates on sdevs: port detach, suspend/resume,\n> ACPI uevent, ZPODD, media change notification, and EH teardown.\n> \n> Replace the scalar struct scsi_device *sdev with a fixed-size array\n> dev->sdev[ATAPI_MAX_LUN] indexed by LUN number, where ATAPI_MAX_LUN\n> is 8 (the SCSI-2 ceiling, LUN values 0..7).\n> \n> Key changes per call site:\n>   - ata_scsi_dev_config:  assign sdev to dev->sdev[sdev->lun]\n>   - ata_scsi_sdev_destroy: clear dev->sdev[sdev->lun]; only trigger\n>     ATA-level detach when LUN 0 is destroyed, since removing a higher\n>     LUN should not tear down the underlying ATA device\n>   - ata_port_detach:  iterate all LUN slots (high→low)\n>   - ata_scsi_offline_dev:  iterate all LUN slots\n>   - ata_scsi_remove_dev:  snapshot and remove all LUN slots, then\n>     scsi_remove_device each one outside the lock\n>   - ata_scsi_media_change_notify:  send event to all populated LUNs\n>   - ata_scsi_dev_rescan:  resume and rescan each populated LUN\n>   - ACPI, ZPODD, ofnode, door-lock:  use dev->sdev[0] (LUN 0 remains\n>     canonical for ATA-level operations)\n>   - ata_scsi_scan_host:  uses dev->sdev[0] for the existing LUN-0\n>     add/retry path\n> \n> For single-LUN devices (the vast majority), only dev->sdev[0] is ever\n> populated and the additional slots remain NULL.\n\nExactly, and that is why I a not a big fan of this patch as is. The main reason\nis that once we probe the device, we'll know how many LUNs it has, and in the\nvast majority of cases, that will be 1. So I think that instead of having all\nthe loops looking at all possible LUNs with ATAPI_MAX_LUN as the upper\nboundary, we need to add a dev->nr_luns field indicating the number of LUNs\nthat are valid for the device. Again, that will be 1 most of the time, and thus\nwill not add unnecessary overhead for looking at LUNs that do not exist.\n\nThe direct refereincing of dev->sdev[i] is also a little ugly. Having a little\ninline helper like:\n\nstatic inline struct scsi_device *\nata_dev_scsi_device(struct ata_device *dev, unsigned int lun)\n{\n\tif (WARN_ON_ONCE(lun >= dev->nr_luns))\n\t\treturn NULL;\n\treturn dev->sdev[lun];\n}\n\nwould make things cleaner.\n\n> \n> Reviewed-by: Hannes Reinecke <hare@suse.de>\n> Signed-off-by: Phil Pemberton <philpem@philpem.me.uk>\n> ---\n>  drivers/ata/libata-acpi.c  |   4 +-\n>  drivers/ata/libata-core.c  |  10 ++-\n>  drivers/ata/libata-scsi.c  | 146 ++++++++++++++++++-------------------\n>  drivers/ata/libata-zpodd.c |   6 +-\n>  include/linux/libata.h     |   2 +-\n>  5 files changed, 86 insertions(+), 82 deletions(-)\n> \n> diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c\n> index 4433f626246b..d07237f66d98 100644\n> --- a/drivers/ata/libata-acpi.c\n> +++ b/drivers/ata/libata-acpi.c\n> @@ -153,8 +153,8 @@ static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,\n>  \tchar *envp[] = { event_string, NULL };\n>  \n>  \tif (dev) {\n> -\t\tif (dev->sdev)\n> -\t\t\tkobj = &dev->sdev->sdev_gendev.kobj;\n> +\t\tif (dev->sdev[0])\n> +\t\t\tkobj = &dev->sdev[0]->sdev_gendev.kobj;\n>  \t} else\n>  \t\tkobj = &ap->dev->kobj;\n>  \n> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c\n> index 8c279b6eb1fb..f24d38f6ee73 100644\n> --- a/drivers/ata/libata-core.c\n> +++ b/drivers/ata/libata-core.c\n> @@ -6270,11 +6270,15 @@ static void ata_port_detach(struct ata_port *ap)\n>  \t/* Remove scsi devices */\n>  \tata_for_each_link(link, ap, HOST_FIRST) {\n>  \t\tata_for_each_dev(dev, link, ALL) {\n> -\t\t\tif (dev->sdev) {\n> +\t\t\tint lun;\n> +\n> +\t\t\tfor (lun = ATAPI_MAX_LUN - 1; lun >= 0; lun--) {\n> +\t\t\t\tif (!dev->sdev[lun])\n> +\t\t\t\t\tcontinue;\n>  \t\t\t\tspin_unlock_irqrestore(ap->lock, flags);\n> -\t\t\t\tscsi_remove_device(dev->sdev);\n> +\t\t\t\tscsi_remove_device(dev->sdev[lun]);\n>  \t\t\t\tspin_lock_irqsave(ap->lock, flags);\n> -\t\t\t\tdev->sdev = NULL;\n> +\t\t\t\tdev->sdev[lun] = NULL;\n>  \t\t\t}\n>  \t\t}\n>  \t}\n> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c\n> index d1665305b552..317883bac25f 100644\n> --- a/drivers/ata/libata-scsi.c\n> +++ b/drivers/ata/libata-scsi.c\n> @@ -1131,7 +1131,7 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct queue_limits *lim,\n>  \tif (dev->flags & ATA_DFLAG_TRUSTED)\n>  \t\tsdev->security_supported = 1;\n>  \n> -\tdev->sdev = sdev;\n> +\tdev->sdev[sdev->lun] = sdev;\n>  \treturn 0;\n>  }\n>  \n> @@ -1202,10 +1202,10 @@ EXPORT_SYMBOL_GPL(ata_scsi_sdev_configure);\n>   *\n>   *\t@sdev is about to be destroyed for hot/warm unplugging.  If\n>   *\tthis unplugging was initiated by libata as indicated by NULL\n> - *\tdev->sdev, this function doesn't have to do anything.\n> + *\tdev->sdev[], this function doesn't have to do anything.\n>   *\tOtherwise, SCSI layer initiated warm-unplug is in progress.\n> - *\tClear dev->sdev, schedule the device for ATA detach and invoke\n> - *\tEH.\n> + *\tClear the per-LUN slot; when the last LUN (LUN 0) is destroyed,\n> + *\tschedule ATA-level detach via EH.\n>   *\n>   *\tLOCKING:\n>   *\tDefined by SCSI layer.  We don't really care.\n> @@ -1220,11 +1220,12 @@ void ata_scsi_sdev_destroy(struct scsi_device *sdev)\n>  \n>  \tspin_lock_irqsave(ap->lock, flags);\n>  \tdev = __ata_scsi_find_dev(ap, sdev);\n> -\tif (dev && dev->sdev) {\n> -\t\t/* SCSI device already in CANCEL state, no need to offline it */\n> -\t\tdev->sdev = NULL;\n> -\t\tdev->flags |= ATA_DFLAG_DETACH;\n> -\t\tata_port_schedule_eh(ap);\n> +\tif (dev && dev->sdev[sdev->lun] == sdev) {\n> +\t\tdev->sdev[sdev->lun] = NULL;\n> +\t\tif (sdev->lun == 0) {\n> +\t\t\tdev->flags |= ATA_DFLAG_DETACH;\n> +\t\t\tata_port_schedule_eh(ap);\n> +\t\t}\n>  \t}\n>  \tspin_unlock_irqrestore(ap->lock, flags);\n>  \n> @@ -2912,10 +2913,10 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)\n>  \t\t * avoid this infinite loop.\n>  \t\t *\n>  \t\t * This may happen before SCSI scan is complete.  Make\n> -\t\t * sure qc->dev->sdev isn't NULL before dereferencing.\n> +\t\t * sure qc->dev->sdev[0] isn't NULL before dereferencing.\n>  \t\t */\n> -\t\tif (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)\n> -\t\t\tqc->dev->sdev->locked = 0;\n> +\t\tif (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev[0])\n> +\t\t\tqc->dev->sdev[0]->locked = 0;\n>  \n>  \t\tqc->scsicmd->result = SAM_STAT_CHECK_CONDITION;\n>  \t\tata_qc_done(qc);\n> @@ -4651,7 +4652,7 @@ int ata_scsi_add_hosts(struct ata_host *host, const struct scsi_host_template *s\n>  #ifdef CONFIG_OF\n>  static void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap)\n>  {\n> -\tstruct scsi_device *sdev = dev->sdev;\n> +\tstruct scsi_device *sdev = dev->sdev[0];\n>  \tstruct device *d = ap->host->dev;\n>  \tstruct device_node *np = d->of_node;\n>  \tstruct device_node *child;\n> @@ -4689,7 +4690,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)\n>  \t\t\tstruct scsi_device *sdev;\n>  \t\t\tint channel = 0, id = 0;\n>  \n> -\t\t\tif (dev->sdev)\n> +\t\t\tif (dev->sdev[0])\n>  \t\t\t\tcontinue;\n>  \n>  \t\t\tif (ata_is_host_link(link))\n> @@ -4700,11 +4701,11 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)\n>  \t\t\tsdev = __scsi_add_device(ap->scsi_host, channel, id, 0,\n>  \t\t\t\t\t\t NULL);\n>  \t\t\tif (!IS_ERR(sdev)) {\n> -\t\t\t\tdev->sdev = sdev;\n> +\t\t\t\tdev->sdev[0] = sdev;\n>  \t\t\t\tata_scsi_assign_ofnode(dev, ap);\n>  \t\t\t\tscsi_device_put(sdev);\n>  \t\t\t} else {\n> -\t\t\t\tdev->sdev = NULL;\n> +\t\t\t\tdev->sdev[0] = NULL;\n>  \t\t\t}\n>  \t\t}\n>  \t}\n> @@ -4715,7 +4716,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)\n>  \t */\n>  \tata_for_each_link(link, ap, EDGE) {\n>  \t\tata_for_each_dev(dev, link, ENABLED) {\n> -\t\t\tif (!dev->sdev)\n> +\t\t\tif (!dev->sdev[0])\n>  \t\t\t\tgoto exit_loop;\n>  \t\t}\n>  \t}\n> @@ -4756,7 +4757,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)\n>   *\n>   *\tThis function is called from ata_eh_detach_dev() and is responsible for\n>   *\ttaking the SCSI device attached to @dev offline.  This function is\n> - *\tcalled with host lock which protects dev->sdev against clearing.\n> + *\tcalled with host lock which protects dev->sdev[] against clearing.\n>   *\n>   *\tLOCKING:\n>   *\tspin_lock_irqsave(host lock)\n> @@ -4766,11 +4767,16 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)\n>   */\n>  bool ata_scsi_offline_dev(struct ata_device *dev)\n>  {\n> -\tif (dev->sdev) {\n> -\t\tscsi_device_set_state(dev->sdev, SDEV_OFFLINE);\n> -\t\treturn true;\n> +\tbool found = false;\n> +\tint lun;\n> +\n> +\tfor (lun = ATAPI_MAX_LUN - 1; lun >= 0; lun--) {\n> +\t\tif (dev->sdev[lun]) {\n> +\t\t\tscsi_device_set_state(dev->sdev[lun], SDEV_OFFLINE);\n> +\t\t\tfound = true;\n> +\t\t}\n>  \t}\n> -\treturn false;\n> +\treturn found;\n>  }\n>  \n>  /**\n> @@ -4786,49 +4792,38 @@ bool ata_scsi_offline_dev(struct ata_device *dev)\n>  static void ata_scsi_remove_dev(struct ata_device *dev)\n>  {\n>  \tstruct ata_port *ap = dev->link->ap;\n> -\tstruct scsi_device *sdev;\n> +\tstruct scsi_device *sdevs[ATAPI_MAX_LUN] = {};\n>  \tunsigned long flags;\n> +\tint lun;\n>  \n> -\t/* Alas, we need to grab scan_mutex to ensure SCSI device\n> -\t * state doesn't change underneath us and thus\n> -\t * scsi_device_get() always succeeds.  The mutex locking can\n> -\t * be removed if there is __scsi_device_get() interface which\n> -\t * increments reference counts regardless of device state.\n> -\t */\n>  \tmutex_lock(&ap->scsi_host->scan_mutex);\n>  \tspin_lock_irqsave(ap->lock, flags);\n>  \n> -\t/* clearing dev->sdev is protected by host lock */\n> -\tsdev = dev->sdev;\n> -\tdev->sdev = NULL;\n> +\tfor (lun = ATAPI_MAX_LUN - 1; lun >= 0; lun--) {\n> +\t\tstruct scsi_device *sdev = dev->sdev[lun];\n> +\n> +\t\tdev->sdev[lun] = NULL;\n> +\t\tif (!sdev)\n> +\t\t\tcontinue;\n>  \n> -\tif (sdev) {\n> -\t\t/* If user initiated unplug races with us, sdev can go\n> -\t\t * away underneath us after the host lock and\n> -\t\t * scan_mutex are released.  Hold onto it.\n> -\t\t */\n>  \t\tif (scsi_device_get(sdev) == 0) {\n> -\t\t\t/* The following ensures the attached sdev is\n> -\t\t\t * offline on return from ata_scsi_offline_dev()\n> -\t\t\t * regardless it wins or loses the race\n> -\t\t\t * against this function.\n> -\t\t\t */\n>  \t\t\tscsi_device_set_state(sdev, SDEV_OFFLINE);\n> +\t\t\tsdevs[lun] = sdev;\n>  \t\t} else {\n>  \t\t\tWARN_ON(1);\n> -\t\t\tsdev = NULL;\n>  \t\t}\n>  \t}\n>  \n>  \tspin_unlock_irqrestore(ap->lock, flags);\n>  \tmutex_unlock(&ap->scsi_host->scan_mutex);\n>  \n> -\tif (sdev) {\n> +\tfor (lun = ATAPI_MAX_LUN - 1; lun >= 0; lun--) {\n> +\t\tif (!sdevs[lun])\n> +\t\t\tcontinue;\n>  \t\tata_dev_info(dev, \"detaching (SCSI %s)\\n\",\n> -\t\t\t     dev_name(&sdev->sdev_gendev));\n> -\n> -\t\tscsi_remove_device(sdev);\n> -\t\tscsi_device_put(sdev);\n> +\t\t\t     dev_name(&sdevs[lun]->sdev_gendev));\n> +\t\tscsi_remove_device(sdevs[lun]);\n> +\t\tscsi_device_put(sdevs[lun]);\n>  \t}\n>  }\n>  \n> @@ -4865,9 +4860,12 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)\n>   */\n>  void ata_scsi_media_change_notify(struct ata_device *dev)\n>  {\n> -\tif (dev->sdev)\n> -\t\tsdev_evt_send_simple(dev->sdev, SDEV_EVT_MEDIA_CHANGE,\n> -\t\t\t\t     GFP_ATOMIC);\n> +\tint lun;\n> +\n> +\tfor (lun = 0; lun < ATAPI_MAX_LUN; lun++)\n> +\t\tif (dev->sdev[lun])\n> +\t\t\tsdev_evt_send_simple(dev->sdev[lun],\n> +\t\t\t\t\t     SDEV_EVT_MEDIA_CHANGE, GFP_ATOMIC);\n>  }\n>  \n>  /**\n> @@ -5000,37 +4998,39 @@ void ata_scsi_dev_rescan(struct work_struct *work)\n>  \n>  \tata_for_each_link(link, ap, EDGE) {\n>  \t\tata_for_each_dev(dev, link, ENABLED) {\n> -\t\t\tstruct scsi_device *sdev = dev->sdev;\n> +\t\t\tint lun;\n>  \n> -\t\t\t/*\n> -\t\t\t * If the port was suspended before this was scheduled,\n> -\t\t\t * bail out.\n> -\t\t\t */\n>  \t\t\tif (ap->pflags & ATA_PFLAG_SUSPENDED)\n>  \t\t\t\tgoto unlock_ap;\n>  \n> -\t\t\tif (!sdev)\n> -\t\t\t\tcontinue;\n> -\t\t\tif (scsi_device_get(sdev))\n> -\t\t\t\tcontinue;\n> -\n>  \t\t\tdo_resume = dev->flags & ATA_DFLAG_RESUMING;\n>  \n> -\t\t\tspin_unlock_irqrestore(ap->lock, flags);\n> -\t\t\tif (do_resume) {\n> -\t\t\t\tret = scsi_resume_device(sdev);\n> -\t\t\t\tif (ret == -EWOULDBLOCK) {\n> -\t\t\t\t\tscsi_device_put(sdev);\n> -\t\t\t\t\tgoto unlock_scan;\n> +\t\t\tfor (lun = 0; lun < ATAPI_MAX_LUN; lun++) {\n> +\t\t\t\tstruct scsi_device *sdev = dev->sdev[lun];\n> +\n> +\t\t\t\tif (!sdev)\n> +\t\t\t\t\tcontinue;\n> +\t\t\t\tif (scsi_device_get(sdev))\n> +\t\t\t\t\tcontinue;\n> +\n> +\t\t\t\tspin_unlock_irqrestore(ap->lock, flags);\n> +\t\t\t\tif (do_resume) {\n> +\t\t\t\t\tret = scsi_resume_device(sdev);\n> +\t\t\t\t\tif (ret == -EWOULDBLOCK) {\n> +\t\t\t\t\t\tscsi_device_put(sdev);\n> +\t\t\t\t\t\tgoto unlock_scan;\n> +\t\t\t\t\t}\n>  \t\t\t\t}\n> -\t\t\t\tdev->flags &= ~ATA_DFLAG_RESUMING;\n> +\t\t\t\tret = scsi_rescan_device(sdev);\n> +\t\t\t\tscsi_device_put(sdev);\n> +\t\t\t\tspin_lock_irqsave(ap->lock, flags);\n> +\n> +\t\t\t\tif (ret)\n> +\t\t\t\t\tgoto unlock_ap;\n>  \t\t\t}\n> -\t\t\tret = scsi_rescan_device(sdev);\n> -\t\t\tscsi_device_put(sdev);\n> -\t\t\tspin_lock_irqsave(ap->lock, flags);\n>  \n> -\t\t\tif (ret)\n> -\t\t\t\tgoto unlock_ap;\n> +\t\t\tif (do_resume)\n> +\t\t\t\tdev->flags &= ~ATA_DFLAG_RESUMING;\n>  \t\t}\n>  \t}\n>  \n> diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c\n> index 414e7c63bd85..116dd42f8232 100644\n> --- a/drivers/ata/libata-zpodd.c\n> +++ b/drivers/ata/libata-zpodd.c\n> @@ -185,7 +185,7 @@ void zpodd_enable_run_wake(struct ata_device *dev)\n>  {\n>  \tstruct zpodd *zpodd = dev->zpodd;\n>  \n> -\tsdev_disable_disk_events(dev->sdev);\n> +\tsdev_disable_disk_events(dev->sdev[0]);\n>  \n>  \tzpodd->powered_off = true;\n>  \tacpi_pm_set_device_wakeup(&dev->tdev, true);\n> @@ -233,14 +233,14 @@ void zpodd_post_poweron(struct ata_device *dev)\n>  \tzpodd->zp_sampled = false;\n>  \tzpodd->zp_ready = false;\n>  \n> -\tsdev_enable_disk_events(dev->sdev);\n> +\tsdev_enable_disk_events(dev->sdev[0]);\n>  }\n>  \n>  static void zpodd_wake_dev(acpi_handle handle, u32 event, void *context)\n>  {\n>  \tstruct ata_device *ata_dev = context;\n>  \tstruct zpodd *zpodd = ata_dev->zpodd;\n> -\tstruct device *dev = &ata_dev->sdev->sdev_gendev;\n> +\tstruct device *dev = &ata_dev->sdev[0]->sdev_gendev;\n>  \n>  \tif (event == ACPI_NOTIFY_DEVICE_WAKE && pm_runtime_suspended(dev)) {\n>  \t\tzpodd->from_notify = true;\n> diff --git a/include/linux/libata.h b/include/linux/libata.h\n> index 27b11577826e..e2e759d492c7 100644\n> --- a/include/linux/libata.h\n> +++ b/include/linux/libata.h\n> @@ -722,7 +722,7 @@ struct ata_device {\n>  \tunsigned int\t\tdevno;\t\t/* 0 or 1 */\n>  \tu64\t\t\tquirks;\t\t/* List of broken features */\n>  \tunsigned long\t\tflags;\t\t/* ATA_DFLAG_xxx */\n> -\tstruct scsi_device\t*sdev;\t\t/* attached SCSI device */\n> +\tstruct scsi_device\t*sdev[ATAPI_MAX_LUN];\t/* per-LUN SCSI devices */\n>  \tvoid\t\t\t*private_data;\n>  #ifdef CONFIG_ATA_ACPI\n>  \tunion acpi_object\t*gtf_cache;","headers":{"Return-Path":"\n <linux-ide+bounces-5543-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-ide@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=Q8UtPsw3;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-ide+bounces-5543-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"Q8UtPsw3\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g3jWM0PSQz1yJX\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 09:26:22 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id C39223006F01\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 26 Apr 2026 23:25:25 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 834BE315D35;\n\tSun, 26 Apr 2026 23:25:24 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F90922A4FC;\n\tSun, 26 Apr 2026 23:25:24 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id C3DC0C2BCAF;\n\tSun, 26 Apr 2026 23:25:22 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777245924; cv=none;\n b=oq+1V31tNIwpCZC5lBA8MCFtF4XV19R8TyIlYW635QHpGdmFbhk1FB2HgGJIPKxHUMR1dbvufEa4mWc7jHS0qlNW+HgmPfx2sEANdnJhndlWb6GhExvni2j9PJImTniHH45XkP5pT612v1Jmy/MPFwWXyK2EIGa35MBcdHjzXSg=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777245924; c=relaxed/simple;\n\tbh=H38xYiV7xYMM3e5g/FJI1lAKMOobmpQJfWwsl/o9lDk=;\n\th=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From:\n\t In-Reply-To:Content-Type;\n b=X2t5BtLTBXwKx0o395+gVPv5CfPzlpYWkCgP5JmVzply5i9FualhK6PGB/XXSMx4hXlOngHPjU+AKRlQjUDOzmtkdiWjQq51eyF3pfbv/Kew1jJ3mlPufL0rkPdQhIU4w/Ep604E3t8vLDhhPcCGdZrlMdRxOdHJAtFe8p76R2I=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=Q8UtPsw3; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1777245924;\n\tbh=H38xYiV7xYMM3e5g/FJI1lAKMOobmpQJfWwsl/o9lDk=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=Q8UtPsw3ugRpGWq/hJ2ycq882ELg2DhTPQ1wI5PwuYAepYhlsTdvl90v/l3m764Uz\n\t YRXUG7wclDkkKGnOdDtpU412qlF08vf0z8KUA6emWxoS5mDxr1X+A6R+zkcptiSZI1\n\t pa65XazFhks1y8TX/znNlIbyZPWJI4m5ok8D4EHIiScj/pK5MJ3C2F6lkHyYSSwI7q\n\t K1dtFewi7ZUc8Ks0SfbD6v35kieutN3so2YHf7gLq3zCDrz4nc9NaQGQ4xeT5ezy3m\n\t FL/x+BQxCEknLELt9FFqbpFbAB31sJU299ApVzAsIY45N2e8OS3ojd6WbqVEI54lyE\n\t phVI10F/AuZ4g==","Message-ID":"<862142af-5620-4f9a-81b9-f13384e653ef@kernel.org>","Date":"Mon, 27 Apr 2026 08:25:15 +0900","Precedence":"bulk","X-Mailing-List":"linux-ide@vger.kernel.org","List-Id":"<linux-ide.vger.kernel.org>","List-Subscribe":"<mailto:linux-ide+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-ide+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 2/7] ata: libata-scsi: convert dev->sdev to per-LUN\n array","To":"Phil Pemberton <philpem@philpem.me.uk>, linux-ide@vger.kernel.org,\n linux-scsi@vger.kernel.org","Cc":"linux-kernel@vger.kernel.org, Niklas Cassel <cassel@kernel.org>,\n \"James E . J . Bottomley\" <James.Bottomley@HansenPartnership.com>,\n \"Martin K . Petersen\" <martin.petersen@oracle.com>,\n Hannes Reinecke <hare@suse.de>","References":"<20260426190920.2051289-1-philpem@philpem.me.uk>\n <20260426190920.2051289-3-philpem@philpem.me.uk>","Content-Language":"en-US","From":"Damien Le Moal <dlemoal@kernel.org>","Organization":"Western Digital Research","In-Reply-To":"<20260426190920.2051289-3-philpem@philpem.me.uk>","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit"}}]