mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
xfs: add parent attributes to link
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> [djwong: minor rebase fixes] Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
b7c62d90c1
commit
f1097be220
@ -50,3 +50,17 @@ xfs_mkdir_space_res(
|
||||
{
|
||||
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 @@
|
||||
(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_QM_DQALLOC_SPACE_RES(mp) \
|
||||
(XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK) + \
|
||||
XFS_DQUOT_CLUSTER_SIZE_FSB)
|
||||
@ -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_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__ */
|
||||
|
@ -704,7 +704,7 @@ xrep_dir_replay_update(
|
||||
uint resblks;
|
||||
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);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -326,7 +326,7 @@ xrep_adoption_trans_alloc(
|
||||
|
||||
/* Compute the worst case space reservation that we need. */
|
||||
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))
|
||||
child_blkres = XFS_RENAME_SPACE_RES(mp, xfs_name_dotdot.len);
|
||||
adopt->child_blkres = child_blkres;
|
||||
|
@ -1299,14 +1299,15 @@ xfs_create_tmpfile(
|
||||
|
||||
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;
|
||||
struct xfs_parent_args *ppargs;
|
||||
|
||||
trace_xfs_link(tdp, target_name);
|
||||
|
||||
@ -1325,11 +1326,25 @@ xfs_link(
|
||||
if (error)
|
||||
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,
|
||||
&tp, &nospace_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
|
||||
@ -1380,6 +1395,19 @@ xfs_link(
|
||||
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 (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);
|
||||
|
||||
/*
|
||||
@ -1393,12 +1421,15 @@ xfs_link(
|
||||
error = xfs_trans_commit(tp);
|
||||
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
|
||||
xfs_iunlock(sip, XFS_ILOCK_EXCL);
|
||||
xfs_parent_finish(mp, ppargs);
|
||||
return error;
|
||||
|
||||
error_return:
|
||||
xfs_trans_cancel(tp);
|
||||
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
|
||||
xfs_iunlock(sip, XFS_ILOCK_EXCL);
|
||||
out_parent:
|
||||
xfs_parent_finish(mp, ppargs);
|
||||
std_return:
|
||||
if (error == -ENOSPC && nospace_error)
|
||||
error = nospace_error;
|
||||
|
Loading…
Reference in New Issue
Block a user