diff options
author | Matthew R. Ochs <mrochs@linux.vnet.ibm.com> | 2015-10-21 20:16:15 (GMT) |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-10-30 08:23:55 (GMT) |
commit | 1a47401bb397183e0500db2c7d5f8d2a3506598e (patch) | |
tree | 484fd193fca6695a44cfbdb0d204eb9bbdfa8fb3 /drivers/scsi/cxlflash/superpipe.h | |
parent | e6e6df3f71a0b567e55d17b08f5bad8f1043afa3 (diff) | |
download | linux-1a47401bb397183e0500db2c7d5f8d2a3506598e.tar.xz |
cxlflash: Fix to avoid corrupting port selection mask
The port selection mask of a LUN can be corrupted when the manage LUN
ioctl (DK_CXLFLASH_MANAGE_LUN) is issued more than once for any device.
This mask indicates to the AFU which port[s] can be used for a data
transfer to/from a particular LUN. The mask is critical to ensuring the
correct behavior when using the virtual LUN function of this adapter.
When the mask is configured for both ports, an I/O may be sent to either
port as the AFU assumes that each port has access to the same physical
device (specified by LUN ID in the port LUN table).
In a situation where the mask becomes incorrectly configured to reflect
access to both ports when in fact there is only access through a single
port, an I/O can be targeted to the wrong physical device. This can lead
to data corruption among other ill effects (e.g. security leaks).
The cause for this corruption is the assumption that the ioctl will only
be called a second time for a LUN when it is being configured for access
via a second port. A boolean 'newly_created' variable is used to
differentiate between a LUN that was created (and subsequently configured
for single port access) and one that is destined for access across both
ports. While initially set to 'true', this sticky boolean is toggled to
the 'false' state during a lookup on any next ioctl performed on a device
with a matching WWN/WWID. The code fails to realize that the match could
in fact be the same device calling in again. From here, an assumption is
made that any LUN with 'newly_created' set to 'false' is configured for
access over both ports and the port selection mask is set to reflect this.
Any future attempts to use this LUN for hosting a virtual LUN will result
in the port LUN table being incorrectly programmed.
As a remedy, the 'newly_created' concept was removed entirely and replaced
with code that always constructs the port selection mask based upon the
SCSI channel of the LUN being accessed. The bits remain sticky, therefore
allowing for a device to be accessed over both ports when that is in fact
the correct physical configuration.
Also included in this commit are a few minor related changes to enhance
the fix and provide better debug information for port selection mask and
port LUN table bugs in the future. These include renaming refresh_local()
to lookup_local(), tracing the WWN/WWID as a big-endian entity, and
tracing the port selection mask, SCSI channel, and LUN ID each time the
port LUN table is programmed.
Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Acked-by: Manoj Kumar <manoj@linux.vnet.ibm.com>
Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/cxlflash/superpipe.h')
-rw-r--r-- | drivers/scsi/cxlflash/superpipe.h | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/drivers/scsi/cxlflash/superpipe.h b/drivers/scsi/cxlflash/superpipe.h index 06a805a..bede574 100644 --- a/drivers/scsi/cxlflash/superpipe.h +++ b/drivers/scsi/cxlflash/superpipe.h @@ -63,7 +63,6 @@ struct llun_info { u32 lun_index; /* Index in the LUN table */ u32 host_no; /* host_no from Scsi_host */ u32 port_sel; /* What port to use for this LUN */ - bool newly_created; /* Whether the LUN was just discovered */ bool in_table; /* Whether a LUN table entry was created */ u8 wwid[16]; /* Keep a duplicate copy here? */ |