{
struct xfs_mount *mp = rtg->rtg_mount;
struct xfs_trans *tp;
- struct xfs_inode *ip;
- struct xfs_imeta_path *path;
+ struct xfs_inode *dp, *ip;
+ const char *path;
struct xfs_btree_cur *bt_cur;
- xfs_ino_t ino;
int error;
- path = xfs_rtrmapbt_create_path(mp, rtg->rtg_rgno);
+ path = xfs_rtrmapbt_path(rtg->rtg_rgno);
if (!path) {
dbprintf(
_("Cannot create path to rtgroup %u rmap inode\n"),
goto out_path;
}
- error = -libxfs_imeta_lookup(tp, path, &ino);
- if (ino == NULLFSINO)
- error = ENOENT;
+ error = -libxfs_imeta_load(tp, mp->m_metadirip, "realtime", S_IFDIR,
+ &dp);
if (error) {
- dbprintf(_("Cannot look up rtgroup %u rmap inode, error %d\n"),
- rtg->rtg_rgno, error);
+ dbprintf(_("Cannot load realtime inode, error %d\n"),
+ error);
goto out_trans;
}
- error = -libxfs_imeta_iget(tp, ino, S_IFREG, &ip);
+ error = -libxfs_imeta_load(tp, dp, path, S_IFREG, &ip);
if (error) {
- dbprintf(_("Cannot load rtgroup %u rmap inode\n"),
- rtg->rtg_rgno);
- goto out_trans;
+ dbprintf(_("Cannot load rtgroup %u rmap inode, error %d\n"),
+ rtg->rtg_rgno, error);
+ goto out_rele_dp;
}
bt_cur = libxfs_rtrmapbt_init_cursor(mp, tp, rtg, ip);
if (!bt_cur) {
dbprintf(_("Not enough memory.\n"));
- goto out_rele;
+ goto out_rele_ip;
}
error = -libxfs_rmap_query_range(bt_cur, low, high, fsmap_rt_fn,
out_cur:
libxfs_btree_del_cursor(bt_cur, error);
-out_rele:
+out_rele_ip:
libxfs_irele(ip);
+out_rele_dp:
+ libxfs_irele(dp);
out_trans:
libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
static inline int
set_rtgroup_rmap_inode(
- struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_inode *dp,
xfs_rgnumber_t rgno)
{
- struct xfs_imeta_path *path;
- struct xfs_trans *tp;
+ const char *path;
xfs_ino_t rtino;
int error;
- if (!xfs_has_rtrmapbt(mp))
+ if (!xfs_has_rtrmapbt(dp->i_mount))
return 0;
- path = xfs_rtrmapbt_create_path(mp, rgno);
+ path = xfs_rtrmapbt_path(rgno);
if (!path)
return ENOMEM;
- error = -libxfs_trans_alloc_empty(mp, &tp);
- if (error)
- goto out_path;
- error = -libxfs_imeta_lookup(tp, path, &rtino);
+ error = -libxfs_imeta_lookup(tp, dp, path, &rtino);
+ if (error == -ENOENT) {
+ rtino = NULLFSINO;
+ error = 0;
+ }
if (error)
- goto out_trans;
+ goto out_path;
- if (!libxfs_verify_ino(mp, rtino)) {
+ if (!libxfs_verify_ino(dp->i_mount, rtino)) {
error = EFSCORRUPTED;
- goto out_trans;
+ goto out_path;
}
error = bitmap_set(rmap_inodes, rtino, 1);
if (error)
- goto out_trans;
+ goto out_path;
rtgroup_inodes[rgno].rmap_ino = rtino;
-out_trans:
- libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
static inline int
set_rtgroup_refcount_inode(
- struct xfs_mount *mp,
+ struct xfs_trans *tp,
+ struct xfs_inode *dp,
xfs_rgnumber_t rgno)
{
- struct xfs_imeta_path *path;
- struct xfs_trans *tp;
+ const char *path;
xfs_ino_t rtino;
int error;
- if (!xfs_has_rtreflink(mp))
+ if (!xfs_has_rtreflink(dp->i_mount))
return 0;
- path = xfs_rtrefcountbt_create_path(mp, rgno);
+ path = xfs_rtrefcountbt_path(rgno);
if (!path)
return ENOMEM;
- error = -libxfs_trans_alloc_empty(mp, &tp);
+ error = -libxfs_imeta_lookup(tp, dp, path, &rtino);
+ if (error == -ENOENT) {
+ rtino = NULLFSINO;
+ error = 0;
+ }
if (error)
goto out_path;
- error = -libxfs_imeta_lookup(tp, path, &rtino);
- if (error)
- goto out_trans;
-
- if (!libxfs_verify_ino(mp, rtino)) {
+ if (!libxfs_verify_ino(dp->i_mount, rtino)) {
error = EFSCORRUPTED;
- goto out_trans;
+ goto out_path;
}
error = bitmap_set(refcount_inodes, rtino, 1);
if (error)
- goto out_trans;
+ goto out_path;
rtgroup_inodes[rgno].refcount_ino = rtino;
-out_trans:
- libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
init_rtmeta_inode_bitmaps(
struct xfs_mount *mp)
{
+ struct xfs_trans *tp;
+ struct xfs_inode *dp;
xfs_rgnumber_t rgno;
int error;
+ if (!xfs_has_rtgroups(mp))
+ return 0;
+
if (rmap_inodes)
return 0;
if (error)
return error;
+ error = -libxfs_trans_alloc_empty(mp, &tp);
+ if (error)
+ return error;
+
+ error = -libxfs_imeta_load(tp, mp->m_metadirip, "realtime", S_IFDIR,
+ &dp);
+ if (error)
+ return error;
+
for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) {
- int err2 = set_rtgroup_rmap_inode(mp, rgno);
+ int err2 = set_rtgroup_rmap_inode(tp, dp, rgno);
if (err2 && !error)
error = err2;
- err2 = set_rtgroup_refcount_inode(mp, rgno);
+ err2 = set_rtgroup_refcount_inode(tp, dp, rgno);
if (err2 && !error)
error = err2;
}
+ libxfs_trans_cancel(tp);
+ xfs_irele(dp);
return error;
}
bool is_rtrmap_inode(xfs_ino_t ino)
{
+ if (!rmap_inodes)
+ return false;
return bitmap_test(rmap_inodes, ino, 1);
}
bool is_rtrefcount_inode(xfs_ino_t ino)
{
+ if (!refcount_inodes)
+ return false;
return bitmap_test(refcount_inodes, ino, 1);
}
struct xfs_inode *m_rbmip; /* pointer to bitmap inode */
struct xfs_inode *m_rsumip; /* pointer to summary inode */
struct xfs_inode *m_metadirip; /* ptr to metadata directory */
+ struct xfs_inode *m_rtdirip;
struct xfs_buftarg *m_ddev_targp;
struct xfs_buftarg *m_logdev_targp;
struct xfs_buftarg *m_rtdev_targp;
#define xfs_imeta_cancel libxfs_imeta_cancel
#define xfs_imeta_commit libxfs_imeta_commit
-#define xfs_imeta_create_file_path libxfs_imeta_create_file_path
-#define xfs_imeta_ensure_dirpath libxfs_imeta_ensure_dirpath
-#define xfs_imeta_free_path libxfs_imeta_free_path
#define xfs_imeta_iget libxfs_imeta_iget
#define xfs_imeta_link libxfs_imeta_link
#define xfs_imeta_lookup libxfs_imeta_lookup
+#define xfs_imeta_load libxfs_imeta_load
+#define xfs_imeta_mkdir libxfs_imeta_mkdir
#define xfs_imeta_resv_free_inode libxfs_imeta_resv_free_inode
#define xfs_imeta_resv_init_inode libxfs_imeta_resv_init_inode
#define xfs_imeta_set_iflag libxfs_imeta_set_iflag
{
struct xfs_imeta_update upd = { };
struct xfs_mount *mp = rtg->rtg_mount;
- struct xfs_imeta_path *path;
+ const char *path;
struct xfs_btree_cur *cur;
int error;
- path = xfs_rtrmapbt_create_path(mp, rtg->rtg_rgno);
+ path = xfs_rtrmapbt_path(rtg->rtg_rgno);
if (!path)
fail( _("rtrmap inode path creation failed"), ENOMEM);
- error = -libxfs_imeta_ensure_dirpath(mp, path);
- if (error)
- fail(_("rtgroup directory allocation failed"), error);
-
- error = -libxfs_imeta_start_create(mp, path, &upd);
+ error = -libxfs_imeta_start_create(mp->m_rtdirip, path, &upd);
if (error)
res_failed(error);
if (error)
fail(_("rtrmapbt commit failed"), error);
- libxfs_imeta_free_path(path);
+ kfree(path);
rtg->rtg_rmapip = upd.ip;
}
{
struct xfs_imeta_update upd = { };
struct xfs_mount *mp = rtg->rtg_mount;
- struct xfs_imeta_path *path;
+ const char *path;
int error;
- path = xfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno);
+ path = xfs_rtrefcountbt_path(rtg->rtg_rgno);
if (!path)
fail( _("rtrefcount inode path creation failed"), ENOMEM);
- error = -libxfs_imeta_ensure_dirpath(mp, path);
- if (error)
- fail(_("rtgroup allocation failed"),
- error);
-
- error = -libxfs_imeta_start_create(mp, path, &upd);
+ error = -libxfs_imeta_start_create(mp->m_rtdirip, path, &upd);
if (error)
res_failed(error);
if (error)
fail(_("rtrefcountbt commit failed"), error);
- libxfs_imeta_free_path(path);
+ kfree(path);
rtg->rtg_refcountip = upd.ip;
}
rtbitmap_create(mp);
rtsummary_create(mp);
+ if (xfs_has_rtgroups(mp)) {
+ int error;
+
+ error = xfs_imeta_mkdir(mp->m_metadirip, "realtime",
+ &mp->m_rtdirip);
+ if (error)
+ fail(_("rtgroup directory allocation failed"), error);
+ }
+
for_each_rtgroup(mp, rgno, rtg) {
if (xfs_has_rtrmapbt(mp))
rtrmapbt_create(rtg);
struct xfs_mount *mp = sc->mp;
struct xfs_btree_cur *cur;
struct xfs_inode *ip;
- struct xfs_imeta_path *path;
- xfs_ino_t ino;
+ const char *path;
int error;
- path = xfs_rtrmapbt_create_path(mp, rtg->rtg_rgno);
+ /* failed to load the rtdir inode? */
+ if (!mp->m_rtdirip)
+ return ENOENT;
+
+ path = xfs_rtrmapbt_path(rtg->rtg_rgno);
if (!path)
return ENOMEM;
- error = -libxfs_imeta_lookup(sc->tp, path, &ino);
- if (error)
- goto out_path;
-
- error = -libxfs_imeta_iget(sc->tp, ino, S_IFREG, &ip);
+ error = -libxfs_imeta_load(sc->tp, mp->m_rtdirip, path, S_IFREG, &ip);
if (error)
goto out_path;
libxfs_btree_del_cursor(cur, error);
libxfs_irele(ip);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
{
struct xfs_mount *mp = rtg->rtg_mount;
struct xfs_trans *tp;
- struct xfs_imeta_path *path;
- xfs_ino_t ino;
+ const char *path;
xfs_filblks_t ask;
int error;
if (!xfs_has_rtrmapbt(mp))
return 0;
- path = xfs_rtrmapbt_create_path(mp, rtg->rtg_rgno);
+ /* failed to load the rtdir inode? */
+ if (!mp->m_rtdirip)
+ return ENOENT;
+
+ path = xfs_rtrmapbt_path(rtg->rtg_rgno);
if (!path)
return ENOMEM;
ask = libxfs_rtrmapbt_calc_reserves(mp);
- error = -libxfs_imeta_lookup(tp, path, &ino);
- if (error)
- goto out_trans;
-
- if (ino == NULLFSINO) {
- *new_resv += ask;
- error = 0;
+ error = -libxfs_imeta_load(tp, mp->m_rtdirip, path, S_IFREG,
+ &rtg->rtg_rmapip);
+ if (error) {
+ if (error == -ENOENT) {
+ *new_resv += ask;
+ error = 0;
+ }
goto out_trans;
}
- error = -libxfs_imeta_iget(tp, ino, S_IFREG, &rtg->rtg_rmapip);
- if (error)
- goto out_trans;
-
error = -libxfs_imeta_resv_init_inode(rtg->rtg_rmapip, ask);
out_trans:
libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
xfs_rfsblock_t *new_resv)
{
struct xfs_mount *mp = rtg->rtg_mount;
- struct xfs_imeta_path *path;
+ const char *path;
struct xfs_trans *tp;
- xfs_ino_t ino;
xfs_filblks_t ask;
int error;
if (!xfs_has_rtreflink(mp))
return 0;
- path = xfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno);
+ /* failed to load the rtdir inode? */
+ if (!mp->m_rtdirip)
+ return ENOENT;
+
+ path = xfs_rtrefcountbt_path(rtg->rtg_rgno);
if (!path)
return ENOMEM;
ask = libxfs_rtrefcountbt_calc_reserves(mp);
- error = -libxfs_imeta_lookup(tp, path, &ino);
- if (error)
- goto out_trans;
-
- if (ino == NULLFSINO) {
- *new_resv += ask;
- error = 0;
+ error = -libxfs_imeta_load(tp, mp->m_rtdirip, path, S_IFREG,
+ &rtg->rtg_refcountip);
+ if (error) {
+ if (error == -ENOENT) {
+ *new_resv += ask;
+ error = 0;
+ }
goto out_trans;
}
- error = -libxfs_imeta_iget(tp, ino, S_IFREG, &rtg->rtg_refcountip);
- if (error)
- goto out_trans;
-
error = -libxfs_imeta_resv_init_inode(rtg->rtg_refcountip, ask);
out_trans:
libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
set_inode_isadir(irec, ino_offset);
}
-/* Make sure this metadata directory path exists. */
-static int
-ensure_imeta_dirpath(
- struct xfs_mount *mp,
- const struct xfs_imeta_path *path)
-{
- struct xfs_imeta_path temp_path = {
- .im_path = path->im_path,
- .im_ftype = XFS_DIR3_FT_DIR,
- };
- struct xfs_trans *tp;
- xfs_ino_t parent;
- int error;
-
- if (!xfs_has_metadir(mp))
- return 0;
-
- error = -libxfs_imeta_ensure_dirpath(mp, path);
- if (error)
- return error;
-
- error = -libxfs_trans_alloc_empty(mp, &tp);
- if (error)
- return error;
-
- /* Mark all directories in this path as inuse. */
- parent = mp->m_metadirip->i_ino;
- for (temp_path.im_depth = 1;
- temp_path.im_depth < path->im_depth;
- temp_path.im_depth++) {
- xfs_ino_t ino;
-
- error = -libxfs_imeta_lookup(tp, &temp_path, &ino);
- if (error)
- break;
- if (ino == NULLFSINO) {
- error = ENOENT;
- break;
- }
- if (!libxfs_verify_ino(mp, ino)) {
- error = EFSCORRUPTED;
- break;
- }
-
- mark_ino_inuse(mp, ino, S_IFDIR, parent);
- mark_ino_metadata(mp, ino);
- parent = ino;
- }
-
- libxfs_trans_cancel(tp);
- return error;
-}
-
static struct xfs_inode *
ensure_rtgroup_file(
struct xfs_rtgroup *rtg,
xfs_ino_t ino,
- struct xfs_imeta_path *path,
+ const char *path,
const char *name,
int (*create)(struct xfs_imeta_update *upd))
{
do_warn(_("resetting rtgroup %u %s inode\n"),
rtg->rtg_rgno, name);
- 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;
*/
try_erase_parent_ptrs(upd.ip);
- error = -libxfs_imeta_start_link(mp, path, upd.ip, &upd);
+ error = -libxfs_imeta_start_link(mp->m_rtdirip, path, upd.ip,
+ &upd);
if (error)
do_error(
_("Couldn't grab resources to reconnect rtgroup %u %s, error %d\n"),
* 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);
+ error = -libxfs_imeta_start_create(mp->m_rtdirip, path, &upd);
if (error)
do_error(
_("Couldn't grab resources to recreate rtgroup %u %s, error %d\n"),
struct xfs_rtgroup *rtg,
xfs_filblks_t est_fdblocks)
{
- struct xfs_imeta_path *path;
+ const char *path;
struct xfs_inode *ip;
if (!xfs_has_rtrmapbt(rtg->rtg_mount))
return;
- path = xfs_rtrmapbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
+ path = xfs_rtrmapbt_path(rtg->rtg_rgno);
if (!path)
do_error(
_("Couldn't create rtgroup %u rmap file path\n"),
populate_rtgroup_rmapbt(rtg, ip, est_fdblocks);
libxfs_irele(ip);
}
- libxfs_imeta_free_path(path);
+ kfree(path);
}
static void
struct xfs_rtgroup *rtg,
xfs_filblks_t est_fdblocks)
{
- struct xfs_imeta_path *path;
+ const char *path;
struct xfs_inode *ip;
if (!xfs_has_rtreflink(rtg->rtg_mount))
return;
- path = xfs_rtrefcountbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
+ path = xfs_rtrefcountbt_path(rtg->rtg_rgno);
if (!path)
do_error(
_("Couldn't create rtgroup %u refcount file path\n"),
populate_rtgroup_refcountbt(rtg, ip, est_fdblocks);
libxfs_irele(ip);
}
- libxfs_imeta_free_path(path);
+ kfree(path);
}
/* Initialize a root directory. */
struct xfs_trans *tp;
int error;
+ if (mp->m_rtdirip) {
+ xfs_irele(mp->m_rtdirip);
+ mp->m_rtdirip = NULL;
+ }
+
error = init_fs_root_dir(mp, mp->m_sb.sb_metadirino, 0,
&mp->m_metadirip);
if (error)
xfs_filblks_t metadata_blocks = 0;
xfs_filblks_t est_fdblocks = 0;
xfs_rgnumber_t rgno;
+ int error;
+
+ if (!no_modify) {
+ error = -libxfs_imeta_mkdir(mp->m_metadirip, "realtime",
+ &mp->m_rtdirip);
+ if (error)
+ do_error(_("failed to create realtime directory (%d)\n"),
+ error);
+ }
+
+ mark_ino_inuse(mp, mp->m_rtdirip->i_ino, S_IFDIR,
+ mp->m_metadirip->i_ino);
+ mark_ino_metadata(mp, mp->m_rtdirip->i_ino);
/*
* Estimate how much free space will be left after building btrees
}
}
- reset_rt_metadata_inodes(mp);
+ if (xfs_has_rtgroups(mp))
+ reset_rt_metadata_inodes(mp);
if (!no_modify) {
do_log(
struct xfs_mount *mp,
xfs_rgnumber_t rgno)
{
- struct xfs_imeta_path *path;
struct xfs_ag_rmap *ar = rmaps_for_group(true, rgno);
+ const char *path;
struct xfs_trans *tp;
xfs_ino_t ino;
int error;
if (!xfs_has_rtrmapbt(mp))
return 0;
- path = xfs_rtrmapbt_create_path(mp, rgno);
+ path = xfs_rtrmapbt_path(rgno);
if (!path)
return ENOMEM;
if (error)
goto out_path;
- error = -libxfs_imeta_lookup(tp, path, &ino);
+ error = -libxfs_imeta_lookup(tp, mp->m_rtdirip, path, &ino);
+ if (error == -ENOENT) {
+ ino = NULLFSINO;
+ error = 0;
+ }
if (error)
goto out_trans;
out_trans:
libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
struct xfs_mount *mp,
xfs_rgnumber_t rgno)
{
- struct xfs_imeta_path *path;
struct xfs_ag_rmap *ar = rmaps_for_group(true, rgno);
+ const char *path;
struct xfs_trans *tp;
xfs_ino_t ino;
int error;
if (!xfs_has_rtreflink(mp))
return 0;
- path = xfs_rtrefcountbt_create_path(mp, rgno);
+ path = xfs_rtrefcountbt_path(rgno);
if (!path)
return ENOMEM;
if (error)
goto out_path;
- error = -libxfs_imeta_lookup(tp, path, &ino);
+ error = -libxfs_imeta_lookup(tp, mp->m_rtdirip, path, &ino);
+ if (error == -ENOENT) {
+ ino = NULLFSINO;
+ error = 0;
+ }
if (error)
goto out_trans;
out_trans:
libxfs_trans_cancel(tp);
out_path:
- libxfs_imeta_free_path(path);
+ kfree(path);
return error;
}
discover_rtgroup_inodes(
struct xfs_mount *mp)
{
+ struct xfs_trans *tp;
xfs_rgnumber_t rgno;
int error;
goto out;
}
+ error = -libxfs_trans_alloc_empty(mp, &tp);
+ if (error)
+ goto out;
+ error = -libxfs_imeta_load(tp, mp->m_metadirip, "realtime", S_IFDIR,
+ &mp->m_rtdirip);
+ libxfs_trans_cancel(tp);
+ if (error)
+ goto out;
+
for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) {
int err2 = set_rtgroup_rmap_inode(mp, rgno);
if (err2 && !error)
for (i = 0; i < mp->m_sb.sb_agcount; i++)
rmaps_init_ag(mp, i, &ag_rmaps[i]);
+ if (!xfs_has_rtgroups(mp))
+ return;
+
rg_rmaps = calloc(mp->m_sb.sb_rgcount, sizeof(struct xfs_ag_rmap));
if (!rg_rmaps)
do_error(_("couldn't allocate per-rtgroup reverse map roots\n"));
if (!rmap_needs_work(mp))
return;
- free_rtmeta_inode_bitmaps();
+ if (xfs_has_rtgroups(mp)) {
+ free_rtmeta_inode_bitmaps();
- for (i = 0; i < mp->m_sb.sb_rgcount; i++)
- rmaps_destroy(mp, &rg_rmaps[i]);
- free(rg_rmaps);
- rg_rmaps = NULL;
+ for (i = 0; i < mp->m_sb.sb_rgcount; i++)
+ rmaps_destroy(mp, &rg_rmaps[i]);
+ free(rg_rmaps);
+ rg_rmaps = NULL;
+ }
for (i = 0; i < mp->m_sb.sb_agcount; i++)
rmaps_destroy(mp, &ag_rmaps[i]);