• Filipe Manana's avatar
    btrfs: log conflicting inodes without holding log mutex of the initial inode · e09d94c9
    Filipe Manana authored
    When logging an inode, if we detect the inode has a reference that
    conflicts with some other inode that got renamed, we log that other inode
    while holding the log mutex of the current inode. We then find out if
    there are other inodes that conflict with the first conflicting inode,
    and log them while under the log mutex of the original inode. This is
    fine because the recursion can only happen once.
    
    For the upcoming work where we directly log delayed items without flushing
    them first to the subvolume tree, this recursion adds a lot of complexity
    and it's hard to keep lockdep happy about it.
    
    So collect a list of conflicting inodes and then log the inodes after
    unlocking the log mutex of the inode we started with.
    
    Also limit the maximum number of conflict inodes we log to 10, to avoid
    spending too much time logging (and maybe allocating too many list
    elements too), as typically we don't have more than 1 or 2 conflicting
    inodes - if we go over the limit, simply fallback to a transaction commit.
    
    It is possible to have a very long list of conflicting inodes to be
    intentionally created by a user if he/she creates a very long succession
    of renames like this:
    
      (...)
      rename E to F
      rename D to E
      rename C to D
      rename B to C
      rename A to B
      touch A (create a new file named A)
      fsync A
    
    If that happened for a sequence of hundreds or thousands of renames, it
    could massively slow down the logging and cause other secondary effects
    like for example blocking other fsync operations and transaction commits
    for a very long time (assuming it wouldn't run into -ENOSPC or -ENOMEM
    first). However such cases are very uncommon to happen in practice,
    nevertheless it's better to be prepared for them and avoid chaos.
    Such long sequence of conflicting inodes could be created before this
    change.
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    e09d94c9
tree-log.h 3.29 KB