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>
Showing
Please register or sign in to comment