kfree(ptr);
}
+static inline void kvfree(const void *ptr)
+{
+ kfree(ptr);
+}
__attribute__((format(printf,2,3)))
char *kasprintf(gfp_t gfp, const char *fmt, ...);
uint m_rsumlevels; /* rt summary levels */
xfs_filblks_t m_rsumblocks; /* size of rt summary, FSBs */
uint32_t m_rgblocks; /* size of rtgroup in rtblocks */
- /*
- * Optional cache of rt summary level per bitmap block with the
- * invariant that m_rsum_cache[bbno] <= the minimum i for which
- * rsum[i][bbno] != 0. Reads and writes are serialized by the rsumip
- * inode lock.
- */
- uint8_t *m_rsum_cache;
- 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 realtime metadir */
struct xfs_buftarg *m_ddev_targp;
mp->m_rsumlevels = mp->m_sb.sb_rextslog + 1;
mp->m_rsumblocks = xfs_rtsummary_blockcount(mp, mp->m_rsumlevels,
mp->m_sb.sb_rbmblocks);
- mp->m_rbmip = mp->m_rsumip = NULL;
/*
* Allow debugger to be run without the realtime device present.
if (rtg->rtg_inodes[i])
libxfs_irele(rtg->rtg_inodes[i]);
rtg->rtg_inodes[i] = NULL;
+ kvfree(rtg->rtg_rsum_cache);
}
}
if (mp->m_rtdirip)
libxfs_irele(mp->m_rtdirip);
- if (mp->m_rsumip)
- libxfs_irele(mp->m_rsumip);
- if (mp->m_rbmip)
- libxfs_irele(mp->m_rbmip);
- mp->m_rsumip = mp->m_rbmip = mp->m_rtdirip = NULL;
}
/* Flush a device and report on writes that didn't make it to stable storage. */
#define xfs_free_extent_later libxfs_free_extent_later
#define xfs_free_perag libxfs_free_perag
#define xfs_free_rtgroups libxfs_free_rtgroups
+#define xfs_rtginode_load libxfs_rtginode_load
+#define xfs_rtginode_create libxfs_rtginode_create
+#define xfs_rtginode_load_parent libxfs_rtginode_load_parent
+#define xfs_rtginode_mkdir_parent libxfs_rtginode_mkdir_parent
+#define xfs_rtginode_irele libxfs_rtginode_irele
+#define xfs_rtginode_name libxfs_rtginode_name
#define xfs_fs_geometry libxfs_fs_geometry
#define xfs_get_projid libxfs_get_projid
#define xfs_get_initial_prid libxfs_get_initial_prid
/* Create a sb-rooted metadata file. */
static void
create_sb_metadata_file(
- struct xfs_mount *mp,
+ struct xfs_rtgroup *rtg,
+ enum xfs_rtg_inodes type,
void (*create)(struct xfs_inode *ip))
{
+ struct xfs_mount *mp = rtg->rtg_mount;
struct xfs_icreate_args args = {
.mode = S_IFREG,
.flags = XFS_ICREATE_UNLINKABLE,
error = -libxfs_trans_commit(tp);
if (error)
goto fail;
+ rtg->rtg_inodes[type] = ip;
+ return;
fail:
if (ip)
inode_set_atime(VFS_I(ip), 0, 0);
mp->m_sb.sb_rbmino = ip->i_ino;
- mp->m_rbmip = ip;
- ihold(VFS_I(ip));
}
static void
ip->i_disk_size = mp->m_rsumblocks * mp->m_sb.sb_blocksize;
mp->m_sb.sb_rsumino = ip->i_ino;
- mp->m_rsumip = ip;
- ihold(VFS_I(ip));
}
/*
*/
static void
rtfreesp_init(
- struct xfs_mount *mp)
+ struct xfs_rtgroup *rtg)
{
+ struct xfs_mount *mp = rtg->rtg_mount;
struct xfs_trans *tp;
xfs_rtxnum_t rtx;
xfs_rtxnum_t ertx;
/*
* First zero the realtime bitmap and summary files.
*/
- error = -libxfs_rtfile_initialize_blocks(mp->m_rbmip, 0,
+ error = -libxfs_rtfile_initialize_blocks(rtg, XFS_RTG_BITMAP, 0,
mp->m_sb.sb_rbmblocks, NULL);
if (error)
fail(_("Initialization of rtbitmap inode failed"), error);
- error = -libxfs_rtfile_initialize_blocks(mp->m_rsumip, 0,
+ error = -libxfs_rtfile_initialize_blocks(rtg, XFS_RTG_SUMMARY, 0,
mp->m_rsumblocks, NULL);
if (error)
fail(_("Initialization of rtsummary inode failed"), error);
if (error)
res_failed(error);
- libxfs_trans_ijoin(tp, mp->m_rbmip, 0);
+ libxfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTG_BITMAP], 0);
ertx = min(mp->m_sb.sb_rextents,
rtx + NBBY * mp->m_sb.sb_blocksize);
- error = -libxfs_rtfree_extent(tp, rtx,
+ error = -libxfs_rtfree_extent(tp, rtg, rtx,
(xfs_rtxlen_t)(ertx - rtx));
if (error) {
fail(_("Error initializing the realtime space"),
rtinit(
struct xfs_mount *mp)
{
- create_sb_metadata_file(mp, rtbitmap_create);
- create_sb_metadata_file(mp, rtsummary_create);
+ struct xfs_rtgroup *rtg;
+ xfs_rgnumber_t rgno;
- rtfreesp_init(mp);
+ for_each_rtgroup(mp, rgno, rtg) {
+ create_sb_metadata_file(rtg, XFS_RTG_BITMAP,
+ rtbitmap_create);
+ create_sb_metadata_file(rtg, XFS_RTG_SUMMARY,
+ rtsummary_create);
+
+ rtfreesp_init(rtg);
+ }
}
static long
set_inode_is_meta(irec, ino_offset);
}
-/* Load a realtime freespace metadata inode from disk and reset it. */
-static int
-ensure_rtino(
- struct xfs_trans *tp,
- xfs_ino_t ino,
- struct xfs_inode **ipp)
-{
- struct xfs_mount *mp = tp->t_mountp;
- int error;
-
- error = -libxfs_iget(mp, tp, ino, 0, ipp);
- if (error)
- return error;
-
- reset_sbroot_ino(tp, S_IFREG, *ipp);
- if (xfs_has_metadir(mp))
- libxfs_metafile_set_iflag(tp, *ipp);
- return 0;
-}
-
static void
-mk_rbmino(
- struct xfs_mount *mp)
+mk_rtino(
+ struct xfs_rtgroup *rtg,
+ enum xfs_rtg_inodes type)
{
+ struct xfs_mount *mp = rtg->rtg_mount;
+ struct xfs_inode *ip = rtg->rtg_inodes[type];
struct xfs_trans *tp;
- struct xfs_inode *ip;
int error;
+ if (!ip) {
+ /*
+ * XXX: we probably should still re-initialize / re-create the
+ * inode if the earlier validations failed.
+ */
+ do_error(_("no %s inode for rtgroup %u\n"),
+ xfs_rtginode_name(type), rtg->rtg_rgno);
+ }
+
error = -libxfs_trans_alloc_rollable(mp, 10, &tp);
if (error)
res_failed(error);
- /* Reset the realtime bitmap inode. */
- error = ensure_rtino(tp, mp->m_sb.sb_rbmino, &ip);
- if (error) {
- do_error(
- _("couldn't iget realtime bitmap inode -- error - %d\n"),
- error);
- }
- ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
- libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- error = -libxfs_trans_commit(tp);
- if (error)
- do_error(_("%s: commit failed, error %d\n"), __func__, error);
- libxfs_irele(ip);
-}
+ reset_sbroot_ino(tp, S_IFREG, ip);
-static void
-mk_rsumino(
- struct xfs_mount *mp)
-{
- struct xfs_trans *tp;
- struct xfs_inode *ip;
- int error;
+ switch (type) {
+ case XFS_RTG_BITMAP:
+ error = -xfs_rtbitmap_create(rtg, ip, tp, false);
+ break;
+ case XFS_RTG_SUMMARY:
+ error = -xfs_rtsummary_create(rtg, ip, tp, false);
+ break;
+ default:
+ error = EINVAL;
+ }
- error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp);
if (error)
- res_failed(error);
+ do_error(_("%s inode re-initialization failed for rtgroup %u\n"),
+ xfs_rtginode_name(type), rtg->rtg_rgno);
- /* Reset the rt summary inode. */
- error = ensure_rtino(tp, mp->m_sb.sb_rsumino, &ip);
- if (error) {
- do_error(
- _("couldn't iget realtime summary inode -- error - %d\n"),
- error);
- }
- ip->i_disk_size = mp->m_rsumblocks * mp->m_sb.sb_blocksize;
- libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
error = -libxfs_trans_commit(tp);
if (error)
do_error(_("%s: commit failed, error %d\n"), __func__, error);
- libxfs_irele(ip);
}
/* Initialize a root directory. */
do_inode_prefetch(mp, ag_stride, traverse_function, false, true);
}
+static void
+reset_rt_sb_inodes(
+ struct xfs_mount *mp)
+{
+ struct xfs_rtgroup *rtg;
+
+ if (no_modify) {
+ if (need_rbmino)
+ do_warn(_("would reinitialize realtime bitmap inode\n"));
+ if (need_rsumino)
+ do_warn(_("would reinitialize realtime summary inode\n"));
+ return;
+ }
+
+ rtg = xfs_rtgroup_grab(mp, 0);
+
+ if (need_rbmino) {
+ do_warn(_("reinitializing realtime bitmap inode\n"));
+ mk_rtino(rtg, XFS_RTG_BITMAP);
+ need_rbmino = 0;
+ }
+
+ if (need_rsumino) {
+ do_warn(_("reinitializing realtime summary inode\n"));
+ mk_rtino(rtg, XFS_RTG_SUMMARY);
+ need_rsumino = 0;
+ }
+
+ do_log(
+_(" - resetting contents of realtime bitmap and summary inodes\n"));
+
+ fill_rtbitmap(rtg);
+ fill_rtsummary(rtg);
+
+ xfs_rtgroup_rele(rtg);
+}
+
void
phase6(xfs_mount_t *mp)
{
do_warn(_("would reinitialize metadata root directory\n"));
}
- if (need_rbmino) {
- if (!no_modify) {
- do_warn(_("reinitializing realtime bitmap inode\n"));
- mk_rbmino(mp);
- need_rbmino = 0;
- } else {
- do_warn(_("would reinitialize realtime bitmap inode\n"));
- }
- }
-
- if (need_rsumino) {
- if (!no_modify) {
- do_warn(_("reinitializing realtime summary inode\n"));
- mk_rsumino(mp);
- need_rsumino = 0;
- } else {
- do_warn(_("would reinitialize realtime summary inode\n"));
- }
- }
-
- if (!no_modify) {
- do_log(
-_(" - resetting contents of realtime bitmap and summary inodes\n"));
- fill_rtbitmap(mp);
- fill_rtsummary(mp);
- }
+ reset_rt_sb_inodes(mp);
mark_standalone_inodes(mp);
do_error(
_("couldn't allocate memory for incore realtime summary info.\n"));
- ASSERT(mp->m_rbmip == NULL);
-
/*
* Slower but simple, don't play around with trying to set things one
* word at a time, just set bit as required. Have to track start and
void
fill_rtbitmap(
- struct xfs_mount *mp)
+ struct xfs_rtgroup *rtg)
{
- struct xfs_trans *tp;
- struct xfs_inode *ip;
int error;
- error = -libxfs_trans_alloc_empty(mp, &tp);
- if (error)
- do_error(
-_("couldn't allocate empty transaction, error %d\n"), error);
- error = -libxfs_iget(mp, tp, mp->m_sb.sb_rbmino, 0, &ip);
- if (error)
- do_error(
-_("couldn't iget realtime bitmap inode, error %d\n"), error);
- libxfs_trans_cancel(tp);
-
- error = -libxfs_rtfile_initialize_blocks(ip, 0, mp->m_sb.sb_rbmblocks,
- btmcompute);
+ error = -libxfs_rtfile_initialize_blocks(rtg, XFS_RTG_BITMAP,
+ 0, rtg->rtg_mount->m_sb.sb_rbmblocks, btmcompute);
if (error)
do_error(
_("couldn't re-initialize realtime bitmap inode, error %d\n"), error);
- libxfs_irele(ip);
}
void
fill_rtsummary(
- struct xfs_mount *mp)
+ struct xfs_rtgroup *rtg)
{
- struct xfs_trans *tp;
- struct xfs_inode *ip;
int error;
- error = -libxfs_trans_alloc_empty(mp, &tp);
- if (error)
- do_error(
-_("couldn't allocate empty transaction, error %d\n"), error);
- error = -libxfs_iget(mp, tp, mp->m_sb.sb_rsumino, 0, &ip);
- if (error) {
- do_error(
-_("couldn't iget realtime summary inode, error - %d\n"), error);
- }
- libxfs_trans_cancel(tp);
-
- mp->m_rsumip = ip;
- error = -libxfs_rtfile_initialize_blocks(ip, 0, mp->m_rsumblocks,
- sumcompute);
- mp->m_rsumip = NULL;
+ error = -libxfs_rtfile_initialize_blocks(rtg, XFS_RTG_SUMMARY,
+ 0, rtg->rtg_mount->m_rsumblocks, sumcompute);
if (error)
do_error(
_("couldn't re-initialize realtime summary inode, error %d\n"), error);
-
- libxfs_irele(ip);
}
void check_rtbitmap(struct xfs_mount *mp);
void check_rtsummary(struct xfs_mount *mp);
-void fill_rtbitmap(struct xfs_mount *mp);
-void fill_rtsummary(struct xfs_mount *mp);
+void fill_rtbitmap(struct xfs_rtgroup *rtg);
+void fill_rtsummary(struct xfs_rtgroup *rtg);
#endif /* _XFS_REPAIR_RT_H_ */