@@ -1134,6 +1134,73 @@ xfs_growfsrt_create_rtrmap(
return error;
}
+/* Add a metadata inode for a realtime refcount btree. */
+static int
+xfs_growfsrt_create_rtrefcount(
+ struct xfs_rtgroup *rtg)
+{
+ struct xfs_mount *mp = rtg->rtg_mount;
+ struct xfs_imeta_update upd;
+ struct xfs_imeta_path *path;
+ struct xfs_trans *tp;
+ struct xfs_inode *ip = NULL;
+ int error;
+
+ if (!xfs_has_rtreflink(mp) || rtg->rtg_refcountip)
+ return 0;
+
+ error = xfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno, &path);
+ if (error)
+ return error;
+
+ error = xfs_imeta_ensure_dirpath(mp, path);
+ if (error)
+ goto out_path;
+
+ error = xfs_imeta_start_update(mp, path, &upd);
+ if (error)
+ goto out_path;
+
+ error = xfs_qm_dqattach(upd.dp);
+ if (error)
+ goto out_upd;
+
+ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create,
+ xfs_imeta_create_space_res(mp), 0, 0, &tp);
+ if (error)
+ goto out_end;
+
+ error = xfs_rtrefcountbt_create(&tp, path, &upd, &ip);
+ if (error)
+ goto out_cancel;
+
+ lockdep_set_class(&ip->i_lock.mr_lock, &xfs_rrefcountip_key);
+
+ error = xfs_trans_commit(tp);
+ if (error)
+ goto out_end;
+
+ xfs_imeta_end_update(mp, &upd, error);
+ xfs_imeta_free_path(path);
+ xfs_finish_inode_setup(ip);
+ rtg->rtg_refcountip = ip;
+ return 0;
+
+out_cancel:
+ xfs_trans_cancel(tp);
+out_end:
+ /* Have to finish setting up the inode to ensure it's deleted. */
+ if (ip) {
+ xfs_finish_inode_setup(ip);
+ xfs_irele(ip);
+ }
+out_upd:
+ xfs_imeta_end_update(mp, &upd, error);
+out_path:
+ xfs_imeta_free_path(path);
+ return error;
+}
+
/*
* Check that changes to the realtime geometry won't affect the minimum
* log size, which would cause the fs to become unusable.
@@ -1241,9 +1308,11 @@ xfs_growfs_rt(
return -EINVAL;
/* Unsupported realtime features. */
- if (!xfs_has_rtgroups(mp) && xfs_has_rmapbt(mp))
+ if (!xfs_has_rtgroups(mp) && (xfs_has_rmapbt(mp) || xfs_has_reflink(mp)))
return -EOPNOTSUPP;
- if (xfs_has_reflink(mp) || xfs_has_quota(mp))
+ if (xfs_has_quota(mp))
+ return -EOPNOTSUPP;
+ if (xfs_has_reflink(mp) && in->extsize != 1)
return -EOPNOTSUPP;
nrblocks = in->newblocks;
@@ -1378,6 +1447,12 @@ xfs_growfs_rt(
xfs_rtgroup_put(rtg);
break;
}
+
+ error = xfs_growfsrt_create_rtrefcount(rtg);
+ if (error) {
+ xfs_rtgroup_put(rtg);
+ break;
+ }
}
}