• Boaz Harrosh's avatar
    ore: Fix NFS crash by supporting any unaligned RAID IO · 9ff19309
    Boaz Harrosh authored
    In RAID_5/6 We used to not permit an IO that it's end
    byte is not stripe_size aligned and spans more than one stripe.
    .i.e the caller must check if after submission the actual
    transferred bytes is shorter, and would need to resubmit
    a new IO with the remainder.
    Exofs supports this, and NFS was supposed to support this
    as well with it's short write mechanism. But late testing has
    exposed a CRASH when this is used with none-RPC layout-drivers.
    The change at NFS is deep and risky, in it's place the fix
    at ORE to lift the limitation is actually clean and simple.
    So here it is below.
    The principal here is that in the case of unaligned IO on
    both ends, beginning and end, we will send two read requests
    one like old code, before the calculation of the first stripe,
    and also a new site, before the calculation of the last stripe.
    If any "boundary" is aligned or the complete IO is within a single
    stripe. we do a single read like before.
    The code is clean and simple by splitting the old _read_4_write
    into 3 even parts:
    2. _read_4_write_last_stripe
    3. _read_4_write_execute
    And calling 1+3 at the same place as before. 2+3 before last
    stripe, and in the case of all in a single stripe then 1+2+3
    is preformed additively.
    Why did I not think of it before. Well I had a strike of
    genius because I have stared at this code for 2 years, and did
    not find this simple solution, til today. Not that I did not try.
    This solution is much better for NFS than the previous supposedly
    solution because the short write was dealt  with out-of-band after
    IO_done, which would cause for a seeky IO pattern where as in here
    we execute in order. At both solutions we do 2 separate reads, only
    here we do it within a single IO request. (And actually combine two
    writes into a single submission)
    NFS/exofs code need not change since the ORE API communicates the new
    shorter length on return, what will happen is that this case would not
    occur anymore.
    [Stable this is an NFS bug since 3.2 Kernel should apply cleanly]
    CC: Stable Tree <stable@kernel.org>
    Signed-off-by: default avatarBoaz Harrosh <bharrosh@panasas.com>