[PATCHv3] nvme: module parameter to disable pi with offsets

Keith Busch kbusch at kernel.org
Wed Oct 30 07:18:45 PDT 2024


On Thu, Oct 24, 2024 at 08:49:23AM -0700, Keith Busch wrote:
> +/*
> + * Older kernels didn't enable protection information if it was at an offset.
> + * Newer kernels do, so it breaks reads on the upgrade if such formats were
> + * used in prior kernels since the metadata written did not contain a valid
> + * checksum.
> + */
> +static bool disable_pi_offsets = false;
> +module_param(disable_pi_offsets, bool, 0444);
> +MODULE_PARM_DESC(disable_pi_offsets,
> +	"disable protection information if it has an offset");
> +
>  /*
>   * nvme_wq - hosts nvme related works that are not reset or delete
>   * nvme_reset_wq - hosts nvme reset works
> @@ -1915,6 +1926,8 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl,
>  		head->pi_type = id->dps & NVME_NS_DPS_PI_MASK;
>  	if (!(id->dps & NVME_NS_DPS_PI_FIRST))
>  		info->pi_offset = head->ms - head->pi_size;
> +	if (info->pi_offset && disable_pi)
> +		head->pi_type = 0;

I need to rework this yet again. The old code didn't look for offsets.
It looked for the "first" flag. If you have MS == PI_SIZE, "first" and
"last" mean the exact same thing: there is no offset. But the old code
didn't care, it just wanted to see the PI_FIRST flag.

The part needs to look like this:

---
@@ -1937,10 +1937,12 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl,

        if (head->pi_size && head->ms >= head->pi_size)
                head->pi_type = id->dps & NVME_NS_DPS_PI_MASK;
-       if (!(id->dps & NVME_NS_DPS_PI_FIRST))
-               info->pi_offset = head->ms - head->pi_size;
+       if (!(id->dps & NVME_NS_DPS_PI_FIRST)) {
+               if (disable_pi_offsets)
+                       head->pi_type = 0;
+               else
+                       info->pi_offset = head->ms - head->pi_size;
+       }
--



More information about the Linux-nvme mailing list