From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>,
allison.henderson@oracle.com, hch@infradead.org,
linux-xfs@vger.kernel.org, catherine.hoang@oracle.com
Subject: Re: [PATCH v13.2.1 26/31] xfs: add parent pointer ioctls
Date: Wed, 17 Apr 2024 15:25:03 -0700 [thread overview]
Message-ID: <20240417222503.GC11948@frogsfrogsfrogs> (raw)
In-Reply-To: <20240417024955.GL11948@frogsfrogsfrogs>
On Tue, Apr 16, 2024 at 07:49:55PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> This patch adds a pair of new file ioctls to retrieve the parent pointer
> of a given inode. They both return the same results, but one operates
> on the file descriptor passed to ioctl() whereas the other allows the
> caller to specify a file handle for which the caller wants results.
>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> ---
> v13.2.1: dont check fsid like the other handle code, hoist iget to helper
> ---
> fs/xfs/libxfs/xfs_fs.h | 73 +++++++++++
> fs/xfs/libxfs/xfs_ondisk.h | 5 +
> fs/xfs/libxfs/xfs_parent.c | 34 +++++
> fs/xfs/libxfs/xfs_parent.h | 5 +
> fs/xfs/xfs_export.c | 2
> fs/xfs/xfs_export.h | 2
> fs/xfs/xfs_handle.c | 298 ++++++++++++++++++++++++++++++++++++++++++++
> fs/xfs/xfs_handle.h | 5 +
> fs/xfs/xfs_ioctl.c | 6 +
> fs/xfs/xfs_trace.c | 1
> fs/xfs/xfs_trace.h | 92 ++++++++++++++
> 11 files changed, 521 insertions(+), 2 deletions(-)
>
<snip>
> diff --git a/fs/xfs/libxfs/xfs_ondisk.h b/fs/xfs/libxfs/xfs_ondisk.h
> index 25952ef584eee..e8cdd77d03fa8 100644
> --- a/fs/xfs/libxfs/xfs_ondisk.h
> +++ b/fs/xfs/libxfs/xfs_ondisk.h
> @@ -156,6 +156,11 @@ xfs_check_ondisk_structs(void)
> XFS_CHECK_OFFSET(struct xfs_efi_log_format_32, efi_extents, 16);
> XFS_CHECK_OFFSET(struct xfs_efi_log_format_64, efi_extents, 16);
>
> + /* parent pointer ioctls */
> + XFS_CHECK_STRUCT_SIZE(struct xfs_getparents_rec, 32);
It turns out that the i386 (or probably just 32-bit) build robots trip
over this statement, probably because of the implied padding after the
gpr_name[] flexarray. I'll change this to:
XFS_CHECK_OFFSET(struct xfs_getparents_rec, gpr_name, 26);
and let's see what they say. armhf checks out locally.
--D
> + XFS_CHECK_STRUCT_SIZE(struct xfs_getparents, 40);
> + XFS_CHECK_STRUCT_SIZE(struct xfs_getparents_by_handle, 64);
> +
> /*
> * The v5 superblock format extended several v4 header structures with
> * additional data. While new fields are only accessible on v5
> diff --git a/fs/xfs/libxfs/xfs_parent.c b/fs/xfs/libxfs/xfs_parent.c
> index fdf643bfde4df..504de1ef33876 100644
> --- a/fs/xfs/libxfs/xfs_parent.c
> +++ b/fs/xfs/libxfs/xfs_parent.c
> @@ -257,3 +257,37 @@ xfs_parent_replacename(
> xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REPLACE);
> return 0;
> }
> +
> +/*
> + * Extract parent pointer information from any parent pointer xattr into
> + * @parent_ino/gen. The last two parameters can be NULL pointers.
> + *
> + * Returns 0 if this is not a parent pointer xattr at all; or -EFSCORRUPTED for
> + * garbage.
> + */
> +int
> +xfs_parent_from_attr(
> + struct xfs_mount *mp,
> + unsigned int attr_flags,
> + const unsigned char *name,
> + unsigned int namelen,
> + const void *value,
> + unsigned int valuelen,
> + xfs_ino_t *parent_ino,
> + uint32_t *parent_gen)
> +{
> + const struct xfs_parent_rec *rec = value;
> +
> + ASSERT(attr_flags & XFS_ATTR_PARENT);
> +
> + if (!xfs_parent_namecheck(attr_flags, name, namelen))
> + return -EFSCORRUPTED;
> + if (!xfs_parent_valuecheck(mp, value, valuelen))
> + return -EFSCORRUPTED;
> +
> + if (parent_ino)
> + *parent_ino = be64_to_cpu(rec->p_ino);
> + if (parent_gen)
> + *parent_gen = be32_to_cpu(rec->p_gen);
> + return 0;
> +}
> diff --git a/fs/xfs/libxfs/xfs_parent.h b/fs/xfs/libxfs/xfs_parent.h
> index 768633b313671..d7ab09e738ad4 100644
> --- a/fs/xfs/libxfs/xfs_parent.h
> +++ b/fs/xfs/libxfs/xfs_parent.h
> @@ -91,4 +91,9 @@ int xfs_parent_replacename(struct xfs_trans *tp,
> struct xfs_inode *new_dp, const struct xfs_name *new_name,
> struct xfs_inode *child);
>
> +int xfs_parent_from_attr(struct xfs_mount *mp, unsigned int attr_flags,
> + const unsigned char *name, unsigned int namelen,
> + const void *value, unsigned int valuelen,
> + xfs_ino_t *parent_ino, uint32_t *parent_gen);
> +
> #endif /* __XFS_PARENT_H__ */
> diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
> index 4b03221351c0f..201489d3de089 100644
> --- a/fs/xfs/xfs_export.c
> +++ b/fs/xfs/xfs_export.c
> @@ -102,7 +102,7 @@ xfs_fs_encode_fh(
> return fileid_type;
> }
>
> -STATIC struct inode *
> +struct inode *
> xfs_nfs_get_inode(
> struct super_block *sb,
> u64 ino,
> diff --git a/fs/xfs/xfs_export.h b/fs/xfs/xfs_export.h
> index 64471a3ddb04d..3cd85e8901a5f 100644
> --- a/fs/xfs/xfs_export.h
> +++ b/fs/xfs/xfs_export.h
> @@ -57,4 +57,6 @@ struct xfs_fid64 {
> /* This flag goes on the wire. Don't play with it. */
> #define XFS_FILEID_TYPE_64FLAG 0x80 /* NFS fileid has 64bit inodes */
>
> +struct inode *xfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 gen);
> +
> #endif /* __XFS_EXPORT_H__ */
> diff --git a/fs/xfs/xfs_handle.c b/fs/xfs/xfs_handle.c
> index b9f4d9860682a..c8785ed595434 100644
> --- a/fs/xfs/xfs_handle.c
> +++ b/fs/xfs/xfs_handle.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> * Copyright (c) 2000-2005 Silicon Graphics, Inc.
> + * Copyright (c) 2022-2024 Oracle.
> * All rights reserved.
> */
> #include "xfs.h"
> @@ -178,6 +179,30 @@ xfs_khandle_to_dentry(
> xfs_handle_acceptable, NULL);
> }
>
> +/* Convert handle already copied to kernel space into an xfs_inode. */
> +static struct xfs_inode *
> +xfs_khandle_to_inode(
> + struct file *file,
> + struct xfs_handle *handle)
> +{
> + struct xfs_inode *ip = XFS_I(file_inode(file));
> + struct xfs_mount *mp = ip->i_mount;
> + struct inode *inode;
> +
> + if (!S_ISDIR(VFS_I(ip)->i_mode))
> + return ERR_PTR(-ENOTDIR);
> +
> + if (handle->ha_fid.fid_len != xfs_filehandle_fid_len())
> + return ERR_PTR(-EINVAL);
> +
> + inode = xfs_nfs_get_inode(mp->m_super, handle->ha_fid.fid_ino,
> + handle->ha_fid.fid_gen);
> + if (IS_ERR(inode))
> + return ERR_CAST(inode);
> +
> + return XFS_I(inode);
> +}
> +
> /*
> * Convert userspace handle data into a dentry.
> */
> @@ -652,3 +677,276 @@ xfs_attrmulti_by_handle(
> dput(dentry);
> return error;
> }
> +
> +struct xfs_getparents_ctx {
> + struct xfs_attr_list_context context;
> + struct xfs_getparents_by_handle gph;
> +
> + /* File to target */
> + struct xfs_inode *ip;
> +
> + /* Internal buffer where we format records */
> + void *krecords;
> +
> + /* Last record filled out */
> + struct xfs_getparents_rec *lastrec;
> +
> + unsigned int count;
> +};
> +
> +static inline unsigned int
> +xfs_getparents_rec_sizeof(
> + unsigned int namelen)
> +{
> + return round_up(sizeof(struct xfs_getparents_rec) + namelen + 1,
> + sizeof(uint64_t));
> +}
> +
> +static void
> +xfs_getparents_put_listent(
> + struct xfs_attr_list_context *context,
> + int flags,
> + unsigned char *name,
> + int namelen,
> + void *value,
> + int valuelen)
> +{
> + struct xfs_getparents_ctx *gpx =
> + container_of(context, struct xfs_getparents_ctx, context);
> + struct xfs_inode *ip = context->dp;
> + struct xfs_mount *mp = ip->i_mount;
> + struct xfs_getparents *gp = &gpx->gph.gph_request;
> + struct xfs_getparents_rec *gpr = gpx->krecords + context->firstu;
> + unsigned short reclen =
> + xfs_getparents_rec_sizeof(namelen);
> + xfs_ino_t ino;
> + uint32_t gen;
> + int error;
> +
> + if (!(flags & XFS_ATTR_PARENT))
> + return;
> +
> + error = xfs_parent_from_attr(mp, flags, name, namelen, value, valuelen,
> + &ino, &gen);
> + if (error) {
> + xfs_inode_mark_sick(ip, XFS_SICK_INO_PARENT);
> + context->seen_enough = -EFSCORRUPTED;
> + return;
> + }
> +
> + /*
> + * We found a parent pointer, but we've filled up the buffer. Signal
> + * to the caller that we did /not/ reach the end of the parent pointer
> + * recordset.
> + */
> + if (context->firstu > context->bufsize - reclen) {
> + context->seen_enough = 1;
> + return;
> + }
> +
> + /* Format the parent pointer directly into the caller buffer. */
> + gpr->gpr_reclen = reclen;
> + xfs_filehandle_init(mp, ino, gen, &gpr->gpr_parent);
> + memcpy(gpr->gpr_name, name, namelen);
> + gpr->gpr_name[namelen] = 0;
> +
> + trace_xfs_getparents_put_listent(ip, gp, context, gpr);
> +
> + context->firstu += reclen;
> + gpx->count++;
> + gpx->lastrec = gpr;
> +}
> +
> +/* Expand the last record to fill the rest of the caller's buffer. */
> +static inline void
> +xfs_getparents_expand_lastrec(
> + struct xfs_getparents_ctx *gpx)
> +{
> + struct xfs_getparents *gp = &gpx->gph.gph_request;
> + struct xfs_getparents_rec *gpr = gpx->lastrec;
> +
> + if (!gpx->lastrec)
> + gpr = gpx->krecords;
> +
> + gpr->gpr_reclen = gp->gp_bufsize - ((void *)gpr - gpx->krecords);
> +
> + trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr);
> +}
> +
> +static inline void __user *u64_to_uptr(u64 val)
> +{
> + return (void __user *)(uintptr_t)val;
> +}
> +
> +/* Retrieve the parent pointers for a given inode. */
> +STATIC int
> +xfs_getparents(
> + struct xfs_getparents_ctx *gpx)
> +{
> + struct xfs_getparents *gp = &gpx->gph.gph_request;
> + struct xfs_inode *ip = gpx->ip;
> + struct xfs_mount *mp = ip->i_mount;
> + size_t bufsize;
> + int error;
> +
> + /* Check size of buffer requested by user */
> + if (gp->gp_bufsize > XFS_XATTR_LIST_MAX)
> + return -ENOMEM;
> + if (gp->gp_bufsize < xfs_getparents_rec_sizeof(1))
> + return -EINVAL;
> +
> + if (gp->gp_iflags & ~XFS_GETPARENTS_IFLAGS_ALL)
> + return -EINVAL;
> + if (gp->gp_reserved)
> + return -EINVAL;
> +
> + bufsize = round_down(gp->gp_bufsize, sizeof(uint64_t));
> + gpx->krecords = kvzalloc(bufsize, GFP_KERNEL);
> + if (!gpx->krecords) {
> + bufsize = min(bufsize, PAGE_SIZE);
> + gpx->krecords = kvzalloc(bufsize, GFP_KERNEL);
> + if (!gpx->krecords)
> + return -ENOMEM;
> + }
> +
> + gpx->context.dp = ip;
> + gpx->context.resynch = 1;
> + gpx->context.put_listent = xfs_getparents_put_listent;
> + gpx->context.bufsize = bufsize;
> + /* firstu is used to track the bytes filled in the buffer */
> + gpx->context.firstu = 0;
> +
> + /* Copy the cursor provided by caller */
> + memcpy(&gpx->context.cursor, &gp->gp_cursor,
> + sizeof(struct xfs_attrlist_cursor));
> + gpx->count = 0;
> + gp->gp_oflags = 0;
> +
> + trace_xfs_getparents_begin(ip, gp, &gpx->context.cursor);
> +
> + error = xfs_attr_list(&gpx->context);
> + if (error)
> + goto out_free_buf;
> + if (gpx->context.seen_enough < 0) {
> + error = gpx->context.seen_enough;
> + goto out_free_buf;
> + }
> + xfs_getparents_expand_lastrec(gpx);
> +
> + /* Update the caller with the current cursor position */
> + memcpy(&gp->gp_cursor, &gpx->context.cursor,
> + sizeof(struct xfs_attrlist_cursor));
> +
> + /* Is this the root directory? */
> + if (ip->i_ino == mp->m_sb.sb_rootino)
> + gp->gp_oflags |= XFS_GETPARENTS_OFLAG_ROOT;
> +
> + if (gpx->context.seen_enough == 0) {
> + /*
> + * If we did not run out of buffer space, then we reached the
> + * end of the pptr recordset, so set the DONE flag.
> + */
> + gp->gp_oflags |= XFS_GETPARENTS_OFLAG_DONE;
> + } else if (gpx->count == 0) {
> + /*
> + * If we ran out of buffer space before copying any parent
> + * pointers at all, the caller's buffer was too short. Tell
> + * userspace that, erm, the message is too long.
> + */
> + error = -EMSGSIZE;
> + goto out_free_buf;
> + }
> +
> + trace_xfs_getparents_end(ip, gp, &gpx->context.cursor);
> +
> + ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize);
> +
> + /* Copy the records to userspace. */
> + if (copy_to_user(u64_to_uptr(gpx->gph.gph_request.gp_buffer),
> + gpx->krecords, gpx->context.firstu))
> + error = -EFAULT;
> +
> +out_free_buf:
> + kvfree(gpx->krecords);
> + gpx->krecords = NULL;
> + return error;
> +}
> +
> +/* Retrieve the parents of this file and pass them back to userspace. */
> +int
> +xfs_ioc_getparents(
> + struct file *file,
> + struct xfs_getparents __user *ureq)
> +{
> + struct xfs_getparents_ctx gpx = {
> + .ip = XFS_I(file_inode(file)),
> + };
> + struct xfs_getparents *kreq = &gpx.gph.gph_request;
> + struct xfs_mount *mp = gpx.ip->i_mount;
> + int error;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> + if (!xfs_has_parent(mp))
> + return -EOPNOTSUPP;
> + if (copy_from_user(kreq, ureq, sizeof(*kreq)))
> + return -EFAULT;
> +
> + error = xfs_getparents(&gpx);
> + if (error)
> + return error;
> +
> + if (copy_to_user(ureq, kreq, sizeof(*kreq)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +/* Retrieve the parents of this file handle and pass them back to userspace. */
> +int
> +xfs_ioc_getparents_by_handle(
> + struct file *file,
> + struct xfs_getparents_by_handle __user *ureq)
> +{
> + struct xfs_getparents_ctx gpx = { };
> + struct xfs_inode *ip = XFS_I(file_inode(file));
> + struct xfs_mount *mp = ip->i_mount;
> + struct xfs_getparents_by_handle *kreq = &gpx.gph;
> + struct xfs_handle *handle = &kreq->gph_handle;
> + int error;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> + if (!xfs_has_parent(mp))
> + return -EOPNOTSUPP;
> + if (copy_from_user(kreq, ureq, sizeof(*kreq)))
> + return -EFAULT;
> +
> + /*
> + * We don't use exportfs_decode_fh because it does too much work here.
> + * If the handle refers to a directory, the exportfs code will walk
> + * upwards through the directory tree to connect the dentries to the
> + * root directory dentry. For GETPARENTS we don't care about that
> + * because we're not actually going to open a file descriptor; we only
> + * want to open an inode and read its parent pointers.
> + *
> + * Note that xfs_scrub uses GETPARENTS to log that it will try to fix a
> + * corrupted file's metadata. For this usecase we would really rather
> + * userspace single-step the path reconstruction to avoid loops or
> + * other strange things if the directory tree is corrupt.
> + */
> + gpx.ip = xfs_khandle_to_inode(file, handle);
> + if (IS_ERR(gpx.ip))
> + return PTR_ERR(gpx.ip);
> +
> + error = xfs_getparents(&gpx);
> + if (error)
> + goto out_rele;
> +
> + if (copy_to_user(ureq, kreq, sizeof(*kreq)))
> + error = -EFAULT;
> +
> +out_rele:
> + xfs_irele(gpx.ip);
> + return error;
> +}
> diff --git a/fs/xfs/xfs_handle.h b/fs/xfs/xfs_handle.h
> index e39eaf4689da9..6799a86d8565c 100644
> --- a/fs/xfs/xfs_handle.h
> +++ b/fs/xfs/xfs_handle.h
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0
> /*
> * Copyright (c) 2000-2005 Silicon Graphics, Inc.
> + * Copyright (c) 2022-2024 Oracle.
> * All rights reserved.
> */
> #ifndef __XFS_HANDLE_H__
> @@ -25,4 +26,8 @@ int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf,
> struct dentry *xfs_handle_to_dentry(struct file *parfilp, void __user *uhandle,
> u32 hlen);
>
> +int xfs_ioc_getparents(struct file *file, struct xfs_getparents __user *arg);
> +int xfs_ioc_getparents_by_handle(struct file *file,
> + struct xfs_getparents_by_handle __user *arg);
> +
> #endif /* __XFS_HANDLE_H__ */
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 062869a38aa83..6055053a8f6b2 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -35,6 +35,7 @@
> #include "xfs_health.h"
> #include "xfs_reflink.h"
> #include "xfs_ioctl.h"
> +#include "xfs_xattr.h"
> #include "xfs_rtbitmap.h"
> #include "xfs_file.h"
> #include "xfs_exchrange.h"
> @@ -1424,7 +1425,10 @@ xfs_file_ioctl(
>
> case XFS_IOC_FSGETXATTRA:
> return xfs_ioc_fsgetxattra(ip, arg);
> -
> + case XFS_IOC_GETPARENTS:
> + return xfs_ioc_getparents(filp, arg);
> + case XFS_IOC_GETPARENTS_BY_HANDLE:
> + return xfs_ioc_getparents_by_handle(filp, arg);
> case XFS_IOC_GETBMAP:
> case XFS_IOC_GETBMAPA:
> case XFS_IOC_GETBMAPX:
> diff --git a/fs/xfs/xfs_trace.c b/fs/xfs/xfs_trace.c
> index cf92a3bd56c79..9c7fbaae2717d 100644
> --- a/fs/xfs/xfs_trace.c
> +++ b/fs/xfs/xfs_trace.c
> @@ -41,6 +41,7 @@
> #include "xfs_bmap.h"
> #include "xfs_exchmaps.h"
> #include "xfs_exchrange.h"
> +#include "xfs_parent.h"
>
> /*
> * We include this last to have the helpers above available for the trace
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index fdded7c248143..11a56b6f27662 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -87,6 +87,9 @@ struct xfs_bmap_intent;
> struct xfs_exchmaps_intent;
> struct xfs_exchmaps_req;
> struct xfs_exchrange;
> +struct xfs_getparents;
> +struct xfs_parent_irec;
> +struct xfs_attrlist_cursor_kern;
>
> #define XFS_ATTR_FILTER_FLAGS \
> { XFS_ATTR_ROOT, "ROOT" }, \
> @@ -5153,6 +5156,95 @@ TRACE_EVENT(xfs_exchmaps_delta_nextents,
> __entry->d_nexts1, __entry->d_nexts2)
> );
>
> +DECLARE_EVENT_CLASS(xfs_getparents_rec_class,
> + TP_PROTO(struct xfs_inode *ip, const struct xfs_getparents *ppi,
> + const struct xfs_attr_list_context *context,
> + const struct xfs_getparents_rec *pptr),
> + TP_ARGS(ip, ppi, context, pptr),
> + TP_STRUCT__entry(
> + __field(dev_t, dev)
> + __field(xfs_ino_t, ino)
> + __field(unsigned int, firstu)
> + __field(unsigned short, reclen)
> + __field(unsigned int, bufsize)
> + __field(xfs_ino_t, parent_ino)
> + __field(unsigned int, parent_gen)
> + __string(name, pptr->gpr_name)
> + ),
> + TP_fast_assign(
> + __entry->dev = ip->i_mount->m_super->s_dev;
> + __entry->ino = ip->i_ino;
> + __entry->firstu = context->firstu;
> + __entry->reclen = pptr->gpr_reclen;
> + __entry->bufsize = ppi->gp_bufsize;
> + __entry->parent_ino = pptr->gpr_parent.ha_fid.fid_ino;
> + __entry->parent_gen = pptr->gpr_parent.ha_fid.fid_gen;
> + __assign_str(name, pptr->gpr_name);
> + ),
> + TP_printk("dev %d:%d ino 0x%llx firstu %u reclen %u bufsize %u parent_ino 0x%llx parent_gen 0x%x name '%s'",
> + MAJOR(__entry->dev), MINOR(__entry->dev),
> + __entry->ino,
> + __entry->firstu,
> + __entry->reclen,
> + __entry->bufsize,
> + __entry->parent_ino,
> + __entry->parent_gen,
> + __get_str(name))
> +)
> +#define DEFINE_XFS_GETPARENTS_REC_EVENT(name) \
> +DEFINE_EVENT(xfs_getparents_rec_class, name, \
> + TP_PROTO(struct xfs_inode *ip, const struct xfs_getparents *ppi, \
> + const struct xfs_attr_list_context *context, \
> + const struct xfs_getparents_rec *pptr), \
> + TP_ARGS(ip, ppi, context, pptr))
> +DEFINE_XFS_GETPARENTS_REC_EVENT(xfs_getparents_put_listent);
> +DEFINE_XFS_GETPARENTS_REC_EVENT(xfs_getparents_expand_lastrec);
> +
> +DECLARE_EVENT_CLASS(xfs_getparents_class,
> + TP_PROTO(struct xfs_inode *ip, const struct xfs_getparents *ppi,
> + const struct xfs_attrlist_cursor_kern *cur),
> + TP_ARGS(ip, ppi, cur),
> + TP_STRUCT__entry(
> + __field(dev_t, dev)
> + __field(xfs_ino_t, ino)
> + __field(unsigned short, iflags)
> + __field(unsigned short, oflags)
> + __field(unsigned int, bufsize)
> + __field(unsigned int, hashval)
> + __field(unsigned int, blkno)
> + __field(unsigned int, offset)
> + __field(int, initted)
> + ),
> + TP_fast_assign(
> + __entry->dev = ip->i_mount->m_super->s_dev;
> + __entry->ino = ip->i_ino;
> + __entry->iflags = ppi->gp_iflags;
> + __entry->oflags = ppi->gp_oflags;
> + __entry->bufsize = ppi->gp_bufsize;
> + __entry->hashval = cur->hashval;
> + __entry->blkno = cur->blkno;
> + __entry->offset = cur->offset;
> + __entry->initted = cur->initted;
> + ),
> + TP_printk("dev %d:%d ino 0x%llx iflags 0x%x oflags 0x%x bufsize %u cur_init? %d hashval 0x%x blkno %u offset %u",
> + MAJOR(__entry->dev), MINOR(__entry->dev),
> + __entry->ino,
> + __entry->iflags,
> + __entry->oflags,
> + __entry->bufsize,
> + __entry->initted,
> + __entry->hashval,
> + __entry->blkno,
> + __entry->offset)
> +)
> +#define DEFINE_XFS_GETPARENTS_EVENT(name) \
> +DEFINE_EVENT(xfs_getparents_class, name, \
> + TP_PROTO(struct xfs_inode *ip, const struct xfs_getparents *ppi, \
> + const struct xfs_attrlist_cursor_kern *cur), \
> + TP_ARGS(ip, ppi, cur))
> +DEFINE_XFS_GETPARENTS_EVENT(xfs_getparents_begin);
> +DEFINE_XFS_GETPARENTS_EVENT(xfs_getparents_end);
> +
> #endif /* _TRACE_XFS_H */
>
> #undef TRACE_INCLUDE_PATH
>
next prev parent reply other threads:[~2024-04-17 22:25 UTC|newest]
Thread overview: 134+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-16 1:16 [PATCHBOMB v13.2] xfs: directory parent pointers Darrick J. Wong
2024-04-16 1:19 ` [PATCHSET v13.2 1/7] xfs: shrink struct xfs_da_args Darrick J. Wong
2024-04-16 1:21 ` [PATCH 1/5] xfs: remove XFS_DA_OP_REMOVE Darrick J. Wong
2024-04-16 1:21 ` [PATCH 2/5] xfs: remove XFS_DA_OP_NOTIME Darrick J. Wong
2024-04-16 1:21 ` [PATCH 3/5] xfs: remove xfs_da_args.attr_flags Darrick J. Wong
2024-04-16 5:07 ` Christoph Hellwig
2024-04-16 1:22 ` [PATCH 4/5] xfs: make attr removal an explicit operation Darrick J. Wong
2024-04-16 5:12 ` Christoph Hellwig
2024-04-16 17:31 ` Darrick J. Wong
2024-04-16 1:22 ` [PATCH 5/5] xfs: rearrange xfs_da_args a bit to use less space Darrick J. Wong
2024-04-16 5:13 ` Christoph Hellwig
2024-04-16 1:19 ` [PATCHSET v13.2 2/7] xfs: improve extended attribute validation Darrick J. Wong
2024-04-16 1:22 ` [PATCH 01/14] xfs: attr fork iext must be loaded before calling xfs_attr_is_leaf Darrick J. Wong
2024-04-16 1:22 ` [PATCH 02/14] xfs: require XFS_SB_FEAT_INCOMPAT_LOG_XATTRS for attr log intent item recovery Darrick J. Wong
2024-04-16 1:23 ` [PATCH 03/14] xfs: use an XFS_OPSTATE_ flag for detecting if logged xattrs are available Darrick J. Wong
2024-04-16 1:23 ` [PATCH 04/14] xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2 Darrick J. Wong
2024-04-16 1:23 ` [PATCH 05/14] xfs: fix missing check for invalid attr flags Darrick J. Wong
2024-04-16 1:23 ` [PATCH 06/14] xfs: check shortform attr entry flags specifically Darrick J. Wong
2024-04-16 5:13 ` Christoph Hellwig
2024-04-16 1:24 ` [PATCH 07/14] xfs: restructure xfs_attr_complete_op a bit Darrick J. Wong
2024-04-16 1:24 ` [PATCH 08/14] xfs: use helpers to extract xattr op from opflags Darrick J. Wong
2024-04-16 1:24 ` [PATCH 09/14] xfs: validate recovered name buffers when recovering xattr items Darrick J. Wong
2024-04-16 1:24 ` [PATCH 10/14] xfs: always set args->value in xfs_attri_item_recover Darrick J. Wong
2024-04-16 1:25 ` [PATCH 11/14] xfs: use local variables for name and value length in _attri_commit_pass2 Darrick J. Wong
2024-04-16 1:25 ` [PATCH 12/14] xfs: refactor name/length checks in xfs_attri_validate Darrick J. Wong
2024-04-16 1:25 ` [PATCH 13/14] xfs: refactor name/value iovec validation in xlog_recover_attri_commit_pass2 Darrick J. Wong
2024-04-16 5:15 ` Christoph Hellwig
2024-04-16 1:26 ` [PATCH 14/14] xfs: enforce one namespace per attribute Darrick J. Wong
2024-04-16 1:20 ` [PATCHSET v13.2 3/7] xfs: Parent Pointers Darrick J. Wong
2024-04-16 1:26 ` [PATCH 01/31] xfs: rearrange xfs_attr_match parameters Darrick J. Wong
2024-04-16 1:26 ` [PATCH 02/31] xfs: check the flags earlier in xfs_attr_match Darrick J. Wong
2024-04-16 1:26 ` [PATCH 03/31] xfs: move xfs_attr_defer_add to xfs_attr_item.c Darrick J. Wong
2024-04-16 1:27 ` [PATCH 04/31] xfs: create a separate hashname function for extended attributes Darrick J. Wong
2024-04-16 1:27 ` [PATCH 05/31] xfs: add parent pointer support to attribute code Darrick J. Wong
2024-04-16 1:27 ` [PATCH 06/31] xfs: define parent pointer ondisk extended attribute format Darrick J. Wong
2024-04-16 1:27 ` [PATCH 07/31] xfs: allow xattr matching on name and value for parent pointers Darrick J. Wong
2024-04-16 1:28 ` [PATCH 08/31] xfs: refactor xfs_is_using_logged_xattrs checks in attr item recovery Darrick J. Wong
2024-04-16 5:15 ` Christoph Hellwig
2024-04-16 1:28 ` [PATCH 09/31] xfs: create attr log item opcodes and formats for parent pointers Darrick J. Wong
2024-04-16 5:16 ` Christoph Hellwig
2024-04-17 2:52 ` [PATCH v13.2.1 " Darrick J. Wong
2024-04-16 1:28 ` [PATCH 10/31] xfs: record inode generation in xattr update log intent items Darrick J. Wong
2024-04-16 5:17 ` Christoph Hellwig
2024-04-16 1:28 ` [PATCH 11/31] xfs: Expose init_xattrs in xfs_create_tmpfile Darrick J. Wong
2024-04-16 1:29 ` [PATCH 12/31] xfs: add parent pointer validator functions Darrick J. Wong
2024-04-16 1:29 ` [PATCH 13/31] xfs: extend transaction reservations for parent attributes Darrick J. Wong
2024-04-16 1:29 ` [PATCH 14/31] xfs: create a hashname function for parent pointers Darrick J. Wong
2024-04-16 1:29 ` [PATCH 15/31] xfs: parent pointer attribute creation Darrick J. Wong
2024-04-16 1:30 ` [PATCH 16/31] xfs: add parent attributes to link Darrick J. Wong
2024-04-16 1:30 ` [PATCH 17/31] xfs: add parent attributes to symlink Darrick J. Wong
2024-04-16 1:30 ` [PATCH 18/31] xfs: remove parent pointers in unlink Darrick J. Wong
2024-04-16 1:30 ` [PATCH 19/31] xfs: Add parent pointers to rename Darrick J. Wong
2024-04-16 1:31 ` [PATCH 20/31] xfs: Add parent pointers to xfs_cross_rename Darrick J. Wong
2024-04-16 1:31 ` [PATCH 21/31] xfs: don't return XFS_ATTR_PARENT attributes via listxattr Darrick J. Wong
2024-04-16 5:17 ` Christoph Hellwig
2024-04-16 1:31 ` [PATCH 22/31] xfs: pass the attr value to put_listent when possible Darrick J. Wong
2024-04-16 1:32 ` [PATCH 23/31] xfs: move handle ioctl code to xfs_handle.c Darrick J. Wong
2024-04-16 1:32 ` [PATCH 24/31] xfs: split out handle management helpers a bit Darrick J. Wong
2024-04-16 1:32 ` [PATCH 25/31] xfs: actually check the fsid of a handle Darrick J. Wong
2024-04-16 5:19 ` Christoph Hellwig
2024-04-16 17:44 ` Darrick J. Wong
2024-04-16 1:32 ` [PATCH 26/31] xfs: add parent pointer ioctls Darrick J. Wong
2024-04-16 5:21 ` Christoph Hellwig
2024-04-16 17:59 ` Darrick J. Wong
2024-04-16 18:08 ` Christoph Hellwig
2024-04-16 18:12 ` Darrick J. Wong
2024-04-16 18:50 ` Christoph Hellwig
2024-04-17 2:49 ` [PATCH v13.2.1 " Darrick J. Wong
2024-04-17 22:25 ` Darrick J. Wong [this message]
2024-04-18 4:21 ` Christoph Hellwig
2024-04-18 16:49 ` Darrick J. Wong
2024-04-16 1:33 ` [PATCH 27/31] xfs: don't remove the attr fork when parent pointers are enabled Darrick J. Wong
2024-04-16 1:33 ` [PATCH 28/31] xfs: add a incompat feature bit for parent pointers Darrick J. Wong
2024-04-16 1:33 ` [PATCH 29/31] xfs: fix unit conversion error in xfs_log_calc_max_attrsetm_res Darrick J. Wong
2024-04-16 1:33 ` [PATCH 30/31] xfs: drop compatibility minimum log size computations for reflink Darrick J. Wong
2024-04-16 1:34 ` [PATCH 31/31] xfs: enable parent pointers Darrick J. Wong
2024-04-16 1:20 ` [PATCHSET v13.2 4/7] xfs: scrubbing for " Darrick J. Wong
2024-04-16 1:34 ` [PATCH 1/7] xfs: revert commit 44af6c7e59b12 Darrick J. Wong
2024-04-16 5:23 ` Christoph Hellwig
2024-04-16 1:34 ` [PATCH 2/7] xfs: check dirents have parent pointers Darrick J. Wong
2024-04-16 1:34 ` [PATCH 3/7] xfs: deferred scrub of dirents Darrick J. Wong
2024-04-16 1:35 ` [PATCH 4/7] xfs: scrub parent pointers Darrick J. Wong
2024-04-16 1:35 ` [PATCH 5/7] xfs: deferred scrub of " Darrick J. Wong
2024-04-16 1:35 ` [PATCH 6/7] xfs: walk directory parent pointers to determine backref count Darrick J. Wong
2024-04-16 1:35 ` [PATCH 7/7] xfs: check parent pointer xattrs when scrubbing Darrick J. Wong
2024-04-16 1:20 ` [PATCHSET v13.2 5/7] xfs: online repair for parent pointers Darrick J. Wong
2024-04-16 1:36 ` [PATCH 01/17] xfs: remove some boilerplate from xfs_attr_set Darrick J. Wong
2024-04-16 5:26 ` Christoph Hellwig
2024-04-16 18:15 ` Darrick J. Wong
2024-04-16 1:36 ` [PATCH 02/17] xfs: make the reserved block permission flag explicit in xfs_attr_set Darrick J. Wong
2024-04-16 5:26 ` Christoph Hellwig
2024-04-16 1:36 ` [PATCH 03/17] xfs: use xfs_attr_defer_parent for calling xfs_attr_set on pptrs Darrick J. Wong
2024-04-16 5:29 ` Christoph Hellwig
2024-04-16 16:05 ` Darrick J. Wong
2024-04-16 16:28 ` Christoph Hellwig
2024-04-16 18:41 ` Darrick J. Wong
2024-04-16 18:51 ` Christoph Hellwig
2024-04-17 2:54 ` Darrick J. Wong
2024-04-17 5:00 ` Christoph Hellwig
2024-04-16 1:36 ` [PATCH 04/17] xfs: salvage parent pointers when rebuilding xattr structures Darrick J. Wong
2024-04-16 1:37 ` [PATCH 05/17] xfs: add raw parent pointer apis to support repair Darrick J. Wong
2024-04-16 1:37 ` [PATCH 06/17] xfs: repair directories by scanning directory parent pointers Darrick J. Wong
2024-04-16 1:37 ` [PATCH 07/17] xfs: implement live updates for directory repairs Darrick J. Wong
2024-04-16 1:38 ` [PATCH 08/17] xfs: replay unlocked parent pointer updates that accrue during xattr repair Darrick J. Wong
2024-04-16 1:38 ` [PATCH 09/17] xfs: repair directory parent pointers by scanning for dirents Darrick J. Wong
2024-04-16 1:38 ` [PATCH 10/17] xfs: implement live updates for parent pointer repairs Darrick J. Wong
2024-04-16 1:38 ` [PATCH 11/17] xfs: remove pointless unlocked assertion Darrick J. Wong
2024-04-16 1:39 ` [PATCH 12/17] xfs: split xfs_bmap_add_attrfork into two pieces Darrick J. Wong
2024-04-16 1:39 ` [PATCH 13/17] xfs: add a per-leaf block callback to xchk_xattr_walk Darrick J. Wong
2024-04-16 1:39 ` [PATCH 14/17] xfs: actually rebuild the parent pointer xattrs Darrick J. Wong
2024-04-16 1:39 ` [PATCH 15/17] xfs: adapt the orphanage code to handle parent pointers Darrick J. Wong
2024-04-16 1:40 ` [PATCH 16/17] xfs: repair link count of nondirectories after rebuilding " Darrick J. Wong
2024-04-16 1:40 ` [PATCH 17/17] xfs: inode repair should ensure there's an attr fork to store " Darrick J. Wong
2024-04-16 1:20 ` [PATCHSET v13.2 6/7] xfs: detect and correct directory tree problems Darrick J. Wong
2024-04-16 1:40 ` [PATCH 1/4] xfs: teach online scrub to find directory tree structure problems Darrick J. Wong
2024-04-16 1:40 ` [PATCH 2/4] xfs: invalidate dirloop scrub path data when concurrent updates happen Darrick J. Wong
2024-04-16 1:41 ` [PATCH 3/4] xfs: report directory tree corruption in the health information Darrick J. Wong
2024-04-16 1:41 ` [PATCH 4/4] xfs: fix corruptions in the directory tree Darrick J. Wong
2024-04-16 1:21 ` [PATCHSET v13.2 7/7] xfs: vectorize scrub kernel calls Darrick J. Wong
2024-04-16 1:41 ` [PATCH 1/4] xfs: reduce the rate of cond_resched calls inside scrub Darrick J. Wong
2024-04-16 1:41 ` [PATCH 2/4] xfs: move xfs_ioc_scrub_metadata to scrub.c Darrick J. Wong
2024-04-16 5:31 ` Christoph Hellwig
2024-04-16 1:42 ` [PATCH 3/4] xfs: introduce vectored scrub mode Darrick J. Wong
2024-04-16 5:33 ` Christoph Hellwig
2024-04-16 18:46 ` Darrick J. Wong
2024-04-16 18:56 ` Christoph Hellwig
2024-04-16 19:06 ` Darrick J. Wong
2024-04-17 2:55 ` [PATCH v13.2.1 " Darrick J. Wong
2024-04-16 1:42 ` [PATCH 4/4] xfs: only iget the file once when doing vectored scrub-by-handle Darrick J. Wong
2024-04-16 5:35 ` Christoph Hellwig
2024-04-16 22:31 ` Darrick J. Wong
2024-04-16 22:51 ` Darrick J. Wong
2024-04-17 5:02 ` Christoph Hellwig
2024-04-17 5:01 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240417222503.GC11948@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=allison.henderson@oracle.com \
--cc=catherine.hoang@oracle.com \
--cc=hch@infradead.org \
--cc=hch@lst.de \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox