This patch adds a new file ioctl to retrieve the parent pointer of a given inode Signed-off-by: Allison Henderson <allison.henderson@xxxxxxxxxx> --- libxfs/xfs_fs.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_parent.c | 10 ++++++++++ libxfs/xfs_parent.h | 2 ++ 3 files changed, 57 insertions(+) diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 407cd61..4c597be 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -568,6 +568,50 @@ struct xfs_scrub_metadata { XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED) #define XFS_SCRUB_FLAGS_ALL (XFS_SCRUB_FLAGS_IN | XFS_SCRUB_FLAGS_OUT) +#define XFS_PPTR_MAXNAMELEN 256 + +/* return parents of the handle, not the open fd */ +#define XFS_PPTR_IFLAG_HANDLE (1U << 0) + +/* target was the root directory */ +#define XFS_PPTR_OFLAG_ROOT (1U << 1) + +/* Cursor is done iterating pptrs */ +#define XFS_PPTR_OFLAG_DONE (1U << 2) + +/* Get an inode parent pointer through ioctl */ +struct xfs_parent_ptr { + __u64 xpp_ino; /* Inode */ + __u32 xpp_gen; /* Inode generation */ + __u32 xpp_diroffset; /* Directory offset */ + __u32 xpp_namelen; /* File name length */ + __u32 xpp_pad; + __u8 xpp_name[XFS_PPTR_MAXNAMELEN]; /* File name */ +}; + +/* Iterate through an inodes parent pointers */ +struct xfs_pptr_info { + struct xfs_handle pi_handle; + struct xfs_attrlist_cursor pi_cursor; + __u32 pi_flags; + __u32 pi_reserved; + __u32 pi_ptrs_size; + __u32 pi_ptrs_used; + __u64 pi_reserved2[6]; + + /* + * An array of struct xfs_parent_ptr follows the header + * information. Use XFS_PPINFO_TO_PP() to access the + * parent pointer array entries. + */ +}; + +#define XFS_PPTR_INFO_SIZEOF(nr_ptrs) sizeof (struct xfs_pptr_info) + \ + nr_ptrs * sizeof(struct xfs_parent_ptr) + +#define XFS_PPINFO_TO_PP(info, idx) \ + (&(((struct xfs_parent_ptr *)((char *)(info) + sizeof(*(info))))[(idx)])) + /* * ioctl limits */ @@ -611,6 +655,7 @@ struct xfs_scrub_metadata { #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) /* XFS_IOC_GETFSMAP ------ hoisted 59 */ #define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata) +#define XFS_IOC_GETPPOINTER _IOR ('X', 61, struct xfs_parent_ptr) /* * ioctl commands that replace IRIX syssgi()'s diff --git a/libxfs/xfs_parent.c b/libxfs/xfs_parent.c index f83815f..d506c22 100644 --- a/libxfs/xfs_parent.c +++ b/libxfs/xfs_parent.c @@ -43,6 +43,16 @@ #include "kmem.h" #include "xfs_bmap.h" +/* Initializes a xfs_parent_ptr from an xfs_parent_name_rec */ +void +xfs_init_parent_ptr(struct xfs_parent_ptr *xpp, + struct xfs_parent_name_rec *rec) +{ + xpp->xpp_ino = be64_to_cpu(rec->p_ino); + xpp->xpp_gen = be32_to_cpu(rec->p_gen); + xpp->xpp_diroffset = be32_to_cpu(rec->p_diroffset); +} + /* * Parent pointer attribute handling. * diff --git a/libxfs/xfs_parent.h b/libxfs/xfs_parent.h index 60f1172..3fcbbbb 100644 --- a/libxfs/xfs_parent.h +++ b/libxfs/xfs_parent.h @@ -32,4 +32,6 @@ void xfs_init_parent_name_irec(struct xfs_parent_name_irec *irec, int xfs_parent_add(struct xfs_inode *parent, struct xfs_inode *child, struct xfs_name *child_name, uint32_t diroffset); +void xfs_init_parent_ptr(struct xfs_parent_ptr *xpp, + struct xfs_parent_name_rec *rec); #endif /* __XFS_PARENT_H__ */ -- 2.7.4