@@ -192,6 +192,7 @@
#define xfs_inode_from_disk libxfs_inode_from_disk
#define xfs_inode_from_disk_ts libxfs_inode_from_disk_ts
#define xfs_inode_hasattr libxfs_inode_hasattr
+#define xfs_inode_init libxfs_inode_init
#define xfs_inode_to_disk libxfs_inode_to_disk
#define xfs_inode_validate_cowextsize libxfs_inode_validate_cowextsize
#define xfs_inode_validate_extsize libxfs_inode_validate_extsize
@@ -447,20 +447,31 @@ res_failed(
do_error(_("xfs_trans_reserve returned %d\n"), err);
}
-static inline void
-reset_inode_fields(struct xfs_inode *ip)
+/*
+ * Forcibly reinitialize a file that is a child of the superblock and has a
+ * statically defined inumber. These files are the root of a directory tree or
+ * the realtime free space inodes. The inode must not otherwise be in use; the
+ * data fork must be empty, and the attr fork will be reset.
+ */
+static void
+reset_sbroot_ino(
+ struct xfs_trans *tp,
+ umode_t mode,
+ struct xfs_inode *ip)
{
- ip->i_projid = 0;
- ip->i_disk_size = 0;
- ip->i_nblocks = 0;
- ip->i_extsize = 0;
- ip->i_cowextsize = 0;
- ip->i_flushiter = 0;
+ struct xfs_icreate_args args = {
+ .idmap = libxfs_nop_idmap,
+ .mode = mode,
+ /* Root directories cannot be linked to a parent. */
+ .flags = XFS_ICREATE_UNLINKABLE,
+ };
+
+ /* Erase the attr fork since libxfs_inode_init won't do it for us. */
ip->i_forkoff = 0;
- ip->i_diflags = 0;
- ip->i_diflags2 = 0;
- ip->i_crtime.tv_sec = 0;
- ip->i_crtime.tv_nsec = 0;
+ libxfs_ifork_zap_attr(ip);
+
+ libxfs_trans_ijoin(tp, ip, 0);
+ libxfs_inode_init(tp, &args, ip);
}
static void
@@ -474,7 +485,6 @@ mk_rbmino(xfs_mount_t *mp)
int error;
xfs_fileoff_t bno;
xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
- int times;
uint blocks;
/*
@@ -491,34 +501,9 @@ mk_rbmino(xfs_mount_t *mp)
error);
}
- reset_inode_fields(ip);
-
- VFS_I(ip)->i_mode = S_IFREG;
- ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
- libxfs_ifork_zap_attr(ip);
-
- set_nlink(VFS_I(ip), 1); /* account for sb ptr */
-
- times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
- if (xfs_has_v3inodes(mp)) {
- VFS_I(ip)->i_version = 1;
- ip->i_diflags2 = 0;
- times |= XFS_ICHGTIME_CREATE;
- }
- libxfs_trans_ichgtime(tp, ip, times);
-
- /*
- * now the ifork
- */
- ip->i_df.if_bytes = 0;
- ip->i_df.if_data = NULL;
-
+ /* Reset the realtime bitmap inode. */
+ reset_sbroot_ino(tp, S_IFREG, ip);
ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
-
- /*
- * commit changes
- */
- libxfs_trans_ijoin(tp, ip, 0);
libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
error = -libxfs_trans_commit(tp);
if (error)
@@ -729,7 +714,6 @@ mk_rsumino(xfs_mount_t *mp)
int nsumblocks;
xfs_fileoff_t bno;
xfs_bmbt_irec_t map[XFS_BMAP_MAX_NMAP];
- int times;
uint blocks;
/*
@@ -746,34 +730,9 @@ mk_rsumino(xfs_mount_t *mp)
error);
}
- reset_inode_fields(ip);
-
- VFS_I(ip)->i_mode = S_IFREG;
- ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
- libxfs_ifork_zap_attr(ip);
-
- set_nlink(VFS_I(ip), 1); /* account for sb ptr */
-
- times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
- if (xfs_has_v3inodes(mp)) {
- VFS_I(ip)->i_version = 1;
- ip->i_diflags2 = 0;
- times |= XFS_ICHGTIME_CREATE;
- }
- libxfs_trans_ichgtime(tp, ip, times);
-
- /*
- * now the ifork
- */
- ip->i_df.if_bytes = 0;
- ip->i_df.if_data = NULL;
-
+ /* Reset the rt summary inode. */
+ reset_sbroot_ino(tp, S_IFREG, ip);
ip->i_disk_size = mp->m_rsumsize;
-
- /*
- * commit changes
- */
- libxfs_trans_ijoin(tp, ip, 0);
libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
error = -libxfs_trans_commit(tp);
if (error)
@@ -829,7 +788,6 @@ mk_root_dir(xfs_mount_t *mp)
int error;
const mode_t mode = 0755;
ino_tree_node_t *irec;
- int times;
ip = NULL;
i = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 10, 0, 0, &tp);
@@ -841,37 +799,8 @@ mk_root_dir(xfs_mount_t *mp)
do_error(_("could not iget root inode -- error - %d\n"), error);
}
- /*
- * take care of the core since we didn't call the libxfs ialloc function
- * (comment changed to avoid tangling xfs/437)
- */
- reset_inode_fields(ip);
-
- VFS_I(ip)->i_mode = mode|S_IFDIR;
- ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
- libxfs_ifork_zap_attr(ip);
-
- set_nlink(VFS_I(ip), 2); /* account for . and .. */
-
- times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
- if (xfs_has_v3inodes(mp)) {
- VFS_I(ip)->i_version = 1;
- ip->i_diflags2 = 0;
- times |= XFS_ICHGTIME_CREATE;
- }
- libxfs_trans_ichgtime(tp, ip, times);
- libxfs_trans_ijoin(tp, ip, 0);
- libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
- /*
- * now the ifork
- */
- ip->i_df.if_bytes = 0;
- ip->i_df.if_data = NULL;
-
- /*
- * initialize the directory
- */
+ /* Reset the root directory. */
+ reset_sbroot_ino(tp, mode | S_IFDIR, ip);
libxfs_dir_init(tp, ip, ip);
error = -libxfs_trans_commit(tp);