@@ -752,6 +752,79 @@ 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)
+
+ #define XFS_PPTR_FLAG_ALL (XFS_PPTR_IFLAG_HANDLE | XFS_PPTR_OFLAG_ROOT | \
+ XFS_PPTR_OFLAG_DONE)
+
+/* 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 */
+ __u64 xpp_rsvd; /* Reserved */
+ __u8 xpp_name[XFS_PPTR_MAXNAMELEN]; /* File name */
+};
+
+/* Iterate through an inodes parent pointers */
+struct xfs_pptr_info {
+ /* File handle, if XFS_PPTR_IFLAG_HANDLE is set */
+ struct xfs_handle pi_handle;
+
+ /*
+ * Structure to track progress in iterating the parent pointers.
+ * Must be initialized to zeroes before the first ioctl call, and
+ * not touched by callers after that.
+ */
+ struct xfs_attrlist_cursor pi_cursor;
+
+ /* Operational flags: XFS_PPTR_*FLAG* */
+ __u32 pi_flags;
+
+ /* Must be set to zero */
+ __u32 pi_reserved;
+
+ /* # of entries in array */
+ __u32 pi_ptrs_size;
+
+ /* # of entries filled in (output) */
+ __u32 pi_ptrs_used;
+
+ /* Must be set to zero */
+ __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.
+ */
+ struct xfs_parent_ptr pi_parents[];
+};
+
+static inline size_t
+xfs_pptr_info_sizeof(int nr_ptrs)
+{
+ return sizeof(struct xfs_pptr_info) +
+ (nr_ptrs * sizeof(struct xfs_parent_ptr));
+}
+
+static inline struct xfs_parent_ptr*
+xfs_ppinfo_to_pp(
+ struct xfs_pptr_info *info,
+ int idx)
+{
+ return &info->pi_parents[idx];
+}
+
/*
* ioctl limits
*/
@@ -797,6 +870,7 @@ struct xfs_scrub_metadata {
/* XFS_IOC_GETFSMAP ------ hoisted 59 */
#define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata)
#define XFS_IOC_AG_GEOMETRY _IOWR('X', 61, struct xfs_ag_geometry)
+#define XFS_IOC_GETPARENTS _IOWR('X', 62, struct xfs_parent_ptr)
/*
* ioctl commands that replace IRIX syssgi()'s
@@ -30,6 +30,16 @@
struct kmem_cache *xfs_parent_intent_cache;
+/* Initializes a xfs_parent_ptr from an xfs_parent_name_rec */
+void
+xfs_init_parent_ptr(struct xfs_parent_ptr *xpp,
+ const 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.
*
@@ -25,6 +25,8 @@ struct xfs_parent_defer {
void xfs_init_parent_name_rec(struct xfs_parent_name_rec *rec,
struct xfs_inode *ip,
uint32_t p_diroffset);
+void xfs_init_parent_ptr(struct xfs_parent_ptr *xpp,
+ const struct xfs_parent_name_rec *rec);
int __xfs_parent_init(struct xfs_mount *mp, bool grab_log,
struct xfs_parent_defer **parentp);
@@ -321,6 +321,61 @@ They are all subject to change and should not be called directly
by applications.
XFS_IOC_FSSETDM_BY_HANDLE is not supported as of Linux 5.5.
+.PP
+.TP
+.B XFS_IOC_GETPARENTS
+This command is used to get a files parent pointers. Parent pointers are
+file attributes used to store meta data information about an inodes parent.
+This command takes a xfs_pptr_info structure with trailing array of
+struct xfs_parent_ptr as an input to store an inodes parents. The
+xfs_pptr_info_sizeof() and xfs_ppinfo_to_pp() routines are provided to
+create and iterate through these structures. The number of pointers stored
+in the array is indicated by the xfs_pptr_info.used field, and the
+XFS_PPTR_OFLAG_DONE flag will be set in xfs_pptr_info.flags when there are
+no more parent pointers to be read. The below code is an example
+of XFS_IOC_GETPARENTS usage:
+
+.nf
+#include<stdio.h>
+#include<string.h>
+#include<errno.h>
+#include<xfs/linux.h>
+#include<xfs/xfs.h>
+#include<xfs/xfs_types.h>
+#include<xfs/xfs_fs.h>
+
+int main() {
+ struct xfs_pptr_info *pi;
+ struct xfs_parent_ptr *p;
+ int i, error, fd, nr_ptrs = 4;
+
+ unsigned char buffer[xfs_pptr_info_sizeof(nr_ptrs)];
+ memset(buffer, 0, sizeof(buffer));
+ pi = (struct xfs_pptr_info *)&buffer;
+ pi->pi_ptrs_size = nr_ptrs;
+
+ fd = open("/mnt/test/foo.txt", O_RDONLY | O_CREAT);
+ if (fd == -1)
+ return errno;
+
+ do {
+ error = ioctl(fd, XFS_IOC_GETPARENTS, pi);
+ if (error)
+ return error;
+
+ for (i = 0; i < pi->pi_ptrs_used; i++) {
+ p = xfs_ppinfo_to_pp(pi, i);
+ printf("inode = %llu\\n", (unsigned long long)p->xpp_ino);
+ printf("generation = %u\\n", (unsigned int)p->xpp_gen);
+ printf("diroffset = %u\\n", (unsigned int)p->xpp_diroffset);
+ printf("name = \\"%s\\"\\n\\n", (char *)p->xpp_name);
+ }
+ } while (!pi->pi_flags & XFS_PPTR_OFLAG_DONE);
+
+ return 0;
+}
+.fi
+
.SS Filesystem Operations
In order to effect one of the following operations, the pathname
and descriptor arguments passed to