From 8fbe738dd13da1a5f36294b29fc5f0923d0e3908 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 4 Dec 2023 15:40:43 +0100 Subject: [PATCH] userspace changes for the metadir updates Not folded into the last patch to make applying the kernel commit easier as it changes. Signed-off-by: Christoph Hellwig --- db/fsmap.c | 27 ++--- db/inode.c | 9 +- include/libxfs.h | 7 ++ include/xfs_mount.h | 1 + libfrog/scrub.c | 25 ---- libxfs/imeta_utils.c | 249 ++++----------------------------------- libxfs/imeta_utils.h | 16 +-- libxfs/init.c | 21 +--- libxfs/inode.c | 2 - libxfs/libxfs_api_defs.h | 14 +-- libxfs/libxfs_priv.h | 1 + mkfs/proto.c | 151 ++++++++++++------------ repair/agheader.c | 5 +- repair/bmap_repair.c | 25 ++-- repair/phase2.c | 72 ++++------- repair/phase6.c | 165 ++++++-------------------- repair/rmap.c | 188 ++++++++++++++--------------- repair/rmap.h | 2 - repair/xfs_repair.c | 4 - 19 files changed, 298 insertions(+), 686 deletions(-) diff --git a/db/fsmap.c b/db/fsmap.c index 363c159ec..1ed3dbf7f 100644 --- a/db/fsmap.c +++ b/db/fsmap.c @@ -131,17 +131,16 @@ fsmap_rtgroup( struct xfs_mount *mp = rtg->rtg_mount; struct xfs_trans *tp; struct xfs_inode *ip; - struct xfs_imeta_path *path; struct xfs_btree_cur *bt_cur; - xfs_ino_t ino; + const char *name; int error; - error = -libxfs_rtrmapbt_create_path(mp, rtg->rtg_rgno, &path); - if (error) { + name = xfs_rtrmapbt_name(rtg->rtg_rgno); + if (!name) { dbprintf( _("Cannot create path to rtgroup %u rmap inode\n"), rtg->rtg_rgno); - return error; + return ENOMEM; } error = -libxfs_trans_alloc_empty(mp, &tp); @@ -149,25 +148,19 @@ fsmap_rtgroup( dbprintf( _("Cannot alloc transaction to look up rtgroup %u rmap inode\n"), rtg->rtg_rgno); - goto out_path; + kfree(name); + return error; } - error = -libxfs_imeta_lookup(tp, path, &ino); - if (ino == NULLFSINO) - error = ENOENT; + error = -libxfs_imeta_dir_lookup(tp, mp->m_rtdirip, name, + XFS_DIR3_FT_REG_FILE, &ip); + kfree(name); if (error) { dbprintf(_("Cannot look up rtgroup %u rmap inode, error %d\n"), rtg->rtg_rgno, error); goto out_trans; } - error = -libxfs_imeta_iget(tp, ino, XFS_DIR3_FT_REG_FILE, &ip); - if (error) { - dbprintf(_("Cannot load rtgroup %u rmap inode\n"), - rtg->rtg_rgno); - goto out_trans; - } - bt_cur = libxfs_rtrmapbt_init_cursor(mp, tp, rtg, ip); if (!bt_cur) { dbprintf(_("Not enough memory.\n")); @@ -188,8 +181,6 @@ out_rele: libxfs_imeta_irele(ip); out_trans: libxfs_trans_cancel(tp); -out_path: - libxfs_imeta_free_path(path); return error; } diff --git a/db/inode.c b/db/inode.c index 4feff172c..9e924f242 100644 --- a/db/inode.c +++ b/db/inode.c @@ -654,6 +654,9 @@ set_rtgroup_rmap_inode( struct xfs_mount *mp, xfs_rgnumber_t rgno) { +#if 1 + return 0; +#else struct xfs_imeta_path *path; struct xfs_trans *tp; xfs_ino_t rtino; @@ -661,7 +664,6 @@ set_rtgroup_rmap_inode( if (!xfs_has_rtrmapbt(mp)) return 0; - error = -libxfs_rtrmapbt_create_path(mp, rgno, &path); if (error) return error; @@ -690,6 +692,7 @@ out_trans: out_path: libxfs_imeta_free_path(path); return error; +#endif } static inline int @@ -697,6 +700,9 @@ set_rtgroup_refcount_inode( struct xfs_mount *mp, xfs_rgnumber_t rgno) { +#if 1 + return 0; +#else struct xfs_imeta_path *path; struct xfs_trans *tp; xfs_ino_t rtino; @@ -733,6 +739,7 @@ out_trans: out_path: libxfs_imeta_free_path(path); return error; +#endif } int diff --git a/include/libxfs.h b/include/libxfs.h index 612bc697f..35d96ac8b 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -257,6 +257,13 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp) (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID); } +static inline bool xfs_sb_version_hasmetadir(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_METADIR); +} + + static inline bool xfs_sb_version_hasalign(struct xfs_sb *sbp) { return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 || diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 850eeeac4..872ba0474 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -68,6 +68,7 @@ typedef struct xfs_mount { 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; /* ptr to RT metadata subdir */ struct xfs_buftarg *m_ddev_targp; struct xfs_buftarg *m_logdev_targp; struct xfs_buftarg *m_rtdev_targp; diff --git a/libfrog/scrub.c b/libfrog/scrub.c index 62220f1eb..471f2359b 100644 --- a/libfrog/scrub.c +++ b/libfrog/scrub.c @@ -182,31 +182,6 @@ const struct xfrog_scrub_descr xfrog_scrubbers[XFS_SCRUB_TYPE_NR] = { }; const struct xfrog_scrub_descr xfrog_metapaths[XFS_SCRUB_METAPATH_NR] = { - [XFS_SCRUB_METAPATH_RTBITMAP] = { - .name = "rtbitmap", - .descr = "realtime bitmap metadir path", - .group = XFROG_SCRUB_GROUP_FS, - }, - [XFS_SCRUB_METAPATH_RTSUMMARY] = { - .name = "rtsummary", - .descr = "realtime summary metadir path", - .group = XFROG_SCRUB_GROUP_FS, - }, - [XFS_SCRUB_METAPATH_USRQUOTA] = { - .name = "usrquota", - .descr = "user quota metadir path", - .group = XFROG_SCRUB_GROUP_FS, - }, - [XFS_SCRUB_METAPATH_GRPQUOTA] = { - .name = "grpquota", - .descr = "group quota metadir path", - .group = XFROG_SCRUB_GROUP_FS, - }, - [XFS_SCRUB_METAPATH_PRJQUOTA] = { - .name = "prjquota", - .descr = "project quota metadir path", - .group = XFROG_SCRUB_GROUP_FS, - }, [XFS_SCRUB_METAPATH_RTRMAPBT] = { .name = "rtrmapbt", .descr = "rmap btree file metadir path", diff --git a/libxfs/imeta_utils.c b/libxfs/imeta_utils.c index d146f5a6f..f6ca7c4f0 100644 --- a/libxfs/imeta_utils.c +++ b/libxfs/imeta_utils.c @@ -24,44 +24,6 @@ #include "xfs_health.h" #include "imeta_utils.h" -/* Initialize a metadata update structure. */ -static inline int -xfs_imeta_init( - struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_imeta_update *upd) -{ - struct xfs_trans *tp; - int error; - - memset(upd, 0, sizeof(struct xfs_imeta_update)); - upd->mp = mp; - upd->path = path; - - if (!xfs_has_metadir(mp)) - return 0; - - /* - * Find the parent of the last path component. If the parent path does - * not exist, we consider this corruption because paths are supposed - * to exist. For example, if the path is /quota/user, we require that - * /quota already exists. - */ - error = xfs_trans_alloc_empty(mp, &tp); - if (error) - return error; - error = xfs_imeta_dir_parent(tp, upd->path, &upd->dp); - xfs_trans_cancel(tp); - if (error == -ENOENT) { - xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR); - return -EFSCORRUPTED; - } - if (error) - return error; - - return xfs_parent_start(mp, &upd->ppargs); -} - /* * Unlock and release resources after committing (or cancelling) a metadata * directory tree operation. The caller retains its reference to @upd->ip @@ -74,25 +36,12 @@ xfs_imeta_teardown( { trace_xfs_imeta_teardown(upd, error); - if (upd->ppargs) { - xfs_parent_finish(upd->mp, upd->ppargs); - upd->ppargs = NULL; - } - - if (upd->ip) { - if (upd->ip_locked) - xfs_iunlock(upd->ip, XFS_ILOCK_EXCL); - upd->ip_locked = false; - } - - if (upd->dp) { - if (upd->dp_locked) - xfs_iunlock(upd->dp, XFS_ILOCK_EXCL); - upd->dp_locked = false; + if (upd->ppargs) + xfs_parent_finish(upd->dp->i_mount, upd->ppargs); - xfs_imeta_irele(upd->dp); - upd->dp = NULL; - } + if (upd->ip) + xfs_iunlock(upd->ip, XFS_ILOCK_EXCL); + xfs_iunlock(upd->dp, XFS_ILOCK_EXCL); } /* @@ -101,125 +50,46 @@ xfs_imeta_teardown( */ int xfs_imeta_start_create( - struct xfs_mount *mp, - const struct xfs_imeta_path *path, struct xfs_imeta_update *upd) { + struct xfs_mount *mp = upd->dp->i_mount; int error; - error = xfs_imeta_init(mp, path, upd); - if (error) - return error; + ASSERT(upd->dp); + ASSERT(upd->name); + + if (xfs_has_metadir(mp)) { + error = xfs_parent_start(mp, &upd->ppargs); + if (error) + return error; + } + + /* + * If we ever need the ability to create rt metadata files on a + * pre-metadir filesystem, we'll need to dqattach the parent here. + * Currently we assume that mkfs will create the files and quotacheck + * will account for them. + */ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create, xfs_create_space_res(mp, MAXNAMELEN), 0, 0, &upd->tp); if (error) - goto out_teardown; + goto out_parent_finish; /* * Lock the parent directory if there is one. We can't ijoin it to * the transaction until after the child file has been created. */ - if (upd->dp) { - xfs_ilock(upd->dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); - upd->dp_locked = true; - } + xfs_ilock(upd->dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); trace_xfs_imeta_start_create(upd); return 0; -out_teardown: - xfs_imeta_teardown(upd, error); - return error; -} - -/* - * Begin the process of linking a metadata file by allocating transactions - * and locking whatever resources we're going to need. - */ -static inline int -xfs_imeta_start_dir_update( - struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_inode *ip, - struct xfs_trans_res *tr_resv, - unsigned int resblks, - struct xfs_imeta_update *upd) -{ - int error; - error = xfs_imeta_init(mp, path, upd); - if (error) - return error; - - upd->ip = ip; - - if (upd->dp) { - error = xfs_trans_alloc_dir(upd->dp, tr_resv, upd->ip, - resblks, &upd->tp); - if (error) - goto out_teardown; - - upd->dp_locked = true; - } else { - error = xfs_trans_alloc_inode(upd->ip, tr_resv, resblks, 0, - false, &upd->tp); - if (error) - goto out_teardown; - } - - upd->ip_locked = true; - return 0; -out_teardown: - xfs_imeta_teardown(upd, error); +out_parent_finish: + xfs_parent_finish(mp, upd->ppargs); return error; } -/* - * Begin the process of linking a metadata file by allocating transactions - * and locking whatever resources we're going to need. - */ -int -xfs_imeta_start_link( - struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_inode *ip, - struct xfs_imeta_update *upd) -{ - int error; - - error = xfs_imeta_start_dir_update(mp, path, ip, - &M_RES(mp)->tr_imeta_link, - xfs_link_space_res(mp, MAXNAMELEN), upd); - if (error) - return error; - - trace_xfs_imeta_start_link(upd); - return 0; -} - -/* - * Begin the process of unlinking a metadata file by allocating transactions - * and locking whatever resources we're going to need. - */ -int -xfs_imeta_start_unlink( - struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_inode *ip, - struct xfs_imeta_update *upd) -{ - int error; - - error = xfs_imeta_start_dir_update(mp, path, ip, - &M_RES(mp)->tr_imeta_unlink, - xfs_remove_space_res(mp, MAXNAMELEN), upd); - if (error) - return error; - - trace_xfs_imeta_start_unlink(upd); - return 0; -} - /* Commit a metadir update and unlock/drop all resources. */ int xfs_imeta_commit_update( @@ -249,72 +119,3 @@ xfs_imeta_cancel_update( xfs_imeta_teardown(upd, error); } - -/* Create a metadata for the last component of the path. */ -STATIC int -xfs_imeta_mkdir( - struct xfs_mount *mp, - const struct xfs_imeta_path *path) -{ - struct xfs_imeta_update upd; - struct xfs_inode *ip = NULL; - int error; - - if (xfs_is_shutdown(mp)) - return -EIO; - - /* Allocate a transaction to create the last directory. */ - error = xfs_imeta_start_create(mp, path, &upd); - if (error) - return error; - - /* Create the subdirectory and take our reference. */ - error = xfs_imeta_create(&upd, S_IFDIR, &ip); - if (error) - goto out_cancel; - - error = xfs_imeta_commit_update(&upd); - - /* - * We don't pass the directory we just created to the caller, so finish - * setting up the inode, then release the dir and the dquots. - */ - goto out_irele; - -out_cancel: - xfs_imeta_cancel_update(&upd, error); -out_irele: - /* Have to finish setting up the inode to ensure it's deleted. */ - if (ip) - xfs_irele(ip); - return error; -} - -/* - * Make sure that every metadata directory path component exists and is a - * directory. - */ -int -xfs_imeta_ensure_dirpath( - struct xfs_mount *mp, - const struct xfs_imeta_path *path) -{ - struct xfs_imeta_path temp_path = { - .im_path = path->im_path, - .im_depth = 1, - .im_ftype = XFS_DIR3_FT_DIR, - }; - unsigned int i; - int error = 0; - - if (!xfs_has_metadir(mp)) - return 0; - - for (i = 0; i < path->im_depth - 1; i++, temp_path.im_depth++) { - error = xfs_imeta_mkdir(mp, &temp_path); - if (error && error != -EEXIST) - return error; - } - - return 0; -} diff --git a/libxfs/imeta_utils.h b/libxfs/imeta_utils.h index d84b7de8c..a9dacfa13 100644 --- a/libxfs/imeta_utils.h +++ b/libxfs/imeta_utils.h @@ -6,21 +6,7 @@ #ifndef __XFS_IMETA_UTILS_H__ #define __XFS_IMETA_UTILS_H__ -int xfs_imeta_start_create(struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_imeta_update *upd); - -int xfs_imeta_start_link(struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_inode *ip, struct xfs_imeta_update *upd); - -int xfs_imeta_start_unlink(struct xfs_mount *mp, - const struct xfs_imeta_path *path, - struct xfs_inode *ip, struct xfs_imeta_update *upd); - -int xfs_imeta_ensure_dirpath(struct xfs_mount *mp, - const struct xfs_imeta_path *path); - +int xfs_imeta_start_create(struct xfs_imeta_update *upd); int xfs_imeta_commit_update(struct xfs_imeta_update *upd); void xfs_imeta_cancel_update(struct xfs_imeta_update *upd, int error); diff --git a/libxfs/init.c b/libxfs/init.c index 88674dba7..4465b304d 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -861,26 +861,14 @@ libxfs_mountfs_imeta( if (error) return; - if (xfs_has_metadir(mp)) { - error = -libxfs_imeta_iget(tp, mp->m_sb.sb_metadirino, + error = -libxfs_imeta_iget(tp, mp->m_sb.sb_metadirino, XFS_DIR3_FT_DIR, &mp->m_metadirip); - if (error) { - fprintf(stderr, - _("%s: Failed to load metadir root directory, error %d\n"), - progname, error); - goto err_cancel; - } - } - - error = -xfs_imeta_mount(tp); if (error) { fprintf(stderr, - _("%s: Failed to load metadata inodes, error %d\n"), - progname, error); - goto err_cancel; + _("%s: Failed to load metadir root directory, error %d\n"), + progname, error); } -err_cancel: libxfs_trans_cancel(tp); } @@ -1115,7 +1103,8 @@ libxfs_mount( } xfs_set_perag_data_loaded(mp); - libxfs_mountfs_imeta(mp); + if (xfs_has_metadir(mp)) + libxfs_mountfs_imeta(mp); error = libxfs_initialize_rtgroups(mp, sbp->sb_rgcount); if (error) { diff --git a/libxfs/inode.c b/libxfs/inode.c index 87b5df84f..65ba44897 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -292,8 +292,6 @@ void libxfs_imeta_irele( struct xfs_inode *ip) { - ASSERT(!xfs_has_metadir(ip->i_mount) || xfs_is_metadir_inode(ip)); - libxfs_irele(ip); } diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 91722de39..78770ef5c 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -179,25 +179,17 @@ #define xfs_imeta_cancel_update libxfs_imeta_cancel_update #define xfs_imeta_commit_update libxfs_imeta_commit_update -#define xfs_imeta_create libxfs_imeta_create -#define xfs_imeta_create_file_path libxfs_imeta_create_file_path -#define xfs_imeta_create_space_res libxfs_imeta_create_space_res -#define xfs_imeta_ensure_dirpath libxfs_imeta_ensure_dirpath -#define xfs_imeta_free_path libxfs_imeta_free_path +#define xfs_imeta_dir_lookup libxfs_imeta_dir_lookup +#define xfs_imeta_dir_create libxfs_imeta_dir_create +#define xfs_imeta_sb_create libxfs_imeta_sb_create #define xfs_imeta_iget libxfs_imeta_iget #define xfs_imeta_irele libxfs_imeta_irele -#define xfs_imeta_link libxfs_imeta_link -#define xfs_imeta_link_space_res libxfs_imeta_link_space_res -#define xfs_imeta_lookup libxfs_imeta_lookup -#define xfs_imeta_mount libxfs_imeta_mount #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 #define xfs_imeta_start_create libxfs_imeta_start_create #define xfs_imeta_start_link libxfs_imeta_start_link #define xfs_imeta_start_unlink libxfs_imeta_start_unlink -#define xfs_imeta_unlink libxfs_imeta_unlink -#define xfs_imeta_unlink_space_res libxfs_imeta_unlink_space_res #define xfs_initialize_perag libxfs_initialize_perag #define xfs_initialize_perag_data libxfs_initialize_perag_data diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index bbe7dd634..439883477 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -42,6 +42,7 @@ #include "libxfs_api_defs.h" #include "platform_defs.h" +#include "libfrog/platform.h" #include "xfs.h" #include "list.h" diff --git a/mkfs/proto.c b/mkfs/proto.c index 5b9f36424..0329bfde0 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -17,7 +17,7 @@ static void fail(char *msg, int i); static struct xfs_trans * getres(struct xfs_mount *mp, uint blocks); static void rsvfile(xfs_mount_t *mp, xfs_inode_t *ip, long long len); static char *newregfile(char **pp, int *len); -static int metadir_create(struct xfs_mount *mp); +static void metadir_create(struct xfs_mount *mp); static void rtinit(xfs_mount_t *mp); static void rtfreesp_init(struct xfs_mount *mp); static long filesize(int fd); @@ -687,16 +687,11 @@ parseproto( libxfs_parent_finish(mp, ppargs); /* - * RT initialization. Do this here to ensure that - * the RT inodes get placed after the root inode. + * Initialize the metadata inodes here to ensure they get placed + * after the root inode. */ if (isroot) { - error = metadir_create(mp); - if (error) - fail( - _("Creation of the metadata directory inode failed"), - error); - + metadir_create(mp); rtinit(mp); } tp = NULL; @@ -737,38 +732,28 @@ parse_proto( } /* Create a new metadata root directory. */ -static int +static void metadir_create( struct xfs_mount *mp) { - struct xfs_imeta_update upd; - struct xfs_inode *ip = NULL; + struct xfs_trans *tp; int error; if (!xfs_has_metadir(mp)) - return 0; + return; - error = -libxfs_imeta_start_create(mp, &XFS_IMETA_METADIR, &upd); + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create, 0, 0, 0, &tp); if (error) - return error; + res_failed(error); - error = -libxfs_imeta_create(&upd, S_IFDIR, &ip); + error = -libxfs_imeta_sb_create(&tp, &mp->m_sb.sb_metadirino, S_IFDIR, + &mp->m_metadirip); if (error) - goto out_cancel; + fail(_("Metadir inode allocation failed"), error); - error = -libxfs_imeta_commit_update(&upd); + error = -libxfs_trans_commit(tp); if (error) - goto out_rele; - - mp->m_metadirip = ip; - return 0; - -out_cancel: - libxfs_imeta_cancel_update(&upd, error); -out_rele: - if (ip) - libxfs_irele(ip); - return error; + fail(_("Completion of the metadir inode failed"), error); } /* Create the realtime bitmap inode. */ @@ -776,19 +761,17 @@ static void rtbitmap_create( struct xfs_mount *mp) { - struct xfs_imeta_update upd; struct xfs_inode *rbmip; + struct xfs_trans *tp; int error; - error = -libxfs_imeta_ensure_dirpath(mp, &XFS_IMETA_RTBITMAP); - if (error) - fail(_("Realtime bitmap directory allocation failed"), error); - - error = -libxfs_imeta_start_create(mp, &XFS_IMETA_RTBITMAP, &upd); + error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create, 0, 0, 0, + &tp); if (error) res_failed(error); - error = -libxfs_imeta_create(&upd, S_IFREG, &rbmip); + error = -libxfs_imeta_sb_create(&tp, &mp->m_sb.sb_rbmino, S_IFREG, + &rbmip); if (error) fail(_("Realtime bitmap inode allocation failed"), error); @@ -796,9 +779,9 @@ rtbitmap_create( rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM; if (!xfs_has_rtgroups(mp)) inode_set_atime(VFS_I(rbmip), 0, 0); - libxfs_trans_log_inode(upd.tp, rbmip, XFS_ILOG_CORE); + libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE); - error = -libxfs_imeta_commit_update(&upd); + error = -libxfs_trans_commit(tp); if (error) fail(_("Completion of the realtime bitmap inode failed"), error); @@ -810,38 +793,65 @@ static void rtsummary_create( struct xfs_mount *mp) { - struct xfs_imeta_update upd; struct xfs_inode *rsumip; + struct xfs_trans *tp; int error; - error = -libxfs_imeta_ensure_dirpath(mp, &XFS_IMETA_RTSUMMARY); - if (error) - fail(_("Realtime summary directory allocation failed"), error); - - error = -libxfs_imeta_start_create(mp, &XFS_IMETA_RTSUMMARY, &upd); + error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_imeta_create, 0, 0, 0, + &tp); if (error) res_failed(error); - error = -libxfs_imeta_create(&upd, S_IFREG, &rsumip); + error = -libxfs_imeta_sb_create(&tp, &mp->m_sb.sb_rsumino, S_IFREG, + &rsumip); if (error) fail(_("Realtime summary inode allocation failed"), error); rsumip->i_disk_size = mp->m_rsumsize; - libxfs_trans_log_inode(upd.tp, rsumip, XFS_ILOG_CORE); + libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE); - error = -libxfs_imeta_commit_update(&upd); + error = -libxfs_trans_commit(tp); if (error) fail(_("Completion of the realtime summary inode failed"), error); mp->m_rsumip = rsumip; } + +static void +create_rtdir( + struct xfs_mount *mp) +{ + struct xfs_imeta_update upd = { + .dp = mp->m_metadirip, + .name = "realtime", + }; + int error; + + error = -libxfs_imeta_start_create(&upd); + if (error) + res_failed(error); + + error = -libxfs_imeta_dir_create(&upd, S_IFDIR); + if (error) + fail(_("rtdir inode creation failed"), error); + + error = -libxfs_imeta_commit_update(&upd); + if (error) + fail(_("rtdir commit failed"), error); + + mp->m_rtdirip = upd.ip; +} + /* Create the realtime rmap btree inode. */ static void rtrmapbt_create( struct xfs_rtgroup *rtg) { - struct xfs_imeta_update upd; + struct xfs_mount *mp = rtg->rtg_mount; + struct xfs_imeta_update upd = { + .dp = mp->m_rtdirip, + }; struct xfs_rmap_irec rmap = { .rm_startblock = 0, .rm_blockcount = rtg->rtg_mount->m_sb.sb_rextsize, @@ -849,26 +859,21 @@ rtrmapbt_create( .rm_offset = 0, .rm_flags = 0, }; - struct xfs_mount *mp = rtg->rtg_mount; - struct xfs_imeta_path *path; struct xfs_btree_cur *cur; int error; - error = -libxfs_rtrmapbt_create_path(mp, rtg->rtg_rgno, &path); - if (error) - fail( _("rtrmap inode path creation failed"), error); + upd.name = xfs_rtrmapbt_name(rtg->rtg_rgno); + if (!upd.name) + fail( _("rtrmap inode name allocation 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(&upd); if (error) res_failed(error); - error = -libxfs_rtrmapbt_create(&upd, &rtg->rtg_rmapip); + error = -libxfs_rtrmapbt_create(&upd); if (error) fail(_("rtrmap inode creation failed"), error); + rtg->rtg_rmapip = upd.ip; /* Adding an rmap for the rtgroup super should fit in the data fork */ cur = libxfs_rtrmapbt_init_cursor(mp, upd.tp, rtg, rtg->rtg_rmapip); @@ -880,8 +885,6 @@ rtrmapbt_create( error = -libxfs_imeta_commit_update(&upd); if (error) fail(_("rtrmapbt commit failed"), error); - - libxfs_imeta_free_path(path); } /* Create the realtime refcount btree inode. */ @@ -889,33 +892,28 @@ static void rtrefcountbt_create( struct xfs_rtgroup *rtg) { - struct xfs_imeta_update upd; struct xfs_mount *mp = rtg->rtg_mount; - struct xfs_imeta_path *path; + struct xfs_imeta_update upd = { + .dp = mp->m_rtdirip, + }; int error; - error = -libxfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno, &path); - if (error) - fail( _("rtrefcount inode path creation failed"), error); - - error = -libxfs_imeta_ensure_dirpath(mp, path); - if (error) - fail(_("rtgroup allocation failed"), - error); + upd.name = xfs_rtrefcountbt_name(rtg->rtg_rgno); + if (!upd.name) + fail( _("rtrefcount inode name allocation failed"), ENOMEM); - error = -libxfs_imeta_start_create(mp, path, &upd); + error = -libxfs_imeta_start_create(&upd); if (error) res_failed(error); - error = -libxfs_rtrefcountbt_create(&upd, &rtg->rtg_refcountip); + error = -libxfs_rtrefcountbt_create(&upd); if (error) fail(_("rtrefcount inode creation failed"), error); + rtg->rtg_refcountip = upd.ip; error = -libxfs_imeta_commit_update(&upd); if (error) fail(_("rtrefcountbt commit failed"), error); - - libxfs_imeta_free_path(path); } /* Initialize block headers of rt free space files. */ @@ -1097,6 +1095,9 @@ rtinit( rtbitmap_create(mp); rtsummary_create(mp); + if (xfs_has_rtgroups(mp)) + create_rtdir(mp); + for_each_rtgroup(mp, rgno, rtg) { if (xfs_has_rtrmapbt(mp)) rtrmapbt_create(rtg); diff --git a/repair/agheader.c b/repair/agheader.c index 076860a44..455463da4 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -357,7 +357,10 @@ secondary_sb_whack( * * size is the size of data which is valid for this sb. */ - if (xfs_sb_version_hasmetauuid(sb)) + if (xfs_sb_version_hasmetadir(sb)) + size = offsetof(struct xfs_dsb, sb_rgblocks) + + sizeof(sb->sb_rgblocks); + else if (xfs_sb_version_hasmetauuid(sb)) size = offsetof(struct xfs_dsb, sb_meta_uuid) + sizeof(sb->sb_meta_uuid); else if (xfs_sb_version_hascrc(sb)) diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c index 043971637..65f2efd4e 100644 --- a/repair/bmap_repair.c +++ b/repair/bmap_repair.c @@ -295,27 +295,18 @@ xrep_bmap_scan_rt( 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 *name; int error; - error = -libxfs_rtrmapbt_create_path(mp, rtg->rtg_rgno, &path); + name = xfs_rtrmapbt_name(rtg->rtg_rgno); + if (!name) + return ENOMEM; + error = -libxfs_imeta_dir_lookup(sc->tp, mp->m_rtdirip, name, + XFS_DIR3_FT_REG_FILE, &ip); + kfree(name); if (error) return error; - error = -libxfs_imeta_lookup(sc->tp, path, &ino); - if (error) - goto out_path; - - if (ino == NULLFSINO) { - error = EFSCORRUPTED; - goto out_path; - } - - error = -libxfs_imeta_iget(sc->tp, ino, XFS_DIR3_FT_REG_FILE, &ip); - if (error) - goto out_path; - cur = libxfs_rtrmapbt_init_cursor(mp, sc->tp, rtg, ip); error = -libxfs_rmap_query_all(cur, xrep_bmap_walk_rtrmap, rb); if (error) @@ -323,8 +314,6 @@ xrep_bmap_scan_rt( out_cur: libxfs_btree_del_cursor(cur, error); libxfs_imeta_irele(ip); -out_path: - libxfs_imeta_free_path(path); return error; } diff --git a/repair/phase2.c b/repair/phase2.c index bd0530cb6..7ceec9348 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -496,44 +496,34 @@ reserve_rtrmap_inode( { struct xfs_mount *mp = rtg->rtg_mount; struct xfs_trans *tp; - struct xfs_imeta_path *path; - xfs_ino_t ino; + const char *name; + struct xfs_inode *ip; xfs_filblks_t ask; int error; if (!xfs_has_rtrmapbt(mp)) return 0; - error = -libxfs_rtrmapbt_create_path(mp, rtg->rtg_rgno, &path); - if (error) - return error; + name = xfs_rtrmapbt_name(rtg->rtg_rgno); + if (!name) + return ENOMEM; error = -libxfs_trans_alloc_empty(mp, &tp); if (error) - goto out_path; + goto out_name; ask = libxfs_rtrmapbt_calc_reserves(mp); - error = -libxfs_imeta_lookup(tp, path, &ino); - if (error) - goto out_trans; - - if (ino == NULLFSINO) { + error = -libxfs_imeta_dir_lookup(tp, mp->m_rtdirip, name, + XFS_DIR3_FT_REG_FILE, &ip); + if (error == ENOENT) *new_resv += ask; - goto out_trans; - } - - error = -libxfs_imeta_iget(tp, ino, XFS_DIR3_FT_REG_FILE, - &rtg->rtg_rmapip); - if (error) - goto out_trans; - - error = -libxfs_imeta_resv_init_inode(rtg->rtg_rmapip, ask); + else + error = -libxfs_imeta_resv_init_inode(rtg->rtg_rmapip, ask); -out_trans: libxfs_trans_cancel(tp); -out_path: - libxfs_imeta_free_path(path); +out_name: + kfree(name); return error; } @@ -552,45 +542,35 @@ reserve_rtrefcount_inode( xfs_rfsblock_t *new_resv) { struct xfs_mount *mp = rtg->rtg_mount; - struct xfs_imeta_path *path; struct xfs_trans *tp; - xfs_ino_t ino; + const char *name; + struct xfs_inode *ip; xfs_filblks_t ask; int error; if (!xfs_has_rtreflink(mp)) return 0; - error = -libxfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno, &path); - if (error) - return error; + name = xfs_rtrefcountbt_name(rtg->rtg_rgno); + if (!name) + return ENOMEM; error = -libxfs_trans_alloc_empty(mp, &tp); if (error) - goto out_path; + goto out_name; ask = libxfs_rtrefcountbt_calc_reserves(mp); - error = -libxfs_imeta_lookup(tp, path, &ino); - if (error) - goto out_trans; - - if (ino == NULLFSINO) { + error = -libxfs_imeta_dir_lookup(tp, mp->m_rtdirip, name, + XFS_DIR3_FT_REG_FILE, &ip); + if (error == ENOENT) *new_resv += ask; - goto out_trans; - } - - error = -libxfs_imeta_iget(tp, ino, XFS_DIR3_FT_REG_FILE, - &rtg->rtg_refcountip); - if (error) - goto out_trans; - - error = -libxfs_imeta_resv_init_inode(rtg->rtg_refcountip, ask); + else + error = -libxfs_imeta_resv_init_inode(rtg->rtg_refcountip, ask); -out_trans: libxfs_trans_cancel(tp); -out_path: - libxfs_imeta_free_path(path); +out_name: + kfree(name); return error; } diff --git a/repair/phase6.c b/repair/phase6.c index 9c79b233e..5ee04aa42 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -536,6 +536,7 @@ mark_ino_metadata( set_inode_is_meta(irec, ino_offset); } +#if 0 /* Make sure this metadata directory path exists. */ static int ensure_imeta_dirpath( @@ -613,6 +614,7 @@ lookup_imeta_path_dirname( return ino; } +#endif static inline bool is_inode_inuse( @@ -648,124 +650,31 @@ ensure_rtino( return 0; } -/* - * Either link the old rtbitmap/summary inode into the (reinitialized) metadata - * directory tree, or create new ones. - */ -static void -ensure_rtino_metadir( - struct xfs_mount *mp, - const struct xfs_imeta_path *path, - xfs_ino_t *inop, - struct xfs_inode **ipp, - struct xfs_imeta_update *upd) -{ - struct xfs_trans *tp; - xfs_ino_t ino = *inop; - int error; - - /* - * If the incore inode pointer is null or points to an inode that is - * not allocated, we need to create a new file. - */ - if (ino == NULLFSINO || !is_inode_inuse(mp, ino)) { - error = -libxfs_imeta_start_create(mp, path, upd); - if (error) - do_error( - _("failed to allocate resources to recreate rt metadata inode, error %d\n"), - error); - - /* Allocate a new inode. */ - error = -libxfs_imeta_create(upd, S_IFREG, ipp); - if (error) - do_error( - _("couldn't create new rt metadata inode, error %d\n"), error); - - ASSERT(*inop == upd->ip->i_ino); - - mark_ino_inuse(mp, upd->ip->i_ino, S_IFREG, - lookup_imeta_path_dirname(mp, path)); - mark_ino_metadata(mp, upd->ip->i_ino); - return; - } - - /* - * We found the old rt metadata file and it looks ok. Link it into - * the metadata directory tree. Null out the superblock pointer before - * we re-link this file into it. - */ - *inop = NULLFSINO; - - error = -libxfs_trans_alloc_empty(mp, &tp); - if (error) - do_error( - _("failed to allocate trans to iget rt metadata inode 0x%llx, error %d\n"), - (unsigned long long)ino, error); - error = -libxfs_imeta_iget(tp, ino, XFS_DIR3_FT_REG_FILE, ipp); - libxfs_trans_cancel(tp); - if (error) - do_error( - _("failed to iget rt metadata inode 0x%llx, error %d\n"), - (unsigned long long)ino, error); - - /* - * 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(*ipp); - - error = -libxfs_imeta_start_link(mp, path, *ipp, upd); - if (error) - do_error( - _("failed to allocate resources to reinsert rt metadata inode 0x%llx, error %d\n"), - (unsigned long long)ino, error); - - error = -libxfs_imeta_link(upd); - if (error) - do_error( - _("failed to link rt metadata inode 0x%llx, error %d\n"), - (unsigned long long)ino, error); - - /* 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); -} - static void mk_rbmino( struct xfs_mount *mp) { - struct xfs_imeta_update upd = { }; struct xfs_inode *ip = NULL; + struct xfs_trans *tp; int i; int error; /* Reset the realtime bitmap inode. */ - if (!xfs_has_metadir(mp)) { - i = -libxfs_trans_alloc_rollable(mp, 10, &upd.tp); - if (i) - res_failed(i); + i = -libxfs_trans_alloc_rollable(mp, 10, &tp); + if (i) + res_failed(i); - error = ensure_rtino(upd.tp, mp->m_sb.sb_rbmino, &ip); - if (error) { - do_error( + error = ensure_rtino(tp, mp->m_sb.sb_rbmino, &ip); + if (error) { + do_error( _("couldn't iget realtime bitmap inode -- error - %d\n"), - error); - } - } else { - error = ensure_imeta_dirpath(mp, &XFS_IMETA_RTBITMAP); - if (error) - do_error( - _("Couldn't create realtime metadata directory, error %d\n"), error); - - ensure_rtino_metadir(mp, &XFS_IMETA_RTBITMAP, - &mp->m_sb.sb_rbmino, &ip, &upd); + error); } ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize; - libxfs_trans_log_inode(upd.tp, ip, XFS_ILOG_CORE); + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = -libxfs_imeta_commit_update(&upd); + error = -libxfs_trans_commit(tp); if (error) do_error(_("%s: commit failed, error %d\n"), __func__, error); @@ -968,37 +877,27 @@ static void mk_rsumino( struct xfs_mount *mp) { - struct xfs_imeta_update upd = { }; + struct xfs_trans *tp; struct xfs_inode *ip = NULL; int i; int error; /* Reset the realtime summary inode. */ - if (!xfs_has_metadir(mp)) { - i = -libxfs_trans_alloc_rollable(mp, 10, &upd.tp); - if (i) - res_failed(i); + i = -libxfs_trans_alloc_rollable(mp, 10, &tp); + if (i) + res_failed(i); - error = ensure_rtino(upd.tp, mp->m_sb.sb_rsumino, &ip); - if (error) { - do_error( + error = ensure_rtino(tp, mp->m_sb.sb_rsumino, &ip); + if (error) { + do_error( _("couldn't iget realtime summary inode -- error - %d\n"), - error); - } - } else { - error = ensure_imeta_dirpath(mp, &XFS_IMETA_RTSUMMARY); - if (error) - do_error( - _("Couldn't create realtime metadata directory, error %d\n"), error); - - ensure_rtino_metadir(mp, &XFS_IMETA_RTSUMMARY, - &mp->m_sb.sb_rsumino, &ip, &upd); + error); } ip->i_disk_size = mp->m_rsumsize; - libxfs_trans_log_inode(upd.tp, ip, XFS_ILOG_CORE); + libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - error = -libxfs_imeta_commit_update(&upd); + error = -libxfs_trans_commit(tp); if (error) do_error(_("%s: commit failed, error %d\n"), __func__, error); @@ -1023,6 +922,9 @@ ensure_rtgroup_rmapbt( struct xfs_rtgroup *rtg, xfs_filblks_t est_fdblocks) { +#if 1 + return; +#else struct xfs_imeta_update upd; struct xfs_mount *mp = rtg->rtg_mount; struct xfs_imeta_path *path; @@ -1145,7 +1047,8 @@ zap: rtg->rtg_rgno, error); libxfs_imeta_free_path(path); - libxfs_imeta_irele(ip); + libxfs_irele(ip); +#endif } static void @@ -1153,6 +1056,9 @@ ensure_rtgroup_refcountbt( struct xfs_rtgroup *rtg, xfs_filblks_t est_fdblocks) { +#if 1 + return; +#else struct xfs_mount *mp = rtg->rtg_mount; struct xfs_imeta_path *path; struct xfs_inode *ip; @@ -1276,7 +1182,8 @@ zap: rtg->rtg_rgno, error); libxfs_imeta_free_path(path); - libxfs_imeta_irele(ip); + libxfs_irele(ip); +#endif } /* Initialize a root directory. */ @@ -3766,6 +3673,7 @@ mark_inode( static void mark_standalone_inodes(xfs_mount_t *mp) { +#if 0 if (xfs_has_metadir(mp)) { /* * The directory connectivity scanner will pick up the metadata @@ -3774,7 +3682,7 @@ mark_standalone_inodes(xfs_mount_t *mp) */ return; } - +#endif mark_inode(mp, mp->m_sb.sb_rbmino); mark_inode(mp, mp->m_sb.sb_rsumino); @@ -3913,6 +3821,7 @@ update_missing_dotdot_entries( } } +#if 0 /* * Re-link a quota inode into the metadata directory. We do not create quota * inodes or abort repair if we cannot relink the inodes, because quota mount @@ -3996,6 +3905,7 @@ out_rele: libxfs_irele(ip); return error; } +#endif /* * Reattach quota inodes to the metadata directory if we rebuilt the metadata @@ -4009,7 +3919,7 @@ reattach_metadir_quota_inodes( if (!xfs_has_metadir(mp) || no_modify) return; - +#if 0 if (mp->m_sb.sb_uquotino != NULLFSINO) { error = reattach_quota_inode(mp, &mp->m_sb.sb_uquotino, &XFS_IMETA_USRQUOTA); @@ -4036,6 +3946,7 @@ reattach_metadir_quota_inodes( lost_pquotino = 1; } } +#endif } static void diff --git a/repair/rmap.c b/repair/rmap.c index 966c42b39..8ed345a50 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -34,18 +34,6 @@ struct xfs_ag_rmap { int ar_flcount; /* agfl entries from leftover */ /* agbt allocations */ struct xfs_slab *ar_refcount_items; /* refcount items, p4-5 */ - - /* - * inumber of the rmap btree for this rtgroup. This can be set to - * NULLFSINO to signal to phase 6 to link a new inode into the metadir. - */ - xfs_ino_t rg_rmap_ino; - - /* - * inumber of the refcount btree for this rtgroup. This can be set to - * NULLFSINO to signal to phase 6 to link a new inode into the metadir. - */ - xfs_ino_t rg_refcount_ino; }; static struct xfs_ag_rmap *ag_rmaps; @@ -140,8 +128,6 @@ rmaps_init_rt( if (error) goto nomem; - ag_rmap->rg_rmap_ino = NULLFSINO; - ag_rmap->rg_refcount_ino = NULLFSINO; return; nomem: do_error( @@ -191,89 +177,100 @@ _("Insufficient memory while allocating realtime reverse mapping btree.")); static inline int set_rtgroup_rmap_inode( - struct xfs_mount *mp, - xfs_rgnumber_t rgno) + struct xfs_rtgroup *rtg) { - struct xfs_imeta_path *path; - struct xfs_ag_rmap *ar = rmaps_for_group(true, rgno); + struct xfs_mount *mp = rtg->rtg_mount; + xfs_rgnumber_t rgno = rtg->rtg_rgno; + const char *name; + struct xfs_inode *ip; struct xfs_trans *tp; - xfs_ino_t ino; int error; if (!xfs_has_rtrmapbt(mp)) return 0; - error = -libxfs_rtrmapbt_create_path(mp, rgno, &path); - if (error) - return error; + name = xfs_rtrmapbt_name(rgno); + if (!name) + return ENOMEM; error = -libxfs_trans_alloc_empty(mp, &tp); - if (error) - goto out_path; + if (error) { + kfree(name); + return error; + } - error = -libxfs_imeta_lookup(tp, path, &ino); - if (error) + error = -libxfs_imeta_dir_lookup(tp, mp->m_rtdirip, name, + XFS_DIR3_FT_REG_FILE, &ip); + kfree(name); + if (error) { + if (error == ENOENT) + error = EFSCORRUPTED; goto out_trans; + } - if (ino == NULLFSINO || bitmap_test(rmap_inodes, ino, 1)) { - error = EFSCORRUPTED; + if (bitmap_test(rmap_inodes, ip->i_ino, 1)) { + xfs_irele(ip); goto out_trans; } - error = bitmap_set(rmap_inodes, ino, 1); - if (error) + error = bitmap_set(rmap_inodes, ip->i_ino, 1); + if (error) { + xfs_irele(ip); goto out_trans; + } - ar->rg_rmap_ino = ino; + rtg->rtg_rmapip = ip; out_trans: libxfs_trans_cancel(tp); -out_path: - libxfs_imeta_free_path(path); return error; } static inline int set_rtgroup_refcount_inode( - struct xfs_mount *mp, - xfs_rgnumber_t rgno) + struct xfs_rtgroup *rtg) { - struct xfs_imeta_path *path; - struct xfs_ag_rmap *ar = rmaps_for_group(true, rgno); + struct xfs_mount *mp = rtg->rtg_mount; + xfs_rgnumber_t rgno = rtg->rtg_rgno; struct xfs_trans *tp; - xfs_ino_t ino; + struct xfs_inode *ip; + const char *name; int error; if (!xfs_has_rtreflink(mp)) return 0; - error = -libxfs_rtrefcountbt_create_path(mp, rgno, &path); - if (error) - return error; + name = xfs_rtrefcountbt_name(rgno); + if (!name) + return ENOMEM; error = -libxfs_trans_alloc_empty(mp, &tp); if (error) - goto out_path; + return error; - error = -libxfs_imeta_lookup(tp, path, &ino); - if (error) + error = -libxfs_imeta_dir_lookup(tp, mp->m_rtdirip, name, + XFS_DIR3_FT_REG_FILE, &ip); + if (error) { + if (error == ENOENT) + error = EFSCORRUPTED; goto out_trans; + } - if (ino == NULLFSINO || bitmap_test(refcount_inodes, ino, 1)) { - error = EFSCORRUPTED; + if (bitmap_test(refcount_inodes, ip->i_ino, 1)) { + xfs_irele(ip); goto out_trans; } - error = bitmap_set(refcount_inodes, ino, 1); - if (error) + error = bitmap_set(refcount_inodes, ip->i_ino, 1); + if (error) { + xfs_irele(ip); goto out_trans; + } - ar->rg_refcount_ino = ino; + rtg->rtg_refcountip = ip; out_trans: libxfs_trans_cancel(tp); -out_path: - libxfs_imeta_free_path(path); return error; } @@ -281,9 +278,14 @@ static void discover_rtgroup_inodes( struct xfs_mount *mp) { + struct xfs_rtgroup *rtg = NULL; + struct xfs_trans *tp; xfs_rgnumber_t rgno; int error; + if (!xfs_has_rtgroups(mp)) + return; + error = bitmap_alloc(&rmap_inodes); if (error) goto out; @@ -294,12 +296,23 @@ discover_rtgroup_inodes( goto out; } - for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) { - int err2 = set_rtgroup_rmap_inode(mp, rgno); + error = xfs_trans_alloc_empty(mp, &tp); + if (error) + goto out; + error = -libxfs_imeta_dir_lookup(tp, mp->m_metadirip, "realtime", + XFS_DIR3_FT_DIR, &mp->m_rtdirip); + xfs_trans_cancel(tp); + if (error) { + printf("failed to read RT inode: %d\n", error); + goto out; + } + + for_each_rtgroup(mp, rgno, rtg) { + int err2 = set_rtgroup_rmap_inode(rtg); if (err2 && !error) error = err2; - err2 = set_rtgroup_refcount_inode(mp, rgno); + err2 = set_rtgroup_refcount_inode(rtg); if (err2 && !error) error = err2; } @@ -315,8 +328,10 @@ out: } static inline void -free_rtmeta_inode_bitmaps(void) +free_rtmeta_inode_bitmaps( + struct xfs_mount *mp) { + xfs_irele(mp->m_rtdirip); bitmap_free(&refcount_inodes); bitmap_free(&rmap_inodes); } @@ -333,13 +348,14 @@ rtgroup_for_rtrefcount_inode( struct xfs_mount *mp, xfs_ino_t ino) { + struct xfs_rtgroup *rtg; xfs_rgnumber_t rgno; if (!refcount_inodes) return NULLRGNUMBER; - for (rgno = 0; rgno < mp->m_sb.sb_rgcount; rgno++) { - if (rg_rmaps[rgno].rg_refcount_ino == ino) + for_each_rtgroup(mp, rgno, rtg) { + if (rtg->rtg_rmapip->i_ino == ino) return rgno; } @@ -396,7 +412,7 @@ rmaps_free( if (!rmap_needs_work(mp)) return; - free_rtmeta_inode_bitmaps(); + free_rtmeta_inode_bitmaps(mp); for (i = 0; i < mp->m_sb.sb_rgcount; i++) rmaps_destroy(mp, &rg_rmaps[i]); @@ -1376,9 +1392,7 @@ rmap_avoid_check( xfs_rgnumber_t rgno; for_each_rtgroup(mp, rgno, rtg) { - struct xfs_ag_rmap *ar = rmaps_for_group(true, rtg->rtg_rgno); - - ar->rg_rmap_ino = NULLFSINO; + ; // XXX: drop rmap_ip?? } bitmap_clear(rmap_inodes, 0, XFS_MAXINUMBER); @@ -1646,7 +1660,6 @@ rtrmaps_verify_btree( struct rmap_mem_cur rm_cur; struct xfs_btree_cur *bt_cur = NULL; struct xfs_rtgroup *rtg = NULL; - struct xfs_ag_rmap *ar = rmaps_for_group(true, rgno); struct xfs_inode *ip = NULL; int error; @@ -1671,8 +1684,8 @@ rtrmaps_verify_btree( goto err_rcur; } - error = threadsafe_imeta_iget(mp, ar->rg_rmap_ino, &ip); - if (error) { + ip = rtg->rtg_rmapip; + if (!ip) { do_warn( _("Could not load rtgroup %u rmap inode, error %d.\n"), rgno, error); @@ -1684,20 +1697,20 @@ _("Could not load rtgroup %u rmap inode, error %d.\n"), _("rtgroup %u rmap inode has wrong format 0x%x, expected 0x%x\n"), rgno, ip->i_df.if_format, XFS_DINODE_FMT_RMAP); - goto err_ino; + goto err_rtg; } if (xfs_inode_has_attr_fork(ip) && !(xfs_has_metadir(mp) && xfs_has_parent(mp))) { do_warn( _("rtgroup %u rmap inode should not have extended attributes\n"), rgno); - goto err_ino; + goto err_rtg; } bt_cur = libxfs_rtrmapbt_init_cursor(mp, NULL, rtg, ip); if (!bt_cur) { do_warn(_("Not enough memory to check reverse mappings.\n")); - goto err_ino; + goto err_rtg; } error = rmap_compare_records(&rm_cur, bt_cur, rgno); @@ -1706,8 +1719,6 @@ _("rtgroup %u rmap inode should not have extended attributes\n"), rgno); err_cur: libxfs_btree_del_cursor(bt_cur, error); -err_ino: - libxfs_imeta_irele(ip); err_rtg: libxfs_rtgroup_put(rtg); err_rcur: @@ -1963,9 +1974,7 @@ refcount_avoid_check( xfs_rgnumber_t rgno; for_each_rtgroup(mp, rgno, rtg) { - struct xfs_ag_rmap *ar = rmaps_for_group(true, rtg->rtg_rgno); - - ar->rg_refcount_ino = NULLFSINO; + ; // XXX: drop refcountip?? } bitmap_clear(refcount_inodes, 0, XFS_MAXINUMBER); @@ -2113,7 +2122,6 @@ check_rtrefcounts( struct xfs_btree_cur *bt_cur = NULL; struct xfs_rtgroup *rtg = NULL; struct xfs_inode *ip = NULL; - struct xfs_ag_rmap *ar = rmaps_for_group(true, rgno); int error; if (!xfs_has_reflink(mp) || add_reflink) @@ -2142,12 +2150,11 @@ check_rtrefcounts( goto err_rcur; } - error = threadsafe_imeta_iget(mp, ar->rg_refcount_ino, &ip); - if (error) { + ip = rtg->rtg_refcountip; + if (!ip) { do_warn( -_("Cannot load rtgroup %u refcount inode 0x%llx, error %d.\n"), +_("Cannot load rtgroup %u refcount inode, error %d.\n"), rgno, - (unsigned long long)ar->rg_refcount_ino, error); goto err_rtg; } @@ -2158,7 +2165,7 @@ _("rtgroup %u refcount inode has wrong format 0x%x, expected 0x%x\n"), rgno, ip->i_df.if_format, XFS_DINODE_FMT_REFCOUNT); - goto err_ino; + goto err_rtg; } if (xfs_inode_has_attr_fork(ip) && @@ -2166,13 +2173,13 @@ _("rtgroup %u refcount inode has wrong format 0x%x, expected 0x%x\n"), do_warn( _("rtgroup %u refcount inode should not have extended attributes\n"), rgno); - goto err_ino; + goto err_rtg; } bt_cur = libxfs_rtrefcountbt_init_cursor(mp, NULL, rtg, ip); if (!bt_cur) { do_warn(_("Not enough memory to check refcount data.\n")); - goto err_ino; + goto err_rtg; } error = check_refcount_records(rl_cur, bt_cur, rgno); @@ -2181,8 +2188,6 @@ _("rtgroup %u refcount inode should not have extended attributes\n"), err_cur: libxfs_btree_del_cursor(bt_cur, error); -err_ino: - libxfs_imeta_irele(ip); err_rtg: libxfs_rtgroup_put(rtg); err_rcur: @@ -2312,16 +2317,6 @@ estimate_refcountbt_blocks( slab_count(x->ar_refcount_items)); } -/* Retrieve the rtrmapbt inode number for a given rtgroup. */ -xfs_ino_t -rtgroup_rmap_ino( - struct xfs_rtgroup *rtg) -{ - struct xfs_ag_rmap *ar = rmaps_for_group(true, rtg->rtg_rgno); - - return ar->rg_rmap_ino; -} - /* Estimate the size of the ondisk rtrmapbt from the incore tree. */ xfs_filblks_t estimate_rtrmapbt_blocks( @@ -2348,15 +2343,6 @@ estimate_rtrmapbt_blocks( return libxfs_rtrmapbt_calc_size(mp, nr_recs); } -xfs_ino_t -rtgroup_refcount_ino( - struct xfs_rtgroup *rtg) -{ - struct xfs_ag_rmap *ar = rmaps_for_group(true, rtg->rtg_rgno); - - return ar->rg_refcount_ino; -} - /* Estimate the size of the ondisk rtrefcountbt from the incore data. */ xfs_filblks_t estimate_rtrefcountbt_blocks( diff --git a/repair/rmap.h b/repair/rmap.h index 74322044c..a3f018c9b 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -69,7 +69,6 @@ void rmap_free_mem_cursor(struct xfs_trans *tp, struct rmap_mem_cur *rmcur, int rmap_get_mem_rec(struct rmap_mem_cur *rmcur, struct xfs_rmap_irec *irec); bool is_rtrmap_inode(xfs_ino_t ino); -xfs_ino_t rtgroup_rmap_ino(struct xfs_rtgroup *rtg); int populate_rtgroup_rmapbt(struct xfs_rtgroup *rtg, struct xfs_inode *ip, xfs_filblks_t fdblocks); xfs_filblks_t estimate_rtrmapbt_blocks(struct xfs_rtgroup *rtg); @@ -77,7 +76,6 @@ xfs_filblks_t estimate_rtrmapbt_blocks(struct xfs_rtgroup *rtg); xfs_rgnumber_t rtgroup_for_rtrefcount_inode(struct xfs_mount *mp, xfs_ino_t ino); bool is_rtrefcount_ino(xfs_ino_t ino); -xfs_ino_t rtgroup_refcount_ino(struct xfs_rtgroup *rtg); int populate_rtgroup_refcountbt(struct xfs_rtgroup *rtg, struct xfs_inode *ip, xfs_filblks_t fdblocks); xfs_filblks_t estimate_rtrefcountbt_blocks(struct xfs_rtgroup *rtg); diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 587dbc347..4e48d92a4 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -703,10 +703,6 @@ check_metadir_inode( goto done; } - error = -libxfs_imeta_mount(tp); - if (error) - need_metadir_inode = true; - libxfs_trans_cancel(tp); } -- 2.50.1