瀏覽代碼

Btrfs: fix reservation code for mixed block groups

The global reservation stuff tries to add together DATA and METADATA used in
order to figure out how much to reserve for everything, but this doesn't work
right for mixed block groups.  Instead if we have mixed block groups just set
data used to 0.  Also with mixed block groups we will use bytes_may_use for
keeping track of delalloc bytes, so we need to take that into account in our
reservation calculations.

Signed-off-by: Josef Bacik <josef@redhat.com>
Josef Bacik 14 年之前
父節點
當前提交
6d48755d02
共有 1 個文件被更改,包括 6 次插入2 次删除
  1. 6 2
      fs/btrfs/extent-tree.c

+ 6 - 2
fs/btrfs/extent-tree.c

@@ -3213,7 +3213,8 @@ static int reserve_metadata_bytes(struct btrfs_block_rsv *block_rsv,
 
 
 	spin_lock(&space_info->lock);
 	spin_lock(&space_info->lock);
 	unused = space_info->bytes_used + space_info->bytes_reserved +
 	unused = space_info->bytes_used + space_info->bytes_reserved +
-		 space_info->bytes_pinned + space_info->bytes_readonly;
+		 space_info->bytes_pinned + space_info->bytes_readonly +
+		 space_info->bytes_may_use;
 
 
 	if (unused < space_info->total_bytes)
 	if (unused < space_info->total_bytes)
 		unused = space_info->total_bytes - unused;
 		unused = space_info->total_bytes - unused;
@@ -3507,6 +3508,8 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
 
 
 	sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
 	sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
 	spin_lock(&sinfo->lock);
 	spin_lock(&sinfo->lock);
+	if (sinfo->flags & BTRFS_BLOCK_GROUP_DATA)
+		data_used = 0;
 	meta_used = sinfo->bytes_used;
 	meta_used = sinfo->bytes_used;
 	spin_unlock(&sinfo->lock);
 	spin_unlock(&sinfo->lock);
 
 
@@ -3534,7 +3537,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
 	block_rsv->size = num_bytes;
 	block_rsv->size = num_bytes;
 
 
 	num_bytes = sinfo->bytes_used + sinfo->bytes_pinned +
 	num_bytes = sinfo->bytes_used + sinfo->bytes_pinned +
-		    sinfo->bytes_reserved + sinfo->bytes_readonly;
+		    sinfo->bytes_reserved + sinfo->bytes_readonly +
+		    sinfo->bytes_may_use;
 
 
 	if (sinfo->total_bytes > num_bytes) {
 	if (sinfo->total_bytes > num_bytes) {
 		num_bytes = sinfo->total_bytes - num_bytes;
 		num_bytes = sinfo->total_bytes - num_bytes;