Skip to content
  • mwleeds@mailtundra.com's avatar
    zfs: Fix zfs_read() to actually work · 730c69f1
    mwleeds@mailtundra.com authored and Tom Rini's avatar Tom Rini committed
    
    
    Without this patch, the while loop being modified goes on infinitely,
    but with the patch I am able to boot linux on zfs on a jetson tx2 nx.
    
    It seems like this code was never tested because the logic is clearly
    wrong. The function do_div(a,b) does a division that modifies the first
    parameter to have a = a / b, and returns the remainder of the division.
    So clearly in the usual case when file->offset = 0, the line
    "blkid = do_div(blkid, blksz);" just results in blkid being set to zero
    on every iteration of the loop, rather than being incremented as blocks
    are read. Hence the zeroth block is read over and over and this becomes
    an infinite loop.
    
    So instead capture the remainder of the division in a "blkoff" variable,
    and use that to properly calculate the memory address to move from in
    memmove() below.
    
    For example, if file->offset were 1337, on the first iteration of the
    loop blkid would be 0 and blkoff would be 1337. If the blksz is 131072
    (as it was for me), that amount of data would be copied into
    data->file_buf. movesize would be 131072 - 1337 = 129735 so 129735 bytes
    would be moved into buf. On the second iteration of the loop (assuming
    there is one), red would be 129735, blkid would be 1, blkoff would be 0,
    and 131072 bytes would be copied into buf. And so on...
    
    Signed-off-by: default avatarPhaedrus Leeds <mwleeds@mailtundra.com>
    730c69f1