From: Darrick J. Wong <djwong@xxxxxxxxxx> Create a libxfs_iget_meta function for metadata inodes to ensure that we always check that the inobt thinks a metadata inode is in use. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- libxfs/init.c | 4 ++-- libxfs/inode.c | 32 ++++++++++++++++++++++++++++++++ libxfs/libxfs_api_defs.h | 2 ++ libxfs/xfs_imeta.h | 5 +++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/libxfs/init.c b/libxfs/init.c index e19b4e6d4cf..d114ac87f19 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -983,9 +983,9 @@ void libxfs_rtmount_destroy(xfs_mount_t *mp) { if (mp->m_rsumip) - libxfs_irele(mp->m_rsumip); + libxfs_imeta_irele(mp->m_rsumip); if (mp->m_rbmip) - libxfs_irele(mp->m_rbmip); + libxfs_imeta_irele(mp->m_rbmip); mp->m_rsumip = mp->m_rbmip = NULL; } diff --git a/libxfs/inode.c b/libxfs/inode.c index 1a27016a763..95a1ba50cdf 100644 --- a/libxfs/inode.c +++ b/libxfs/inode.c @@ -216,6 +216,31 @@ libxfs_iget( return error; } +/* Get a metadata inode. The ftype must match exactly. */ +int +libxfs_imeta_iget( + struct xfs_mount *mp, + xfs_ino_t ino, + unsigned char ftype, + struct xfs_inode **ipp) +{ + struct xfs_inode *ip; + int error; + + error = libxfs_iget(mp, NULL, ino, 0, &ip); + if (error) + return error; + + if (ftype == XFS_DIR3_FT_UNKNOWN || + xfs_mode_to_ftype(VFS_I(ip)->i_mode) != ftype) { + libxfs_irele(ip); + return -EFSCORRUPTED; + } + + *ipp = ip; + return 0; +} + static void libxfs_idestroy( struct xfs_inode *ip) @@ -249,6 +274,13 @@ libxfs_irele( } } +void +libxfs_imeta_irele( + struct xfs_inode *ip) +{ + libxfs_irele(ip); +} + void xfs_inode_sgid_inherit( const struct xfs_icreate_args *args, diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index 69f1cf2c752..c27949e5f48 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -159,6 +159,8 @@ #define xfs_imeta_create libxfs_imeta_create #define xfs_imeta_create_space_res libxfs_imeta_create_space_res #define xfs_imeta_end_update libxfs_imeta_end_update +#define xfs_imeta_iget libxfs_imeta_iget +#define xfs_imeta_irele libxfs_imeta_irele #define xfs_imeta_link libxfs_imeta_link #define xfs_imeta_lookup libxfs_imeta_lookup #define xfs_imeta_mount libxfs_imeta_mount diff --git a/libxfs/xfs_imeta.h b/libxfs/xfs_imeta.h index 9d54cb0d796..312e3a6fdb9 100644 --- a/libxfs/xfs_imeta.h +++ b/libxfs/xfs_imeta.h @@ -48,4 +48,9 @@ int xfs_imeta_mount(struct xfs_mount *mp); unsigned int xfs_imeta_create_space_res(struct xfs_mount *mp); unsigned int xfs_imeta_unlink_space_res(struct xfs_mount *mp); +/* Must be implemented by the libxfs client */ +int xfs_imeta_iget(struct xfs_mount *mp, xfs_ino_t ino, unsigned char ftype, + struct xfs_inode **ipp); +void xfs_imeta_irele(struct xfs_inode *ip); + #endif /* __XFS_IMETA_H__ */