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

xfs: remove parent pointers in unlink

This patch removes the parent pointer attribute during unlink
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: adjust to new ondisk format, minor rebase fixes]
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 5d31a85d
......@@ -205,3 +205,25 @@ xfs_parent_addname(
xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_SET);
return 0;
}
/* Remove a parent pointer to reflect a dirent removal. */
int
xfs_parent_removename(
struct xfs_trans *tp,
struct xfs_parent_args *ppargs,
struct xfs_inode *dp,
const struct xfs_name *parent_name,
struct xfs_inode *child)
{
int error;
error = xfs_parent_iread_extents(tp, child);
if (error)
return error;
xfs_inode_to_parent_rec(&ppargs->rec, dp);
xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
child->i_ino, parent_name);
xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REMOVE);
return 0;
}
......@@ -81,5 +81,8 @@ xfs_parent_finish(
int xfs_parent_addname(struct xfs_trans *tp, struct xfs_parent_args *ppargs,
struct xfs_inode *dp, const struct xfs_name *parent_name,
struct xfs_inode *child);
int xfs_parent_removename(struct xfs_trans *tp, struct xfs_parent_args *ppargs,
struct xfs_inode *dp, const struct xfs_name *parent_name,
struct xfs_inode *child);
#endif /* __XFS_PARENT_H__ */
......@@ -81,3 +81,16 @@ xfs_symlink_space_res(
return ret;
}
unsigned int
xfs_remove_space_res(
struct xfs_mount *mp,
unsigned int namelen)
{
unsigned int ret = XFS_DIRREMOVE_SPACE_RES(mp);
if (xfs_has_parent(mp))
ret += xfs_parent_calc_space_res(mp, namelen);
return ret;
}
......@@ -91,8 +91,6 @@
XFS_DQUOT_CLUSTER_SIZE_FSB)
#define XFS_QM_QINOCREATE_SPACE_RES(mp) \
XFS_IALLOC_SPACE_RES(mp)
#define XFS_REMOVE_SPACE_RES(mp) \
XFS_DIRREMOVE_SPACE_RES(mp)
#define XFS_RENAME_SPACE_RES(mp,nl) \
(XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
#define XFS_IFREE_SPACE_RES(mp) \
......@@ -106,5 +104,6 @@ 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);
unsigned int xfs_symlink_space_res(struct xfs_mount *mp, unsigned int namelen,
unsigned int fsblocks);
unsigned int xfs_remove_space_res(struct xfs_mount *mp, unsigned int namelen);
#endif /* __XFS_TRANS_SPACE_H__ */
......@@ -2721,16 +2721,17 @@ xfs_iunpin_wait(
*/
int
xfs_remove(
xfs_inode_t *dp,
struct xfs_inode *dp,
struct xfs_name *name,
xfs_inode_t *ip)
struct xfs_inode *ip)
{
xfs_mount_t *mp = dp->i_mount;
xfs_trans_t *tp = NULL;
struct xfs_mount *mp = dp->i_mount;
struct xfs_trans *tp = NULL;
int is_dir = S_ISDIR(VFS_I(ip)->i_mode);
int dontcare;
int error = 0;
uint resblks;
struct xfs_parent_args *ppargs;
trace_xfs_remove(dp, name);
......@@ -2747,6 +2748,10 @@ xfs_remove(
if (error)
goto std_return;
error = xfs_parent_start(mp, &ppargs);
if (error)
goto std_return;
/*
* We try to get the real space reservation first, allowing for
* directory btree deletion(s) implying possible bmap insert(s). If we
......@@ -2758,12 +2763,12 @@ xfs_remove(
* the directory code can handle a reservationless update and we don't
* want to prevent a user from trying to free space by deleting things.
*/
resblks = XFS_REMOVE_SPACE_RES(mp);
resblks = xfs_remove_space_res(mp, name->len);
error = xfs_trans_alloc_dir(dp, &M_RES(mp)->tr_remove, ip, &resblks,
&tp, &dontcare);
if (error) {
ASSERT(error != -ENOSPC);
goto std_return;
goto out_parent;
}
/*
......@@ -2823,6 +2828,13 @@ xfs_remove(
goto out_trans_cancel;
}
/* Remove parent pointer. */
if (ppargs) {
error = xfs_parent_removename(tp, ppargs, dp, name, ip);
if (error)
goto out_trans_cancel;
}
/*
* Drop the link from dp to ip, and if ip was a directory, remove the
* '.' and '..' references since we freed the directory.
......@@ -2846,6 +2858,7 @@ xfs_remove(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
xfs_parent_finish(mp, ppargs);
return 0;
out_trans_cancel:
......@@ -2853,6 +2866,8 @@ xfs_remove(
out_unlock:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
out_parent:
xfs_parent_finish(mp, ppargs);
std_return:
return 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