}
static void
-ensure_rtgroup_rmapbt(
+ensure_rtgroup_file(
struct xfs_rtgroup *rtg,
- xfs_filblks_t est_fdblocks)
+ xfs_ino_t ino,
+ struct xfs_imeta_path *path,
+ const char *name,
+ int (*create)(struct xfs_imeta_update *upd),
+ void (*populate)(struct xfs_rtgroup *rtg,
+ struct xfs_inode *ip,
+ void *private),
+ void *private)
{
- struct xfs_imeta_update upd = { };
struct xfs_mount *mp = rtg->rtg_mount;
- struct xfs_imeta_path *path;
- xfs_ino_t ino;
+ struct xfs_imeta_update upd = { };
int error;
- if (!xfs_has_rtrmapbt(mp))
- return;
-
- ino = rtgroup_rmap_ino(rtg);
if (no_modify) {
if (ino == NULLFSINO)
- do_warn(_("would reset rtgroup %u rmap btree\n"),
- rtg->rtg_rgno);
+ do_warn(_("would reset rtgroup %u %s btree\n"),
+ rtg->rtg_rgno, name);
return;
}
if (ino == NULLFSINO)
- do_warn(_("resetting rtgroup %u rmap btree\n"),
- rtg->rtg_rgno);
-
- path = xfs_rtrmapbt_create_path(mp, rtg->rtg_rgno);
- if (!path)
- do_error(
- _("Couldn't create rtgroup %u rmap file path\n"),
- rtg->rtg_rgno);
+ do_warn(_("resetting rtgroup %u %s btree\n"),
+ rtg->rtg_rgno, name);
error = ensure_imeta_dirpath(mp, path);
if (error)
/*
* We're still hanging on to our old inode pointer, so grab it
* and reconnect it to the metadata directory tree. If it
- * can't be grabbed, create a new rtrmap file.
+ * can't be grabbed, create a new file.
*/
error = -libxfs_trans_alloc_empty(mp, &tp);
if (error)
do_error(
- _("Couldn't allocate transaction to iget rtgroup %u rmap inode 0x%llx, error %d\n"),
- rtg->rtg_rgno, (unsigned long long)ino,
- error);
+ _("Couldn't allocate transaction to iget rtgroup %u %s inode 0x%llx, error %d\n"),
+ rtg->rtg_rgno, name, (unsigned long long)ino,
+ error);
error = -libxfs_imeta_iget(tp, ino, S_IFREG, &upd.ip);
libxfs_trans_cancel(tp);
if (error) {
do_warn(
- _("Couldn't iget rtgroup %u rmap inode 0x%llx, error %d\n"),
- rtg->rtg_rgno, (unsigned long long)ino,
- error);
+ _("Couldn't iget rtgroup %u %s inode 0x%llx, error %d\n"),
+ rtg->rtg_rgno, name, (unsigned long long)ino,
+ error);
goto zap;
}
error = -libxfs_imeta_start_link(mp, path, upd.ip, &upd);
if (error)
do_error(
- _("Couldn't grab resources to reconnect rtgroup %u rmapbt, error %d\n"),
- rtg->rtg_rgno, error);
+ _("Couldn't grab resources to reconnect rtgroup %u %s, error %d\n"),
+ rtg->rtg_rgno, name, error);
error = -libxfs_imeta_link(&upd);
if (error)
do_error(
- _("Failed to link rtgroup %u rmapbt inode 0x%llx, error %d\n"),
- rtg->rtg_rgno,
- (unsigned long long)upd.ip->i_ino,
- error);
+ _("Failed to link rtgroup %u %s inode 0x%llx, error %d\n"),
+ rtg->rtg_rgno, name,
+ (unsigned long long)upd.ip->i_ino, error);
/* Reset the link count to something sane. */
set_nlink(VFS_I(upd.ip), 1);
} else {
zap:
/*
- * The rtrmap inode was bad or gone, so just make a new one
- * and give our reference to the rtgroup structure.
+ * The inode was bad or gone, so just make a new one and give
+ * our reference to the rtgroup structure.
*/
error = -libxfs_imeta_start_create(mp, path, &upd);
if (error)
do_error(
- _("Couldn't grab resources to recreate rtgroup %u rmapbt, error %d\n"),
- rtg->rtg_rgno, error);
+ _("Couldn't grab resources to recreate rtgroup %u %s, error %d\n"),
+ rtg->rtg_rgno, name, error);
- error = -libxfs_rtrmapbt_create(&upd);
+ error = -create(&upd);
if (error)
do_error(
- _("Couldn't create rtgroup %u rmap inode, error %d\n"),
- rtg->rtg_rgno, error);
+ _("Couldn't create rtgroup %u %s inode, error %d\n"),
+ rtg->rtg_rgno, name, error);
}
/* Mark the inode in use. */
error = -libxfs_imeta_commit(&upd);
if (error)
do_error(
- _("Couldn't commit new rtgroup %u rmap inode %llu, error %d\n"),
- rtg->rtg_rgno,
- (unsigned long long)upd.ip->i_ino,
- error);
+ _("Couldn't commit new rtgroup %u %s inode %llu, error %d\n"),
+ rtg->rtg_rgno, name, (unsigned long long)upd.ip->i_ino,
+ error);
- /* Copy our incore rmap data to the ondisk rmap inode. */
- error = populate_rtgroup_rmapbt(rtg, upd.ip, est_fdblocks);
- if (error)
- do_error(
- _("rtgroup %u rmap btree could not be rebuilt, error %d\n"),
- rtg->rtg_rgno, error);
+ populate(rtg, upd.ip, private);
- libxfs_imeta_free_path(path);
libxfs_irele(upd.ip);
}
static void
-ensure_rtgroup_refcountbt(
+ensure_rtgroup_rmapbt(
struct xfs_rtgroup *rtg,
xfs_filblks_t est_fdblocks)
{
- struct xfs_imeta_update upd = { };
- struct xfs_mount *mp = rtg->rtg_mount;
struct xfs_imeta_path *path;
- xfs_ino_t ino;
- int error;
- if (!xfs_has_rtreflink(mp))
+ if (!xfs_has_rtrmapbt(rtg->rtg_mount))
return;
- ino = rtgroup_refcount_ino(rtg);
- if (no_modify) {
- if (ino == NULLFSINO)
- do_warn(_("would reset rtgroup %u refcount btree\n"),
- rtg->rtg_rgno);
- return;
- }
-
- if (ino == NULLFSINO)
- do_warn(_("resetting rtgroup %u refcount btree\n"),
- rtg->rtg_rgno);
-
- path = xfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno);
+ path = xfs_rtrmapbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
if (!path)
do_error(
- _("Couldn't create rtgroup %u refcount btree file path\n"), rtg->rtg_rgno);
-
- error = ensure_imeta_dirpath(mp, path);
- if (error)
- do_error(
- _("Couldn't create rtgroup %u metadata directory, error %d\n"),
- rtg->rtg_rgno, error);
-
- if (ino != NULLFSINO) {
- struct xfs_trans *tp;
-
- /*
- * We're still hanging on to our old inode pointer, so grab it
- * and reconnect it to the metadata directory tree. If it
- * can't be grabbed, create a new rtrefcount file.
- */
- error = -libxfs_trans_alloc_empty(mp, &tp);
- if (error)
- do_error(
- _("Couldn't allocate transaction to iget rtgroup %u refcountbt inode 0x%llx, error %d\n"),
- rtg->rtg_rgno, (unsigned long long)ino,
- error);
- error = -libxfs_imeta_iget(tp, ino, S_IFREG, &upd.ip);
- libxfs_trans_cancel(tp);
- if (error) {
- do_warn(
- _("Couldn't iget rtgroup %u refcountbt inode 0x%llx, error %d\n"),
- rtg->rtg_rgno,
- (unsigned long long)ino,
- error);
- goto zap;
- }
-
- /*
- * Since we're reattaching this file to the metadata directory
- * tree, try to remove all the parent pointers that might be
- * attached.
- */
- try_erase_parent_ptrs(upd.ip);
-
- error = -libxfs_imeta_start_link(mp, path, upd.ip, &upd);
- if (error)
- do_error(
- _("Couldn't grab resources to reconnect rtgroup %u refcountbt, error %d\n"),
- rtg->rtg_rgno, error);
+ _("Couldn't create rtgroup %u rmap file path\n"),
+ rtg->rtg_rgno);
- error = -libxfs_imeta_link(&upd);
- if (error)
- do_error(
- _("Failed to link rtgroup %u refcountbt inode 0x%llx, error %d\n"),
- rtg->rtg_rgno,
- (unsigned long long)ino,
- error);
+ ensure_rtgroup_file(rtg, rtgroup_rmap_ino(rtg), path, "rmap",
+ libxfs_rtrmapbt_create, populate_rtgroup_rmapbt,
+ &est_fdblocks);
- /* Reset the link count to something sane. */
- set_nlink(VFS_I(upd.ip), 1);
- libxfs_trans_log_inode(upd.tp, upd.ip, XFS_ILOG_CORE);
- } else {
-zap:
- /*
- * The rtrefcount inode was bad or gone, so just make a new one
- * and give our reference to the rtgroup structure.
- */
- error = -libxfs_imeta_start_create(mp, path, &upd);
- if (error)
- do_error(
- _("Couldn't grab resources to recreate rtgroup %u refcountbt, error %d\n"),
- rtg->rtg_rgno, error);
+ libxfs_imeta_free_path(path);
+}
- error = -libxfs_rtrefcountbt_create(&upd);
- if (error)
- do_error(
- _("Couldn't create rtgroup %u refcountbt inode, error %d\n"),
- rtg->rtg_rgno, error);
- }
+static void
+ensure_rtgroup_refcountbt(
+ struct xfs_rtgroup *rtg,
+ xfs_filblks_t est_fdblocks)
+{
+ struct xfs_imeta_path *path;
- /* Mark the inode in use. */
- mark_ino_inuse(mp, upd.ip->i_ino, S_IFREG, upd.dp->i_ino);
- mark_ino_metadata(mp, upd.ip->i_ino);
+ if (!xfs_has_rtreflink(rtg->rtg_mount))
+ return;
- error = -libxfs_imeta_commit(&upd);
- if (error)
+ path = xfs_rtrefcountbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
+ if (!path)
do_error(
- _("Couldn't commit new rtgroup %u refcountbt inode %llu, error %d\n"),
- rtg->rtg_rgno,
- (unsigned long long)upd.ip->i_ino,
- error);
+ _("Couldn't create rtgroup %u refcount btree file path\n"),
+ rtg->rtg_rgno);
- /* Copy our incore refcount data to the ondisk refcount inode. */
- error = populate_rtgroup_refcountbt(rtg, upd.ip, est_fdblocks);
- if (error)
- do_error(
- _("rtgroup %u refcount btree could not be rebuilt, error %d\n"),
- rtg->rtg_rgno, error);
+ ensure_rtgroup_file(rtg, rtgroup_refcount_ino(rtg), path, "refcount",
+ libxfs_rtrefcountbt_create, populate_rtgroup_refcountbt,
+ &est_fdblocks);
libxfs_imeta_free_path(path);
- libxfs_irele(upd.ip);
}
/* Initialize a root directory. */