From: Darrick J. Wong <djwong@xxxxxxxxxx> Add an explicit owner field to xfs_da_args, which will make it easier for online fsck to set the owner field of the temporary directory and xattr structures that it builds to repair damaged metadata. Note: I hopefully found all the xfs_da_args definitions by looking for automatic stack variable declarations and xfs_da_args.dp assignments: git grep -E '(args.*dp =|struct xfs_da_args[[:space:]]*[a-z0-9][a-z0-9]*)' Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- db/attrset.c | 2 ++ db/namei.c | 1 + libxfs/xfs_attr_leaf.c | 2 ++ libxfs/xfs_bmap.c | 1 + libxfs/xfs_da_btree.h | 1 + libxfs/xfs_dir2.c | 5 +++++ libxfs/xfs_swapext.c | 2 ++ repair/phase6.c | 3 +++ 8 files changed, 17 insertions(+) diff --git a/db/attrset.c b/db/attrset.c index 0d8d70a8429..2b6cdb5f5c3 100644 --- a/db/attrset.c +++ b/db/attrset.c @@ -161,6 +161,7 @@ attr_set_f( (unsigned long long)iocur_top->ino); goto out; } + args.owner = iocur_top->ino; if (libxfs_attr_set(&args)) { dbprintf(_("failed to set attr %s on inode %llu\n"), @@ -247,6 +248,7 @@ attr_remove_f( (unsigned long long)iocur_top->ino); goto out; } + args.owner = iocur_top->ino; if (libxfs_attr_set(&args)) { dbprintf(_("failed to remove attr %s from inode %llu\n"), diff --git a/db/namei.c b/db/namei.c index 063721ca98f..eb09288b490 100644 --- a/db/namei.c +++ b/db/namei.c @@ -448,6 +448,7 @@ listdir( struct xfs_da_args args = { .dp = dp, .geo = dp->i_mount->m_dir_geo, + .owner = dp->i_ino, }; int error; bool isblock; diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index aa7aad36864..e3e9c265fab 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -972,6 +972,7 @@ xfs_attr_shortform_to_leaf( nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; nargs.op_flags = XFS_DA_OP_OKNOENT; + nargs.owner = args->owner; sfe = &sf->list[0]; for (i = 0; i < sf->hdr.count; i++) { @@ -1175,6 +1176,7 @@ xfs_attr3_leaf_to_shortform( nargs.whichfork = XFS_ATTR_FORK; nargs.trans = args->trans; nargs.op_flags = XFS_DA_OP_OKNOENT; + nargs.owner = args->owner; for (i = 0; i < ichdr.count; entry++, i++) { if (entry->flags & XFS_ATTR_INCOMPLETE) diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 54db35bc398..296e7d85f63 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -952,6 +952,7 @@ xfs_bmap_add_attrfork_local( dargs.total = dargs.geo->fsbcount; dargs.whichfork = XFS_DATA_FORK; dargs.trans = tp; + dargs.owner = ip->i_ino; return xfs_dir2_sf_to_block(&dargs); } diff --git a/libxfs/xfs_da_btree.h b/libxfs/xfs_da_btree.h index 706baf36e17..7fb13f26eda 100644 --- a/libxfs/xfs_da_btree.h +++ b/libxfs/xfs_da_btree.h @@ -79,6 +79,7 @@ typedef struct xfs_da_args { int rmtvaluelen2; /* remote attr value length in bytes */ uint32_t op_flags; /* operation flags */ enum xfs_dacmp cmpresult; /* name compare result for lookups */ + xfs_ino_t owner; /* inode that owns the dir/attr data */ } xfs_da_args_t; /* diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index e503bf8f92f..79b6ec893fd 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -249,6 +249,7 @@ xfs_dir_init( args->geo = dp->i_mount->m_dir_geo; args->dp = dp; args->trans = tp; + args->owner = dp->i_ino; error = xfs_dir2_sf_create(args, pdp->i_ino); kmem_free(args); return error; @@ -294,6 +295,7 @@ xfs_dir_createname( args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + args->owner = dp->i_ino; if (!inum) args->op_flags |= XFS_DA_OP_JUSTCHECK; @@ -388,6 +390,7 @@ xfs_dir_lookup( args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_OKNOENT; + args->owner = dp->i_ino; if (ci_name) args->op_flags |= XFS_DA_OP_CILOOKUP; @@ -461,6 +464,7 @@ xfs_dir_removename( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + args->owner = dp->i_ino; if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); @@ -522,6 +526,7 @@ xfs_dir_replace( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + args->owner = dp->i_ino; if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_replace(args); diff --git a/libxfs/xfs_swapext.c b/libxfs/xfs_swapext.c index 92d2f8fa133..5c96ad8a203 100644 --- a/libxfs/xfs_swapext.c +++ b/libxfs/xfs_swapext.c @@ -524,6 +524,7 @@ xfs_swapext_attr_to_sf( .geo = tp->t_mountp->m_attr_geo, .whichfork = XFS_ATTR_FORK, .trans = tp, + .owner = sxi->sxi_ip2->i_ino, }; struct xfs_buf *bp; int forkoff; @@ -554,6 +555,7 @@ xfs_swapext_dir_to_sf( .geo = tp->t_mountp->m_dir_geo, .whichfork = XFS_DATA_FORK, .trans = tp, + .owner = sxi->sxi_ip2->i_ino, }; struct xfs_dir2_sf_hdr sfh; struct xfs_buf *bp; diff --git a/repair/phase6.c b/repair/phase6.c index c681a69017d..ac037cf80ad 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1393,6 +1393,7 @@ dir2_kill_block( args.trans = tp; args.whichfork = XFS_DATA_FORK; args.geo = mp->m_dir_geo; + args.owner = ip->i_ino; if (da_bno >= mp->m_dir_geo->leafblk && da_bno < mp->m_dir_geo->freeblk) error = -libxfs_da_shrink_inode(&args, da_bno, bp); else @@ -1496,6 +1497,7 @@ longform_dir2_entry_check_data( struct xfs_da_args da = { .dp = ip, .geo = mp->m_dir_geo, + .owner = ip->i_ino, }; @@ -2284,6 +2286,7 @@ longform_dir2_entry_check( /* is this a block, leaf, or node directory? */ args.dp = ip; args.geo = mp->m_dir_geo; + args.owner = ip->i_ino; libxfs_dir2_isblock(&args, &isblock); libxfs_dir2_isleaf(&args, &isleaf);