• Filipe Manana's avatar
    btrfs: qgroup: avoid start/commit empty transaction when flushing reservations · de18fba8
    Filipe Manana authored
    When flushing reservations we are using btrfs_join_transaction() to get a
    handle for the current transaction and then commit it to try to release
    space. However btrfs_join_transaction() has some undesirable consequences:
    
    1) If there's no running transaction, it will create one, and we will
       commit it right after. This is unnecessary because it will not release
       any space, and it will result in unnecessary IO and rotation of backup
       roots in the superblock;
    
    2) If there's a current transaction and that transaction is committing
       (its state is >= TRANS_STATE_COMMIT_DOING), it will wait for that
       transaction to almost finish its commit (for its state to be >=
       TRANS_STATE_UNBLOCKED) and then start and return a new transaction.
    
       We will then commit that new transaction, which is pointless because
       all we wanted was to wait for the current (previous) transaction to
       fully finish its commit (state == TRANS_STATE_COMPLETED), and by
       starting and committing a new transaction we are wasting IO too and
       causing unnecessary rotation of backup roots in the superblock.
    
    So improve this by using btrfs_attach_transaction_barrier() instead, which
    does not create a new transaction if there's none running, and if there's
    a current transaction that is committing, it will wait for it to fully
    commit and not create a new transaction.
    Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Reviewed-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    de18fba8
qgroup.c 132 KB