Commit f1097be2 authored by Allison Henderson's avatar Allison Henderson Committed by Darrick J. Wong

xfs: add parent attributes to link

This patch modifies xfs_link to add a parent pointer to the inode.
Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarAllison Henderson <allison.henderson@oracle.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
[djwong: minor rebase fixes]
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent b7c62d90
...@@ -50,3 +50,17 @@ xfs_mkdir_space_res( ...@@ -50,3 +50,17 @@ xfs_mkdir_space_res(
{ {
return xfs_create_space_res(mp, namelen); return xfs_create_space_res(mp, namelen);
} }
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_parent_calc_space_res(mp, namelen);
return ret;
}
...@@ -86,8 +86,6 @@ ...@@ -86,8 +86,6 @@
(2 * (mp)->m_alloc_maxlevels) (2 * (mp)->m_alloc_maxlevels)
#define XFS_GROWFSRT_SPACE_RES(mp,b) \ #define XFS_GROWFSRT_SPACE_RES(mp,b) \
((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK)) ((b) + XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK))
#define XFS_LINK_SPACE_RES(mp,nl) \
XFS_DIRENTER_SPACE_RES(mp,nl)
#define XFS_QM_DQALLOC_SPACE_RES(mp) \ #define XFS_QM_DQALLOC_SPACE_RES(mp) \
(XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + \ (XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + \
XFS_DQUOT_CLUSTER_SIZE_FSB) XFS_DQUOT_CLUSTER_SIZE_FSB)
...@@ -107,5 +105,6 @@ unsigned int xfs_parent_calc_space_res(struct xfs_mount *mp, ...@@ -107,5 +105,6 @@ unsigned int xfs_parent_calc_space_res(struct xfs_mount *mp,
unsigned int xfs_create_space_res(struct xfs_mount *mp, unsigned int namelen); unsigned int xfs_create_space_res(struct xfs_mount *mp, unsigned int namelen);
unsigned int xfs_mkdir_space_res(struct xfs_mount *mp, unsigned int namelen); unsigned int xfs_mkdir_space_res(struct xfs_mount *mp, unsigned int namelen);
unsigned int xfs_link_space_res(struct xfs_mount *mp, unsigned int namelen);
#endif /* __XFS_TRANS_SPACE_H__ */ #endif /* __XFS_TRANS_SPACE_H__ */
...@@ -704,7 +704,7 @@ xrep_dir_replay_update( ...@@ -704,7 +704,7 @@ xrep_dir_replay_update(
uint resblks; uint resblks;
int error; int error;
resblks = XFS_LINK_SPACE_RES(mp, xname->len); resblks = xfs_link_space_res(mp, xname->len);
error = xchk_trans_alloc(rd->sc, resblks); error = xchk_trans_alloc(rd->sc, resblks);
if (error) if (error)
return error; return error;
......
...@@ -326,7 +326,7 @@ xrep_adoption_trans_alloc( ...@@ -326,7 +326,7 @@ xrep_adoption_trans_alloc(
/* Compute the worst case space reservation that we need. */ /* Compute the worst case space reservation that we need. */
adopt->sc = sc; adopt->sc = sc;
adopt->orphanage_blkres = XFS_LINK_SPACE_RES(mp, MAXNAMELEN); adopt->orphanage_blkres = xfs_link_space_res(mp, MAXNAMELEN);
if (S_ISDIR(VFS_I(sc->ip)->i_mode)) if (S_ISDIR(VFS_I(sc->ip)->i_mode))
child_blkres = XFS_RENAME_SPACE_RES(mp, xfs_name_dotdot.len); child_blkres = XFS_RENAME_SPACE_RES(mp, xfs_name_dotdot.len);
adopt->child_blkres = child_blkres; adopt->child_blkres = child_blkres;
......
...@@ -1299,14 +1299,15 @@ xfs_create_tmpfile( ...@@ -1299,14 +1299,15 @@ xfs_create_tmpfile(
int int
xfs_link( xfs_link(
xfs_inode_t *tdp, struct xfs_inode *tdp,
xfs_inode_t *sip, struct xfs_inode *sip,
struct xfs_name *target_name) struct xfs_name *target_name)
{ {
xfs_mount_t *mp = tdp->i_mount; struct xfs_mount *mp = tdp->i_mount;
xfs_trans_t *tp; struct xfs_trans *tp;
int error, nospace_error = 0; int error, nospace_error = 0;
int resblks; int resblks;
struct xfs_parent_args *ppargs;
trace_xfs_link(tdp, target_name); trace_xfs_link(tdp, target_name);
...@@ -1325,11 +1326,25 @@ xfs_link( ...@@ -1325,11 +1326,25 @@ xfs_link(
if (error) if (error)
goto std_return; goto std_return;
resblks = XFS_LINK_SPACE_RES(mp, target_name->len); error = xfs_parent_start(mp, &ppargs);
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, error = xfs_trans_alloc_dir(tdp, &M_RES(mp)->tr_link, sip, &resblks,
&tp, &nospace_error); &tp, &nospace_error);
if (error) if (error)
goto std_return; goto out_parent;
/*
* We don't allow reservationless or quotaless hardlinking when parent
* pointers are enabled because we can't back out if the xattrs must
* grow.
*/
if (ppargs && nospace_error) {
error = nospace_error;
goto error_return;
}
/* /*
* If we are using project inheritance, we only allow hard link * If we are using project inheritance, we only allow hard link
...@@ -1380,6 +1395,19 @@ xfs_link( ...@@ -1380,6 +1395,19 @@ xfs_link(
xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE); xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE);
xfs_bumplink(tp, sip); 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 (ppargs) {
error = xfs_parent_addname(tp, ppargs, tdp, target_name, sip);
if (error)
goto error_return;
}
xfs_dir_update_hook(tdp, sip, 1, target_name); xfs_dir_update_hook(tdp, sip, 1, target_name);
/* /*
...@@ -1393,12 +1421,15 @@ xfs_link( ...@@ -1393,12 +1421,15 @@ xfs_link(
error = xfs_trans_commit(tp); error = xfs_trans_commit(tp);
xfs_iunlock(tdp, XFS_ILOCK_EXCL); xfs_iunlock(tdp, XFS_ILOCK_EXCL);
xfs_iunlock(sip, XFS_ILOCK_EXCL); xfs_iunlock(sip, XFS_ILOCK_EXCL);
xfs_parent_finish(mp, ppargs);
return error; return error;
error_return: error_return:
xfs_trans_cancel(tp); xfs_trans_cancel(tp);
xfs_iunlock(tdp, XFS_ILOCK_EXCL); xfs_iunlock(tdp, XFS_ILOCK_EXCL);
xfs_iunlock(sip, XFS_ILOCK_EXCL); xfs_iunlock(sip, XFS_ILOCK_EXCL);
out_parent:
xfs_parent_finish(mp, ppargs);
std_return: std_return:
if (error == -ENOSPC && nospace_error) if (error == -ENOSPC && nospace_error)
error = nospace_error; error = nospace_error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment