Skip to content

Commit 0d2dd38

Browse files
author
Chandan Babu R
committed
Merge tag 'scrub-pptrs-6.10_2024-04-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.10-mergeC
xfs: scrubbing for parent pointers Teach online fsck to use parent pointers to assist in checking directories, parent pointers, extended attributes, and link counts. Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: Chandan Babu R <[email protected]> * tag 'scrub-pptrs-6.10_2024-04-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: check parent pointer xattrs when scrubbing xfs: walk directory parent pointers to determine backref count xfs: deferred scrub of parent pointers xfs: scrub parent pointers xfs: deferred scrub of dirents xfs: check dirents have parent pointers xfs: revert commit 44af6c7
2 parents 47d83c1 + 59a2af9 commit 0d2dd38

File tree

13 files changed

+1307
-11
lines changed

13 files changed

+1307
-11
lines changed

fs/xfs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ xfs-y += $(addprefix scrub/, \
177177
scrub.o \
178178
symlink.o \
179179
xfarray.o \
180+
xfblob.o \
180181
xfile.o \
181182
)
182183

@@ -218,7 +219,6 @@ xfs-y += $(addprefix scrub/, \
218219
rmap_repair.o \
219220
symlink_repair.o \
220221
tempfile.o \
221-
xfblob.o \
222222
)
223223

224224
xfs-$(CONFIG_XFS_RT) += $(addprefix scrub/, \

fs/xfs/libxfs/xfs_parent.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,25 @@ xfs_parent_from_attr(
291291
*parent_gen = be32_to_cpu(rec->p_gen);
292292
return 0;
293293
}
294+
295+
/*
296+
* Look up a parent pointer record (@parent_name -> @pptr) of @ip.
297+
*
298+
* Caller must hold at least ILOCK_SHARED. The scratchpad need not be
299+
* initialized.
300+
*
301+
* Returns 0 if the pointer is found, -ENOATTR if there is no match, or a
302+
* negative errno.
303+
*/
304+
int
305+
xfs_parent_lookup(
306+
struct xfs_trans *tp,
307+
struct xfs_inode *ip,
308+
const struct xfs_name *parent_name,
309+
struct xfs_parent_rec *pptr,
310+
struct xfs_da_args *scratch)
311+
{
312+
memset(scratch, 0, sizeof(struct xfs_da_args));
313+
xfs_parent_da_args_init(scratch, tp, pptr, ip, ip->i_ino, parent_name);
314+
return xfs_attr_get_ilocked(scratch);
315+
}

fs/xfs/libxfs/xfs_parent.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,9 @@ int xfs_parent_from_attr(struct xfs_mount *mp, unsigned int attr_flags,
9696
const void *value, unsigned int valuelen,
9797
xfs_ino_t *parent_ino, uint32_t *parent_gen);
9898

99+
/* Repair functions */
100+
int xfs_parent_lookup(struct xfs_trans *tp, struct xfs_inode *ip,
101+
const struct xfs_name *name, struct xfs_parent_rec *pptr,
102+
struct xfs_da_args *scratch);
103+
99104
#endif /* __XFS_PARENT_H__ */

fs/xfs/scrub/attr.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "xfs_attr.h"
1818
#include "xfs_attr_leaf.h"
1919
#include "xfs_attr_sf.h"
20+
#include "xfs_parent.h"
2021
#include "scrub/scrub.h"
2122
#include "scrub/common.h"
2223
#include "scrub/dabtree.h"
@@ -208,13 +209,12 @@ xchk_xattr_actor(
208209
return -ECANCELED;
209210
}
210211

211-
/*
212-
* Local and shortform xattr values are stored in the attr leaf block,
213-
* so we don't need to retrieve the value from a remote block to detect
214-
* corruption problems.
215-
*/
216-
if (value)
217-
return 0;
212+
/* Check parent pointer record. */
213+
if ((attr_flags & XFS_ATTR_PARENT) &&
214+
!xfs_parent_valuecheck(sc->mp, value, valuelen)) {
215+
xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, args.blkno);
216+
return -ECANCELED;
217+
}
218218

219219
/*
220220
* Try to allocate enough memory to extract the attr value. If that
@@ -227,8 +227,21 @@ xchk_xattr_actor(
227227
if (error)
228228
return error;
229229

230+
/*
231+
* Parent pointers are matched on attr name and value, so we must
232+
* supply the xfs_parent_rec here when confirming that the dabtree
233+
* indexing works correctly.
234+
*/
235+
if (attr_flags & XFS_ATTR_PARENT)
236+
memcpy(ab->value, value, valuelen);
237+
230238
args.value = ab->value;
231239

240+
/*
241+
* Get the attr value to ensure that lookup can find this attribute
242+
* through the dabtree indexing and that remote value retrieval also
243+
* works correctly.
244+
*/
232245
xfs_attr_sethash(&args);
233246
error = xfs_attr_get_ilocked(&args);
234247
/* ENODATA means the hash lookup failed and the attr is bad */

fs/xfs/scrub/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ static inline bool xchk_skip_xref(struct xfs_scrub_metadata *sm)
212212
}
213213

214214
bool xchk_dir_looks_zapped(struct xfs_inode *dp);
215+
bool xchk_pptr_looks_zapped(struct xfs_inode *ip);
215216

216217
#ifdef CONFIG_XFS_ONLINE_REPAIR
217218
/* Decide if a repair is required. */

0 commit comments

Comments
 (0)