From: Darrick J. Wong <djwong@xxxxxxxxxx> Walk the filesystem to rebuild parent pointer information. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- include/xfs_inode.h | 6 ++++++ libxfs/xfs_parent.c | 31 +++++++++++++++++++++++++++++-- libxfs/xfs_parent.h | 4 ++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/xfs_inode.h b/include/xfs_inode.h index b0bba109..2bbda956 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -175,6 +175,12 @@ static inline struct inode *VFS_I(struct xfs_inode *ip) return &ip->i_vnode; } +/* convert from xfs inode to vfs inode */ +static inline const struct inode *VFS_IC(const struct xfs_inode *ip) +{ + return &ip->i_vnode; +} + /* We only have i_size in the xfs inode in userspace */ static inline loff_t i_size_read(struct inode *inode) { diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c index 1598158f..3ce30860 100644 --- a/libxfs/xfs_parent.c +++ b/libxfs/xfs_parent.c @@ -95,11 +95,11 @@ xfs_parent_valuecheck( static inline void xfs_init_parent_name_rec( struct xfs_parent_name_rec *rec, - struct xfs_inode *ip, + const struct xfs_inode *ip, uint32_t p_diroffset) { xfs_ino_t p_ino = ip->i_ino; - uint32_t p_gen = VFS_I(ip)->i_generation; + uint32_t p_gen = VFS_IC(ip)->i_generation; rec->p_ino = cpu_to_be64(p_ino); rec->p_gen = cpu_to_be32(p_gen); @@ -337,3 +337,30 @@ xfs_parent_lookup( return scr->args.valuelen; } + +/* + * Attach the parent pointer (@pptr -> @name) to @ip immediately. Caller must + * not have a transaction or hold the ILOCK. The update will not use logged + * xattrs. This is for specialized repair functions only. The scratchpad need + * not be initialized. + */ +int +xfs_parent_set( + struct xfs_inode *ip, + const struct xfs_parent_name_irec *pptr, + struct xfs_parent_scratch *scr) +{ + xfs_parent_irec_to_disk(&scr->rec, NULL, NULL, pptr); + + memset(&scr->args, 0, sizeof(struct xfs_da_args)); + scr->args.attr_filter = XFS_ATTR_PARENT; + scr->args.dp = ip; + scr->args.geo = ip->i_mount->m_attr_geo; + scr->args.name = (const unsigned char *)&scr->rec; + scr->args.namelen = sizeof(struct xfs_parent_name_rec); + scr->args.valuelen = pptr->p_namelen; + scr->args.value = (void *)pptr->p_name; + scr->args.whichfork = XFS_ATTR_FORK; + + return xfs_attr_set(&scr->args); +} diff --git a/libxfs/xfs_parent.h b/libxfs/xfs_parent.h index cd1b1351..effbccdf 100644 --- a/libxfs/xfs_parent.h +++ b/libxfs/xfs_parent.h @@ -113,4 +113,8 @@ int xfs_parent_lookup(struct xfs_trans *tp, struct xfs_inode *ip, const struct xfs_parent_name_irec *pptr, unsigned char *name, unsigned int namelen, struct xfs_parent_scratch *scratch); +int xfs_parent_set(struct xfs_inode *ip, + const struct xfs_parent_name_irec *pptr, + struct xfs_parent_scratch *scratch); + #endif /* __XFS_PARENT_H__ */