• Sage Weil's avatar
    Btrfs: fix ioctl-initiated transactions vs wait_current_trans() · 9ca9ee09
    Sage Weil authored
    
    
    Commit 597:466b27332893 (btrfs_start_transaction: wait for commits in
    progress) breaks the transaction start/stop ioctls by making
    btrfs_start_transaction conditionally wait for the next transaction to
    start.  If an application artificially is holding a transaction open,
    things deadlock.
    
    This workaround maintains a count of open ioctl-initiated transactions in
    fs_info, and avoids wait_current_trans() if any are currently open (in
    start_transaction() and btrfs_throttle()).  The start transaction ioctl
    uses a new btrfs_start_ioctl_transaction() that _does_ call
    wait_current_trans(), effectively pushing the join/wait decision to the
    outer ioctl-initiated transaction.
    
    This more or less neuters btrfs_throttle() when ioctl-initiated
    transactions are in use, but that seems like a pretty fundamental
    consequence of wrapping lots of write()'s in a transaction.  Btrfs has no
    way to tell if the application considers a given operation as part of it's
    transaction.
    
    Obviously, if the transaction start/stop ioctls aren't being used, there
    is no effect on current behavior.
    
    Signed-off-by: default avatarSage Weil <sage@newdream.net>
    ---
     ctree.h       |    1 +
     ioctl.c       |   12 +++++++++++-
     transaction.c |   18 +++++++++++++-----
     transaction.h |    2 ++
     4 files changed, 27 insertions(+), 6 deletions(-)
    
    Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
    9ca9ee09