diff options
author | Allison Henderson <allison.henderson@oracle.com> | 2024-04-22 09:47:47 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2024-04-23 07:46:58 -0700 |
commit | b7c62d90c12c6cc86f10b8a62cefe0029374b6ff (patch) | |
tree | 13dd5bc0b97c470f1eea6e48eec73c52f0b440a9 /fs/xfs/xfs_inode.c | |
parent | fb102fe7fe02e70f8a49cc7f74bc0769cdab2912 (diff) |
xfs: parent pointer attribute creation
Add parent pointer attribute during xfs_create, and subroutines to
initialize attributes. Note that the xfs_attr_intent object contains a
pointer to the caller's xfs_da_args object, so the latter must persist
until transaction commit.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: shorten names, adjust to new format, set init_xattrs for parent
pointers]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 060e4e767b51..0dd4111a6773 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -40,6 +40,8 @@ #include "xfs_log_priv.h" #include "xfs_health.h" #include "xfs_pnfs.h" +#include "xfs_parent.h" +#include "xfs_xattr.h" struct kmem_cache *xfs_inode_cache; @@ -1017,7 +1019,7 @@ xfs_dir_hook_setup( int xfs_create( struct mnt_idmap *idmap, - xfs_inode_t *dp, + struct xfs_inode *dp, struct xfs_name *name, umode_t mode, dev_t rdev, @@ -1029,7 +1031,7 @@ xfs_create( struct xfs_inode *ip = NULL; struct xfs_trans *tp = NULL; int error; - bool unlock_dp_on_error = false; + bool unlock_dp_on_error = false; prid_t prid; struct xfs_dquot *udqp = NULL; struct xfs_dquot *gdqp = NULL; @@ -1037,6 +1039,7 @@ xfs_create( struct xfs_trans_res *tres; uint resblks; xfs_ino_t ino; + struct xfs_parent_args *ppargs; trace_xfs_create(dp, name); @@ -1058,13 +1061,17 @@ xfs_create( return error; if (is_dir) { - resblks = XFS_MKDIR_SPACE_RES(mp, name->len); + resblks = xfs_mkdir_space_res(mp, name->len); tres = &M_RES(mp)->tr_mkdir; } else { - resblks = XFS_CREATE_SPACE_RES(mp, name->len); + resblks = xfs_create_space_res(mp, name->len); tres = &M_RES(mp)->tr_create; } + error = xfs_parent_start(mp, &ppargs); + if (error) + goto out_release_dquots; + /* * Initially assume that the file does not exist and * reserve the resources for that case. If that is not @@ -1080,7 +1087,7 @@ xfs_create( resblks, &tp); } if (error) - goto out_release_dquots; + goto out_parent; xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); unlock_dp_on_error = true; @@ -1124,6 +1131,16 @@ xfs_create( } /* + * If we have parent pointers, we need to add the attribute containing + * the parent information now. + */ + if (ppargs) { + error = xfs_parent_addname(tp, ppargs, dp, name, ip); + if (error) + goto out_trans_cancel; + } + + /* * Create ip with a reference from dp, and add '.' and '..' references * if it's a directory. */ @@ -1155,6 +1172,7 @@ xfs_create( *ipp = ip; xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL); + xfs_parent_finish(mp, ppargs); return 0; out_trans_cancel: @@ -1170,6 +1188,8 @@ xfs_create( xfs_finish_inode_setup(ip); xfs_irele(ip); } + out_parent: + xfs_parent_finish(mp, ppargs); out_release_dquots: xfs_qm_dqrele(udqp); xfs_qm_dqrele(gdqp); @@ -3038,7 +3058,7 @@ xfs_rename_alloc_whiteout( int error; error = xfs_create_tmpfile(idmap, dp, S_IFCHR | WHITEOUT_MODE, - false, &tmpfile); + xfs_has_parent(dp->i_mount), &tmpfile); if (error) return error; |