• Filipe Manana's avatar
    btrfs: hold on to less memory when logging checksums during full fsync · 5b7ce5e2
    Filipe Manana authored
    
    
    When doing a full fsync, at copy_items(), we iterate over all extents and
    then collect their checksums into a list. After copying all the extents to
    the log tree, we then log all the previously collected checksums.
    
    Before the previous patch in the series (subject "btrfs: stop copying old
    file extents when doing a full fsync"), we had to do it this way, because
    while we were iterating over the items in the leaf of the subvolume tree,
    we were holding a write lock on a leaf of the log tree, so logging the
    checksums for an extent right after we collected them could result in a
    deadlock, in case the checksum items ended up in the same leaf.
    
    However after the previous patch in the series we now do a first iteration
    over all the items in the leaf of the subvolume tree before locking a path
    in the log tree, so we can now log the checksums right after we have
    obtained them. This avoids holding in memory all checksums for all extents
    in the leaf while copying items from the source leaf to the log tree. The
    amount of memory used to hold all checksums of the extents in a leaf can
    be significant. For example if a leaf has 200 file extent items referring
    to 1M extents, using the default crc32c checksums, would result in using
    over 200K of memory (not accounting for the extra overhead of struct
    btrfs_ordered_sum), with smaller or less extents it would be less, but
    it could be much more with more extents per leaf and/or much larger
    extents.
    
    So change copy_items() to log the checksums for an extent after looking
    them up, and then free their memory, as they are no longer necessary.
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    5b7ce5e2
tree-log.c 194 KB