Skip to content
  • Dave Chinner's avatar
    xfs: don't dirty buffers beyond EOF · 3430681f
    Dave Chinner authored
    
    
    commit 22e757a49cf010703fcb9c9b4ef793248c39b0c2 upstream.
    
    generic/263 is failing fsx at this point with a page spanning
    EOF that cannot be invalidated. The operations are:
    
    1190 mapwrite   0x52c00 thru    0x5e569 (0xb96a bytes)
    1191 mapread    0x5c000 thru    0x5d636 (0x1637 bytes)
    1192 write      0x5b600 thru    0x771ff (0x1bc00 bytes)
    
    where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO
    write attempts to invalidate the cached page over this range, it
    fails with -EBUSY and so any attempt to do page invalidation fails.
    
    The real question is this: Why can't that page be invalidated after
    it has been written to disk and cleaned?
    
    Well, there's data on the first two buffers in the page (1k block
    size, 4k page), but the third buffer on the page (i.e. beyond EOF)
    is failing drop_buffers because it's bh->b_state == 0x3, which is
    BH_Uptodate | BH_Dirty.  IOWs, there's dirty buffers beyond EOF. Say
    what?
    
    OK, set_buffer_dirty() is called on all buffers from
    __set_page_buffers_dirty(), regardless of whether the buffer is
    beyond EOF or not, which means that when we get to ->writepage,
    we have buffers marked dirty beyond EOF that we need to clean.
    So, we need to implement our own .set_page_dirty method that
    doesn't dirty buffers beyond EOF.
    
    This is messy because the buffer code is not meant to be shared
    and it has interesting locking issues on the buffer dirty bits.
    So just copy and paste it and then modify it to suit what we need.
    
    Note: the solutions the other filesystems and generic block code use
    of marking the buffers clean in ->writepage does not work for XFS.
    It still leaves dirty buffers beyond EOF and invalidations still
    fail. Hence rather than play whack-a-mole, this patch simply
    prevents those buffers from being dirtied in the first place.
    
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    3430681f