Skip to content

Commit

Permalink
xfs: add parent attributes to link
Browse files Browse the repository at this point in the history
This patch modifies xfs_link to add a parent pointer to the inode.

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>
  • Loading branch information
allisonhenderson authored and intel-lab-lkp committed Nov 7, 2022
1 parent d90d2f0 commit 47ecbdd
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
2 changes: 0 additions & 2 deletions fs/xfs/libxfs/xfs_trans_space.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@
(2 * (mp)->m_alloc_maxlevels)
#define XFS_GROWFSRT_SPACE_RES(mp,b) \
((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK))
#define XFS_LINK_SPACE_RES(mp,nl) \
XFS_DIRENTER_SPACE_RES(mp,nl)
#define XFS_MKDIR_SPACE_RES(mp,nl) \
(XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
#define XFS_QM_DQALLOC_SPACE_RES(mp) \
Expand Down
52 changes: 45 additions & 7 deletions fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1248,16 +1248,32 @@ xfs_create_tmpfile(
return error;
}

unsigned int
xfs_link_space_res(
struct xfs_mount *mp,
unsigned int namelen)
{
unsigned int ret;

ret = XFS_DIRENTER_SPACE_RES(mp, namelen);
if (xfs_has_parent(mp))
ret += xfs_pptr_calc_space_res(mp, namelen);

return ret;
}

int
xfs_link(
xfs_inode_t *tdp,
xfs_inode_t *sip,
struct xfs_inode *tdp,
struct xfs_inode *sip,
struct xfs_name *target_name)
{
xfs_mount_t *mp = tdp->i_mount;
xfs_trans_t *tp;
struct xfs_mount *mp = tdp->i_mount;
struct xfs_trans *tp;
int error, nospace_error = 0;
int resblks;
xfs_dir2_dataptr_t diroffset;
struct xfs_parent_defer *parent = NULL;

trace_xfs_link(tdp, target_name);

Expand All @@ -1274,11 +1290,17 @@ xfs_link(
if (error)
goto std_return;

resblks = XFS_LINK_SPACE_RES(mp, target_name->len);
if (xfs_has_parent(mp)) {
error = xfs_parent_init(mp, &parent);
if (error)
goto std_return;
}

resblks = xfs_link_space_res(mp, target_name->len);
error = xfs_trans_alloc_dir(tdp, &M_RES(mp)->tr_link, sip, &resblks,
&tp, &nospace_error);
if (error)
goto std_return;
goto drop_incompat;

/*
* If we are using project inheritance, we only allow hard link
Expand Down Expand Up @@ -1311,14 +1333,27 @@ xfs_link(
}

error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
resblks, NULL);
resblks, &diroffset);
if (error)
goto error_return;
xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE);

xfs_bumplink(tp, sip);

/*
* If we have parent pointers, we now need to add the parent record to
* the attribute fork of the inode. If this is the initial parent
* attribute, we need to create it correctly, otherwise we can just add
* the parent to the inode.
*/
if (parent) {
error = xfs_parent_defer_add(tp, parent, tdp, target_name,
diroffset, sip);
if (error)
goto error_return;
}

/*
* If this is a synchronous mount, make sure that the
* link transaction goes to disk before returning to
Expand All @@ -1336,6 +1371,9 @@ xfs_link(
xfs_trans_cancel(tp);
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
xfs_iunlock(sip, XFS_ILOCK_EXCL);
drop_incompat:
if (parent)
xfs_parent_cancel(mp, parent);
std_return:
if (error == -ENOSPC && nospace_error)
error = nospace_error;
Expand Down

0 comments on commit 47ecbdd

Please sign in to comment.