• Theodore Ts'o's avatar
    ext4/jbd2: don't wait (forever) for stale tid caused by wraparound · bf170962
    Theodore Ts'o authored
    commit d76a3a77 upstream.
    
    In the case where an inode has a very stale transaction id (tid) in
    i_datasync_tid or i_sync_tid, it's possible that after a very large
    (2**31) number of transactions, that the tid number space might wrap,
    causing tid_geq()'s calculations to fail.
    
    Commit deeeaf13 "jbd2: fix fsync() tid wraparound bug", later modified
    by commit e7b04ac0 "jbd2: don't wake kjournald unnecessarily",
    attempted to fix this problem, but it only avoided kjournald spinning
    forever by fixing the logic in jbd2_log_start_commit().
    
    Unfortunately, in the codepaths in fs/ext4/fsync.c and fs/ext4/inode.c
    that might call jbd2_log_start_commit() with a stale tid, those
    functions will subsequently call jbd2_log_wait_commit() with the same
    stale tid, and then wait for a very long time.  To fix this, we
    replace the calls to jbd2_log_start_commit() and
    jbd2_log_wait_commit() with a call to a new function,
    jbd2_complete_transaction(), which will correctly handle stale tid's.
    
    As a bonus, jbd2_complete_transaction() will avoid locking
    j_state_lock for writing unless a commit needs to be started.  This
    should have a small (but probably not measurable) improvement for
    ext4's scalability.
    Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
    Reported-by: default avatarBen Hutchings <ben@decadent.org.uk>
    Reported-by: default avatarGeorge Barnett <gbarnett@atlassian.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    bf170962
inode.c 146 KB