• John Garry's avatar
    scsi: sd: Atomic write support · bf4ae8f2
    John Garry authored
    Support is divided into two main areas:
    - reading VPD pages and setting sdev request_queue limits
    - support WRITE ATOMIC (16) command and tracing
    
    The relevant block limits VPD page need to be read to allow the block layer
    request_queue atomic write limits to be set. These VPD page limits are
    described in sbc4r22 section 6.6.4 - Block limits VPD page.
    
    There are five limits of interest:
    - MAXIMUM ATOMIC TRANSFER LENGTH
    - ATOMIC ALIGNMENT
    - ATOMIC TRANSFER LENGTH GRANULARITY
    - MAXIMUM ATOMIC TRANSFER LENGTH WITH BOUNDARY
    - MAXIMUM ATOMIC BOUNDARY SIZE
    
    MAXIMUM ATOMIC TRANSFER LENGTH is the maximum length for a WRITE ATOMIC
    (16) command. It will not be greater than the device MAXIMUM TRANSFER
    LENGTH.
    
    ATOMIC ALIGNMENT and ATOMIC TRANSFER LENGTH GRANULARITY are the minimum
    alignment and length values for an atomic write in terms of logical blocks.
    
    Unlike NVMe, SCSI does not specify an LBA space boundary, but does specify
    a per-IO boundary granularity. The maximum boundary size is specified in
    MAXIMUM ATOMIC BOUNDARY SIZE. When used, this boundary value is set in the
    WRITE ATOMIC (16) ATOMIC BOUNDARY field - layout for the WRITE_ATOMIC_16
    command can be found in sbc4r22 section 5.48. This boundary value is the
    granularity size at which the device may atomically write the data. A value
    of zero in WRITE ATOMIC (16) ATOMIC BOUNDARY field means that all data must
    be atomically written together.
    
    MAXIMUM ATOMIC TRANSFER LENGTH WITH BOUNDARY is the maximum atomic write
    length if a non-zero boundary value is set.
    
    For atomic write support, the WRITE ATOMIC (16) boundary is not of much
    interest, as the block layer expects each request submitted to be executed
    atomically. However, the SCSI spec does leave itself open to a quirky
    scenario where MAXIMUM ATOMIC TRANSFER LENGTH is zero, yet MAXIMUM ATOMIC
    TRANSFER LENGTH WITH BOUNDARY and MAXIMUM ATOMIC BOUNDARY SIZE are both
    non-zero. This case will be supported.
    
    To set the block layer request_queue atomic write capabilities, sanitize
    the VPD page limits and set limits as follows:
    - atomic_write_unit_min is derived from granularity and alignment values.
      If no granularity value is not set, use physical block size
    - atomic_write_unit_max is derived from MAXIMUM ATOMIC TRANSFER LENGTH. In
      the scenario where MAXIMUM ATOMIC TRANSFER LENGTH is zero and boundary
      limits are non-zero, use MAXIMUM ATOMIC BOUNDARY SIZE for
      atomic_write_unit_max. New flag scsi_disk.use_atomic_write_boundary is
      set for this scenario.
    - atomic_write_boundary_bytes is set to zero always
    
    SCSI also supports a WRITE ATOMIC (32) command, which is for type 2
    protection enabled. This is not going to be supported now, so check for
    T10_PI_TYPE2_PROTECTION when setting any request_queue limits.
    
    To handle an atomic write request, add support for WRITE ATOMIC (16)
    command in handler sd_setup_atomic_cmnd(). Flag use_atomic_write_boundary
    is checked here for encoding ATOMIC BOUNDARY field.
    
    Trace info is also added for WRITE_ATOMIC_16 command.
    Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: default avatarJohn Garry <john.g.garry@oracle.com>
    Acked-by: default avatarDarrick J. Wong <djwong@kernel.org>
    Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
    Link: https://lore.kernel.org/r/20240620125359.2684798-9-john.g.garry@oracle.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    bf4ae8f2
sd.c 115 KB