• Q
    btrfs: qgroup: Make qgroup async transaction commit more aggressive · dcedd379
    Qu Wenruo 提交于
    [ Upstream commit f5fef4593653dfa2a865c485bb81415de51d5c99 ]
    
    [BUG]
    Btrfs qgroup will still hit EDQUOT under the following case:
    
      $ dev=/dev/test/test
      $ mnt=/mnt/btrfs
      $ umount $mnt &> /dev/null
      $ umount $dev &> /dev/null
    
      $ mkfs.btrfs -f $dev
      $ mount $dev $mnt -o nospace_cache
    
      $ btrfs subv create $mnt/subv
      $ btrfs quota enable $mnt
      $ btrfs quota rescan -w $mnt
      $ btrfs qgroup limit -e 1G $mnt/subv
    
      $ fallocate -l 900M $mnt/subv/padding
      $ sync
    
      $ rm $mnt/subv/padding
    
      # Hit EDQUOT
      $ xfs_io -f -c "pwrite 0 512M" $mnt/subv/real_file
    
    [CAUSE]
    Since commit a514d638 ("btrfs: qgroup: Commit transaction in advance
    to reduce early EDQUOT"), btrfs is not forced to commit transaction to
    reclaim more quota space.
    
    Instead, we just check pertrans metadata reservation against some
    threshold and try to do asynchronously transaction commit.
    
    However in above case, the pertrans metadata reservation is pretty small
    thus it will never trigger asynchronous transaction commit.
    
    [FIX]
    Instead of only accounting pertrans metadata reservation, we calculate
    how much free space we have, and if there isn't much free space left,
    commit transaction asynchronously to try to free some space.
    
    This may slow down the fs when we have less than 32M free qgroup space,
    but should reduce a lot of false EDQUOT, so the cost should be
    acceptable.
    Signed-off-by: NQu Wenruo <wqu@suse.com>
    Signed-off-by: NDavid Sterba <dsterba@suse.com>
    Signed-off-by: NSasha Levin <sashal@kernel.org>
    dcedd379
qgroup.c 85.2 KB