• Brian Foster's avatar
    xfs: track and serialize in-flight async buffers against unmount · 9c7504aa
    Brian Foster authored
    Newly allocated XFS metadata buffers are added to the LRU once the hold
    count is released, which typically occurs after I/O completion. There is
    no other mechanism at current that tracks the existence or I/O state of
    a new buffer. Further, readahead I/O tends to be submitted
    asynchronously by nature, which means the I/O can remain in flight and
    actually complete long after the calling context is gone. This means
    that file descriptors or any other holds on the filesystem can be
    released, allowing the filesystem to be unmounted while I/O is still in
    flight. When I/O completion occurs, core data structures may have been
    freed, causing completion to run into invalid memory accesses and likely
    to panic.
    
    This problem is reproduced on XFS via directory readahead. A filesystem
    is mounted, a directory is opened/closed and the filesystem immediately
    unmounted. The open/close cycle triggers a directory readahead that if
    delayed long enough, runs buffer I/O completion after the unmount has
    completed.
    
    To address this problem, add a mechanism to track all in-flight,
    asynchronous buffers using per-cpu counters in the buftarg. The buffer
    is accounted on the first I/O submission after the current reference is
    acquired and unaccounted once the buffer is returned to the LRU or
    freed. Update xfs_wait_buftarg() to wait on all in-flight I/O before
    walking the LRU list. Once in-flight I/O has completed and the workqueue
    has drained, all new buffers should have been released onto the LRU.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    
    9c7504aa
xfs_buf.c 46.7 KB