@@ -28,6 +28,7 @@
#include "xfs_swapext.h"
#include "xfs_xchgrange.h"
#include "xfs_acl.h"
+#include "xfs_parent.h"
#include "scrub/xfs_scrub.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
@@ -124,6 +125,13 @@ xrep_xattr_want_salvage(
return false;
if (valuelen > XATTR_SIZE_MAX || valuelen < 0)
return false;
+ if (attr_flags & XFS_ATTR_PARENT) {
+ if (!xfs_parent_namecheck(rx->sc->mp, name, namelen,
+ attr_flags))
+ return false;
+ if (!xfs_parent_valuecheck(rx->sc->mp, value, valuelen))
+ return false;
+ }
return true;
}
@@ -151,14 +159,21 @@ xrep_xattr_salvage_key(
* Truncate the name to the first character that would trip namecheck.
* If we no longer have a name after that, ignore this attribute.
*/
- while (i < namelen && name[i] != 0)
- i++;
- if (i == 0)
- return 0;
- key.namelen = i;
+ if (flags & XFS_ATTR_PARENT) {
+ key.namelen = namelen;
- trace_xrep_xattr_salvage_rec(rx->sc->ip, flags, name, key.namelen,
- valuelen);
+ trace_xrep_xattr_salvage_pptr(rx->sc->ip, flags, name,
+ key.namelen, value, valuelen);
+ } else {
+ while (i < namelen && name[i] != 0)
+ i++;
+ if (i == 0)
+ return 0;
+ key.namelen = i;
+
+ trace_xrep_xattr_salvage_rec(rx->sc->ip, flags, name,
+ key.namelen, valuelen);
+ }
error = xfblob_store(rx->xattr_blobs, &key.name_cookie, name,
key.namelen);
@@ -562,6 +577,9 @@ xrep_xattr_insert_rec(
struct xchk_xattr_buf *ab = rx->sc->buf;
int error;
+ if (key->flags & XFS_ATTR_PARENT)
+ args.op_flags |= XFS_DA_OP_NVLOOKUP;
+
/*
* Grab pointers to the scrub buffer so that we can use them to insert
* attrs into the temp file.
@@ -595,8 +613,13 @@ xrep_xattr_insert_rec(
ab->name[key->namelen] = 0;
- trace_xrep_xattr_insert_rec(rx->sc->tempip, key->flags, ab->name,
- key->namelen, key->valuelen);
+ if (key->flags & XFS_ATTR_PARENT)
+ trace_xrep_xattr_insert_pptr(rx->sc->tempip, key->flags,
+ ab->name, key->namelen, ab->value,
+ key->valuelen);
+ else
+ trace_xrep_xattr_insert_rec(rx->sc->tempip, key->flags,
+ ab->name, key->namelen, key->valuelen);
/*
* xfs_attr_set creates and commits its own transaction. If the attr
@@ -2662,6 +2662,46 @@ DEFINE_EVENT(xrep_xattr_salvage_class, name, \
DEFINE_XREP_XATTR_SALVAGE_EVENT(xrep_xattr_salvage_rec);
DEFINE_XREP_XATTR_SALVAGE_EVENT(xrep_xattr_insert_rec);
+DECLARE_EVENT_CLASS(xrep_pptr_salvage_class,
+ TP_PROTO(struct xfs_inode *ip, unsigned int flags, const void *name,
+ unsigned int namelen, const void *value, unsigned int valuelen),
+ TP_ARGS(ip, flags, name, namelen, value, valuelen),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(xfs_ino_t, ino)
+ __field(xfs_ino_t, parent_ino)
+ __field(unsigned int, parent_gen)
+ __field(unsigned int, namelen)
+ __dynamic_array(char, name, valuelen)
+ ),
+ TP_fast_assign(
+ struct xfs_parent_name_irec pptr;
+
+ xfs_parent_irec_from_disk(&pptr, name, value, valuelen);
+
+ __entry->dev = ip->i_mount->m_super->s_dev;
+ __entry->ino = ip->i_ino;
+ __entry->parent_ino = pptr.p_ino;
+ __entry->parent_gen = pptr.p_gen;
+ __entry->namelen = pptr.p_namelen;
+ memcpy(__get_str(name), pptr.p_name, pptr.p_namelen);
+ ),
+ TP_printk("dev %d:%d ino 0x%llx parent_ino 0x%llx parent_gen 0x%x name '%.*s'",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->ino,
+ __entry->parent_ino,
+ __entry->parent_gen,
+ __entry->namelen,
+ __get_str(name))
+)
+#define DEFINE_XREP_PPTR_SALVAGE_EVENT(name) \
+DEFINE_EVENT(xrep_pptr_salvage_class, name, \
+ TP_PROTO(struct xfs_inode *ip, unsigned int flags, const void *name, \
+ unsigned int namelen, const void *value, unsigned int valuelen), \
+ TP_ARGS(ip, flags, name, namelen, value, valuelen))
+DEFINE_XREP_PPTR_SALVAGE_EVENT(xrep_xattr_salvage_pptr);
+DEFINE_XREP_PPTR_SALVAGE_EVENT(xrep_xattr_insert_pptr);
+
TRACE_EVENT(xrep_xattr_class,
TP_PROTO(struct xfs_inode *ip, struct xfs_inode *arg_ip),
TP_ARGS(ip, arg_ip),