@@ -675,7 +675,7 @@ xchk_xattr(
* iteration, which doesn't really follow the usual buffer
* locking order.
*/
- error = xchk_xattr_walk(sc, sc->ip, xchk_xattr_actor, NULL);
+ error = xchk_xattr_walk(sc, sc->ip, xchk_xattr_actor, NULL, NULL);
if (!xchk_fblock_process_error(sc, XFS_ATTR_FORK, 0, &error))
return error;
@@ -1288,7 +1288,7 @@ xrep_dir_scan_file(
goto scan_done;
}
- error = xchk_xattr_walk(rd->sc, ip, xrep_dir_scan_pptr, rd);
+ error = xchk_xattr_walk(rd->sc, ip, xrep_dir_scan_pptr, NULL, rd);
if (error)
goto scan_done;
@@ -221,6 +221,7 @@ xchk_xattr_walk_node(
struct xfs_scrub *sc,
struct xfs_inode *ip,
xchk_xattr_fn attr_fn,
+ xchk_xattrleaf_fn leaf_fn,
void *priv)
{
struct xfs_attr3_icleaf_hdr leafhdr;
@@ -252,6 +253,12 @@ xchk_xattr_walk_node(
xfs_trans_brelse(sc->tp, leaf_bp);
+ if (leaf_fn) {
+ error = leaf_fn(sc, priv);
+ if (error)
+ goto out_bitmap;
+ }
+
/* Make sure we haven't seen this new leaf already. */
len = 1;
if (xdab_bitmap_test(&seen_dablks, leafhdr.forw, &len)) {
@@ -288,6 +295,7 @@ xchk_xattr_walk(
struct xfs_scrub *sc,
struct xfs_inode *ip,
xchk_xattr_fn attr_fn,
+ xchk_xattrleaf_fn leaf_fn,
void *priv)
{
int error;
@@ -308,5 +316,5 @@ xchk_xattr_walk(
if (xfs_attr_is_leaf(ip))
return xchk_xattr_walk_leaf(sc, ip, attr_fn, priv);
- return xchk_xattr_walk_node(sc, ip, attr_fn, priv);
+ return xchk_xattr_walk_node(sc, ip, attr_fn, leaf_fn, priv);
}
@@ -11,7 +11,9 @@ typedef int (*xchk_xattr_fn)(struct xfs_scrub *sc, struct xfs_inode *ip,
unsigned int namelen, const void *value, unsigned int valuelen,
void *priv);
+typedef int (*xchk_xattrleaf_fn)(struct xfs_scrub *sc, void *priv);
+
int xchk_xattr_walk(struct xfs_scrub *sc, struct xfs_inode *ip,
- xchk_xattr_fn attr_fn, void *priv);
+ xchk_xattr_fn attr_fn, xchk_xattrleaf_fn leaf_fn, void *priv);
#endif /* __XFS_SCRUB_LISTXATTR_H__ */
@@ -434,7 +434,8 @@ xchk_nlinks_collect_dir(
goto out_unlock;
}
- error = xchk_xattr_walk(sc, dp, xchk_nlinks_collect_pptr, xnc);
+ error = xchk_xattr_walk(sc, dp, xchk_nlinks_collect_pptr, NULL,
+ xnc);
if (error == -ECANCELED) {
error = 0;
goto out_unlock;
@@ -317,7 +317,7 @@ xchk_parent_pptr_and_dotdot(
return 0;
/* Otherwise, walk the pptrs again, and check. */
- error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_dotdot, pp);
+ error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_dotdot, NULL, pp);
if (error == -ECANCELED) {
/* Found a parent pointer that matches dotdot. */
return 0;
@@ -699,7 +699,8 @@ xchk_parent_count_pptrs(
*/
if (pp->need_revalidate) {
pp->pptrs_found = 0;
- error = xchk_xattr_walk(sc, sc->ip, xchk_parent_count_pptr, pp);
+ error = xchk_xattr_walk(sc, sc->ip, xchk_parent_count_pptr,
+ NULL, pp);
if (error == -EFSCORRUPTED) {
/* Found a bad parent pointer */
xchk_fblock_set_corrupt(sc, XFS_ATTR_FORK, 0);
@@ -758,7 +759,7 @@ xchk_parent_pptr(
if (error)
goto out_entries;
- error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_attr, pp);
+ error = xchk_xattr_walk(sc, sc->ip, xchk_parent_scan_attr, NULL, pp);
if (error == -ECANCELED) {
error = 0;
goto out_names;