• Qu Wenruo's avatar
    btrfs: qgroup: fix wrong qgroup metadata reserve for delayed inode · b4c5d8fd
    Qu Wenruo authored
    For delayed inode facility, qgroup metadata is reserved for it, and
    later freed.
    
    However we're freeing more bytes than we reserved.
    In btrfs_delayed_inode_reserve_metadata():
    
    	num_bytes = btrfs_calc_metadata_size(fs_info, 1);
    	...
    		ret = btrfs_qgroup_reserve_meta_prealloc(root,
    				fs_info->nodesize, true);
    		...
    		if (!ret) {
    			node->bytes_reserved = num_bytes;
    
    But in btrfs_delayed_inode_release_metadata():
    
    	if (qgroup_free)
    		btrfs_qgroup_free_meta_prealloc(node->root,
    				node->bytes_reserved);
    	else
    		btrfs_qgroup_convert_reserved_meta(node->root,
    				node->bytes_reserved);
    
    This means, we're always releasing more qgroup metadata rsv than we have
    reserved.
    
    This won't trigger selftest warning, as btrfs qgroup metadata rsv has
    extra protection against cases like quota enabled half-way.
    
    But we still need to fix this problem any way.
    
    This patch will use the same num_bytes for qgroup metadata rsv so we
    could handle it correctly.
    
    Fixes: f218ea6c ("btrfs: delayed-inode: Remove wrong qgroup meta reservation calls")
    CC: stable@vger.kernel.org # 4.19+
    Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    b4c5d8fd
delayed-inode.c 51.9 KB