@@ -750,78 +750,102 @@ parse_proto(
parseproto(mp, NULL, fsx, pp, NULL);
}
-/*
- * Allocate the realtime bitmap and summary inodes, and fill in data if any.
- */
+/* Create a sb-rooted metadata file. */
static void
-rtinit(
- struct xfs_mount *mp)
+create_sb_metadata_file(
+ struct xfs_mount *mp,
+ void (*create)(struct xfs_inode *ip))
{
- struct cred creds;
- struct fsxattr fsxattrs;
- struct xfs_bmbt_irec map[XFS_BMAP_MAX_NMAP];
- struct xfs_inode *rbmip;
- struct xfs_inode *rsumip;
+ struct xfs_icreate_args args = {
+ .mode = S_IFREG,
+ .flags = XFS_ICREATE_UNLINKABLE,
+ };
struct xfs_trans *tp;
- struct xfs_bmbt_irec *ep;
- xfs_fileoff_t bno;
- xfs_extlen_t nsumblocks;
- uint blocks;
- int i;
- int nmap;
+ struct xfs_inode *ip = NULL;
+ xfs_ino_t ino;
int error;
- /* Create the realtime bitmap inode. */
error = -libxfs_trans_alloc_rollable(mp, MKFS_BLOCKRES_INODE, &tp);
if (error)
res_failed(error);
- memset(&creds, 0, sizeof(creds));
- memset(&fsxattrs, 0, sizeof(fsxattrs));
- error = creatproto(&tp, NULL, S_IFREG, 0, &creds, &fsxattrs, &rbmip);
- if (error) {
- fail(_("Realtime bitmap inode allocation failed"), error);
- }
- /*
- * Do our thing with rbmip before allocating rsumip,
- * because the next call to createproto may
- * commit the transaction in which rbmip was allocated.
- */
- mp->m_sb.sb_rbmino = rbmip->i_ino;
- rbmip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
- rbmip->i_diflags = XFS_DIFLAG_NEWRTBM;
- inode_set_atime(VFS_I(rbmip), 0, 0);
- libxfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE);
- libxfs_log_sb(tp);
- mp->m_rbmip = rbmip;
+ error = -libxfs_dialloc(&tp, 0, args.mode, &ino);
+ if (error)
+ goto fail;
+
+ error = -libxfs_icreate(tp, ino, &args, &ip);
+ if (error)
+ goto fail;
- /* Create the realtime summary inode. */
- error = creatproto(&tp, NULL, S_IFREG, 0, &creds, &fsxattrs, &rsumip);
- if (error) {
- fail(_("Realtime summary inode allocation failed"), error);
- }
- mp->m_sb.sb_rsumino = rsumip->i_ino;
- rsumip->i_disk_size = mp->m_rsumsize;
- libxfs_trans_log_inode(tp, rsumip, XFS_ILOG_CORE);
+ create(ip);
+
+ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
libxfs_log_sb(tp);
+
error = -libxfs_trans_commit(tp);
if (error)
- fail(_("Completion of the realtime summary inode failed"),
- error);
- mp->m_rsumip = rsumip;
+ goto fail;
+
+fail:
+ if (ip)
+ libxfs_irele(ip);
+ if (error)
+ fail(_("Realtime inode allocation failed"), error);
+}
+
+static void
+rtbitmap_create(
+ struct xfs_inode *ip)
+{
+ struct xfs_mount *mp = ip->i_mount;
+
+ ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
+ ip->i_diflags |= XFS_DIFLAG_NEWRTBM;
+ 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
+rtsummary_create(
+ struct xfs_inode *ip)
+{
+ struct xfs_mount *mp = ip->i_mount;
+
+ ip->i_disk_size = mp->m_rsumsize;
+
+ mp->m_sb.sb_rsumino = ip->i_ino;
+ mp->m_rsumip = ip;
+ ihold(VFS_I(ip));
+}
+
+/* Zero the realtime bitmap. */
+static void
+rtbitmap_init(
+ struct xfs_mount *mp)
+{
+ struct xfs_bmbt_irec map[XFS_BMAP_MAX_NMAP];
+ struct xfs_trans *tp;
+ struct xfs_bmbt_irec *ep;
+ xfs_fileoff_t bno;
+ uint blocks;
+ int i;
+ int nmap;
+ int error;
- /* Zero the realtime bitmap. */
blocks = mp->m_sb.sb_rbmblocks +
XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
if (error)
res_failed(error);
- libxfs_trans_ijoin(tp, rbmip, 0);
+ libxfs_trans_ijoin(tp, mp->m_rbmip, 0);
bno = 0;
while (bno < mp->m_sb.sb_rbmblocks) {
nmap = XFS_BMAP_MAX_NMAP;
- error = -libxfs_bmapi_write(tp, rbmip, bno,
+ error = -libxfs_bmapi_write(tp, mp->m_rbmip, bno,
(xfs_extlen_t)(mp->m_sb.sb_rbmblocks - bno),
0, mp->m_sb.sb_rbmblocks, map, &nmap);
if (error)
@@ -840,19 +864,34 @@ rtinit(
if (error)
fail(_("Block allocation of the realtime bitmap inode failed"),
error);
+}
+
+/* Zero the realtime summary file. */
+static void
+rtsummary_init(
+ struct xfs_mount *mp)
+{
+ struct xfs_bmbt_irec map[XFS_BMAP_MAX_NMAP];
+ struct xfs_trans *tp;
+ struct xfs_bmbt_irec *ep;
+ xfs_fileoff_t bno;
+ xfs_extlen_t nsumblocks;
+ uint blocks;
+ int i;
+ int nmap;
+ int error;
- /* Zero the summary file. */
nsumblocks = mp->m_rsumsize >> mp->m_sb.sb_blocklog;
blocks = nsumblocks + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1;
error = -libxfs_trans_alloc_rollable(mp, blocks, &tp);
if (error)
res_failed(error);
- libxfs_trans_ijoin(tp, rsumip, 0);
+ libxfs_trans_ijoin(tp, mp->m_rsumip, 0);
bno = 0;
while (bno < nsumblocks) {
nmap = XFS_BMAP_MAX_NMAP;
- error = -libxfs_bmapi_write(tp, rsumip, bno,
+ error = -libxfs_bmapi_write(tp, mp->m_rsumip, bno,
(xfs_extlen_t)(nsumblocks - bno),
0, nsumblocks, map, &nmap);
if (error)
@@ -870,8 +909,6 @@ rtinit(
if (error)
fail(_("Block allocation of the realtime summary inode failed"),
error);
-
- rtfreesp_init(mp);
}
/*
@@ -910,6 +947,21 @@ rtfreesp_init(
}
}
+/*
+ * Allocate the realtime bitmap and summary inodes, and fill in data if any.
+ */
+static void
+rtinit(
+ struct xfs_mount *mp)
+{
+ create_sb_metadata_file(mp, rtbitmap_create);
+ create_sb_metadata_file(mp, rtsummary_create);
+
+ rtbitmap_init(mp);
+ rtsummary_init(mp);
+ rtfreesp_init(mp);
+}
+
static long
filesize(
int fd)