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>
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 5f3544e..1b9b878 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2778,6 +2778,8 @@
 	/* 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 @@
 		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 @@
 			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 @@
 	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 @@
 
 			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 @@
 			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);