• Filipe Manana's avatar
    btrfs: avoid create and commit empty transaction when committing super · cab0d862
    Filipe Manana authored
    At btrfs_commit_super(), called in a few contexts such as when unmounting
    a filesystem, we use btrfs_join_transaction() to catch any running
    transaction and then commit it. This will however create a new and empty
    transaction in case there's no running transaction or there's a running
    transaction with a state >= TRANS_STATE_UNBLOCKED.
    
    As we just want to be sure that any existing transaction is fully
    committed, we can use btrfs_attach_transaction_barrier() instead of
    btrfs_join_transaction(), therefore avoiding the creation and commit of
    empty transactions, which only waste IO and causes rotation of the
    precious backup roots.
    
    Example where we create and commit a pointless empty transaction:
    
      $ mkfs.btrfs -f /dev/sdj
      $ btrfs inspect-internal dump-super /dev/sdj | grep -e '^generation'
      generation            6
    
      $ mount /dev/sdj /mnt/sdj
      $ touch /mnt/sdj/foo
    
      # Commit the currently open transaction. Just 'sync' or wait ~30
      # seconds for the transaction kthread to commit it.
      $ sync
    
      $ btrfs inspect-internal dump-super /dev/sdj | grep -e '^generation'
      generation            7
    
      $ umount /mnt/sdj
    
      $ btrfs inspect-internal dump-super /dev/sdj | grep -e '^generation'
      generation            8
    
    The transaction with id 8 was pointless, an empty transaction that did
    not achieve anything.
    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>
    cab0d862
disk-io.c 138 KB