diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-09-01 11:16:52 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-12-15 17:29:15 -0800 |
commit | cdd6eca08c60201a519d5d18c83df07f1c435f9f (patch) | |
tree | 1e40011adac26cfc3c62465a2aa36954b3b6839c /fs/xfs/libxfs | |
parent | 52bde316dccda396df4435d63b6073461abc8b61 (diff) |
xfs: create routine to allocate and initialize a realtime rmap btree inode
Create a library routine to allocate and initialize an empty realtime
rmapbt inode. We'll use this for mkfs and repair.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_rtrmap_btree.c | 48 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rtrmap_btree.h | 5 |
2 files changed, 53 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.c b/fs/xfs/libxfs/xfs_rtrmap_btree.c index 3f47586a7711..6684ec59bc7a 100644 --- a/fs/xfs/libxfs/xfs_rtrmap_btree.c +++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c @@ -25,6 +25,7 @@ #include "xfs_error.h" #include "xfs_extent_busy.h" #include "xfs_bmap.h" +#include "xfs_imeta.h" static struct kmem_cache *xfs_rtrmapbt_cur_cache; @@ -797,3 +798,50 @@ xfs_iflush_rtrmap( xfs_rtrmapbt_to_disk(ip->i_mount, ifp->if_broot, ifp->if_broot_bytes, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, XFS_DATA_FORK)); } + +/* + * Create a realtime rmap btree inode. + * + * Regardless of the return value, the caller must clean up @ic. If a new + * inode is returned through *ipp, the caller must finish setting up the incore + * inode and release it. + */ +int +xfs_rtrmapbt_create( + struct xfs_trans **tpp, + struct xfs_imeta_end *ic, + struct xfs_inode **ipp) +{ + struct xfs_mount *mp = (*tpp)->t_mountp; + struct xfs_ifork *ifp; + struct xfs_inode *ip; + xfs_ino_t ino = NULLFSINO; + int error; + + *ipp = NULL; + error = xfs_imeta_lookup(mp, &XFS_IMETA_RTRMAPBT, &ino); + if (error) + return error; + if (ino != NULLFSINO) + return -EEXIST; + + error = xfs_imeta_create(tpp, &XFS_IMETA_RTRMAPBT, S_IFREG, 0, ipp, ic); + if (error) + return error; + + ip = *ipp; + ifp = &ip->i_df; + ifp->if_format = XFS_DINODE_FMT_RMAP; + ASSERT(ifp->if_broot_bytes == 0); + ASSERT(ifp->if_bytes == 0); + + /* Initialize the empty incore btree root. */ + xfs_iroot_alloc(ip, XFS_DATA_FORK, + xfs_rtrmap_broot_space_calc(mp, 0, 0)); + xfs_btree_init_block_int(ip->i_mount, ifp->if_broot, + XFS_BUF_DADDR_NULL, XFS_BTNUM_RTRMAP, 0, 0, ip->i_ino, + XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); + xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE | XFS_ILOG_DBROOT); + + return 0; +} diff --git a/fs/xfs/libxfs/xfs_rtrmap_btree.h b/fs/xfs/libxfs/xfs_rtrmap_btree.h index 704ce98b938b..568fd376bed2 100644 --- a/fs/xfs/libxfs/xfs_rtrmap_btree.h +++ b/fs/xfs/libxfs/xfs_rtrmap_btree.h @@ -191,4 +191,9 @@ void xfs_rtrmapbt_to_disk(struct xfs_mount *mp, struct xfs_btree_block *rblock, unsigned int dblocklen); void xfs_iflush_rtrmap(struct xfs_inode *ip, struct xfs_dinode *dip); +struct xfs_imeta_end; + +int xfs_rtrmapbt_create(struct xfs_trans **tpp, struct xfs_imeta_end *ic, + struct xfs_inode **ipp); + #endif /* __XFS_RTRMAP_BTREE_H__ */ |