• Dongsheng Yang's avatar
    Btrfs: qgroup: Introduce a may_use to account space_info->bytes_may_use. · 31193213
    Dongsheng Yang authored
    Currently, for pre_alloc or delay_alloc, the bytes will be accounted
    in space_info by the three guys.
    space_info->bytes_may_use --- space_info->reserved --- space_info->used.
    But on the other hand, in qgroup, there are only two counters to account the
    bytes, qgroup->reserved and qgroup->excl. And qg->reserved accounts
    bytes in space_info->bytes_may_use and qg->excl accounts bytes in
    space_info->used. So the bytes in space_info->reserved is not accounted
    in qgroup. If so, there is a window we can exceed the quota limit when
    bytes is in space_info->reserved.
    
    Example:
    	# btrfs quota enable /mnt
    	# btrfs qgroup limit -e 10M /mnt
    	# for((i=0;i<20;i++));do fallocate -l 1M /mnt/data$i; done
    	# sync
    	# btrfs qgroup show -pcre /mnt
    qgroupid rfer     excl     max_rfer max_excl parent  child
    -------- ----     ----     -------- -------- ------  -----
    0/5      20987904 20987904 0        10485760 ---     ---
    
    qg->excl is 20987904 larger than max_excl 10485760.
    
    This patch introduce a new counter named may_use to qgroup, then
    there are three counters in qgroup to account bytes in space_info
    as below.
    space_info->bytes_may_use --- space_info->reserved --- space_info->used.
    qgroup->may_use           --- qgroup->reserved     --- qgroup->excl
    
    With this patch applied:
    	# btrfs quota enable /mnt
    	# btrfs qgroup limit -e 10M /mnt
    	# for((i=0;i<20;i++));do fallocate -l 1M /mnt/data$i; done
    fallocate: /mnt/data9: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data10: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data11: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data12: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data13: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data14: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data15: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data16: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data17: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data18: fallocate failed: Disk quota exceeded
    fallocate: /mnt/data19: fallocate failed: Disk quota exceeded
    	# sync
    	# btrfs qgroup show -pcre /mnt
    qgroupid rfer    excl    max_rfer max_excl parent  child
    -------- ----    ----    -------- -------- ------  -----
    0/5      9453568 9453568 0        10485760 ---     ---
    Reported-by: default avatarCyril SCETBON <cyril.scetbon@free.fr>
    Signed-off-by: default avatarDongsheng Yang <yangds.fnst@cn.fujitsu.com>
    Signed-off-by: default avatarChris Mason <clm@fb.com>
    31193213
inode.c 259 KB