浏览代码

Btrfs: deal with NULL space info

After a balance it is briefly possible for the space info
field in the inode to be NULL.  This adds some checks
to make sure things properly deal with the NULL value.


Signed-off-by: Chris Mason <chris.mason@oracle.com>
Chris Mason 15 年之前
父节点
当前提交
33b4d47f5e
共有 1 个文件被更改,包括 16 次插入2 次删除
  1. 16 2
      fs/btrfs/extent-tree.c

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

@@ -2778,6 +2778,8 @@ int btrfs_check_metadata_free_space(struct btrfs_root *root)
 	/* get the space info for where the metadata will live */
 	alloc_target = btrfs_get_alloc_profile(root, 0);
 	meta_sinfo = __find_space_info(info, alloc_target);
+	if (!meta_sinfo)
+		goto alloc;
 
 again:
 	spin_lock(&meta_sinfo->lock);
@@ -2795,7 +2797,7 @@ again:
 		if (!meta_sinfo->full) {
 			meta_sinfo->force_alloc = 1;
 			spin_unlock(&meta_sinfo->lock);
-
+alloc:
 			trans = btrfs_start_transaction(root, 1);
 			if (!trans)
 				return -ENOMEM;
@@ -2803,6 +2805,10 @@ again:
 			ret = do_chunk_alloc(trans, root->fs_info->extent_root,
 					     2 * 1024 * 1024, alloc_target, 0);
 			btrfs_end_transaction(trans, root);
+			if (!meta_sinfo) {
+				meta_sinfo = __find_space_info(info,
+							       alloc_target);
+			}
 			goto again;
 		}
 		spin_unlock(&meta_sinfo->lock);
@@ -2838,6 +2844,9 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
 	bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
 
 	data_sinfo = BTRFS_I(inode)->space_info;
+	if (!data_sinfo)
+		goto alloc;
+
 again:
 	/* make sure we have enough space to handle the data first */
 	spin_lock(&data_sinfo->lock);
@@ -2856,7 +2865,7 @@ again:
 
 			data_sinfo->force_alloc = 1;
 			spin_unlock(&data_sinfo->lock);
-
+alloc:
 			alloc_target = btrfs_get_alloc_profile(root, 1);
 			trans = btrfs_start_transaction(root, 1);
 			if (!trans)
@@ -2868,6 +2877,11 @@ again:
 			btrfs_end_transaction(trans, root);
 			if (ret)
 				return ret;
+
+			if (!data_sinfo) {
+				btrfs_set_inode_space_info(root, inode);
+				data_sinfo = BTRFS_I(inode)->space_info;
+			}
 			goto again;
 		}
 		spin_unlock(&data_sinfo->lock);