f5d4320 Fix for deb9 SCSI drives

Authored and Committed by Dakota Williams 3 years ago
1 file changed. 15 lines added. 2 lines removed.
    Fix for deb9 SCSI drives
    
    The last fix to `__DATTOBD_PASSTHROUGH` worked fine for all major distro
    kernels except Debian 9, on kernel 4.9. This time in kernel history
    (after 4.7 and before 4.10), there was a transition in `struct bio` with
    how it was processing opcodes and flags; it moved from `bi_rw` to `bi_opf`.
    `bi_rw` was a bitfield of a bunch of flags, and many of the higher bits went
    unused. We decided to take advantage of this and plop our flag in these
    bits. This worked fine until the transition to `bi_opf` happened. `enum req_op`
    defined opcodes for struct bio and the value of that enum saturated the
    top 3 bits in `bi_opf`. This change is the root cause of our problem, but
    more on that later. In 4.10, the space allocated to `enum req_op` in `bi_opf`
    was too small, so the allocation expanded to a full byte and `enum req_opf`
    was created to list the new opcodes. Luckily, all 8 bits have not been
    saturated yet, so bit 30 is still unused.
    
    Bit 30 in the `enum req_op` era would place the bit smack dab in the
    middle of the opcode portion of `bi_opf`. So what does this have to do
    with SCSI drives? `REQ_OP_SECURE_ERASE` is an ATA command for "securely"
    erasing disk blocks. ATA is a newer standard than SCSI, and SCSI doesn't
    support the command. `REQ_OP_SECURE_ERASE` has an enum value of 3.
    `REQ_OP_WRITE` has an enum value of 1. Since `enum req_op` holds the top
    3 bits in `bi_opf`, a write looks like this: `0 0 1 (bit 28 ... bit 0)`.
    Flipping bit 30 would change this write to look like: `0 1 1 (bit 28 ...
    bit 0)`, which is the opcode to REQ_OP_SECURE_ERASE. Every time we'd
    apply the passthrough bit on writes, it would turn it into a secure
    erase, and then sd_mod would throw a tantrum because it wouldn't know
    what to do about the opcode. More frighteningly, this would still happen
    on non-SCSI drives silently because it *would* know what to do with
    the opcode, potentially causing data loss during a snapshot.
    
        
file modified
+15 -2