Skip to content

Commit

Permalink
xfs: remove parent pointers in unlink
Browse files Browse the repository at this point in the history
This patch removes the parent pointer attribute during unlink

[bfoster: rebase, use VFS inode generation]
[achender: rebased, changed __unint32_t to xfs_dir2_dataptr_t
           implemented xfs_attr_remove_parent]

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
  • Loading branch information
allisonhenderson committed May 5, 2022
1 parent e971cd5 commit 72ff733
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 15 deletions.
2 changes: 1 addition & 1 deletion fs/xfs/libxfs/xfs_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ xfs_attr_defer_replace(
}

/* Removes an attribute for an inode as a deferred operation */
static int
int
xfs_attr_defer_remove(
struct xfs_da_args *args)
{
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/libxfs/xfs_attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ bool xfs_attr_is_leaf(struct xfs_inode *ip);
int xfs_attr_get_ilocked(struct xfs_da_args *args);
int xfs_attr_get(struct xfs_da_args *args);
int xfs_attr_defer_add(struct xfs_da_args *args);
int xfs_attr_defer_remove(struct xfs_da_args *args);
int xfs_attr_set(struct xfs_da_args *args);
int xfs_attr_set_iter(struct xfs_attr_item *attr);
int xfs_attr_remove_iter(struct xfs_attr_item *attr);
Expand Down
63 changes: 49 additions & 14 deletions fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2825,16 +2825,27 @@ xfs_iunpin_wait(
*/
int
xfs_remove(
xfs_inode_t *dp,
struct xfs_name *name,
xfs_inode_t *ip)
{
xfs_mount_t *mp = dp->i_mount;
xfs_trans_t *tp = NULL;
int is_dir = S_ISDIR(VFS_I(ip)->i_mode);
int dontcare;
int error = 0;
uint resblks;
xfs_inode_t *dp,
struct xfs_name *name,
xfs_inode_t *ip)
{
xfs_mount_t *mp = dp->i_mount;
xfs_trans_t *tp = NULL;
int is_dir = S_ISDIR(VFS_I(ip)->i_mode);
int dontcare;
int error = 0;
uint resblks;
xfs_dir2_dataptr_t dir_offset;
struct xfs_parent_name_rec rec;
struct xfs_da_args args = {
.dp = ip,
.geo = mp->m_attr_geo,
.whichfork = XFS_ATTR_FORK,
.attr_filter = XFS_ATTR_PARENT,
.op_flags = XFS_DA_OP_OKNOENT,
.name = (const uint8_t *)&rec,
.namelen = sizeof(rec),
};

trace_xfs_remove(dp, name);

Expand All @@ -2849,6 +2860,12 @@ xfs_remove(
if (error)
goto std_return;

if (xfs_has_larp(mp)) {
error = xfs_attr_use_log_assist(mp);
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
Expand All @@ -2862,10 +2879,10 @@ xfs_remove(
*/
resblks = XFS_REMOVE_SPACE_RES(mp);
error = xfs_trans_alloc_dir(dp, &M_RES(mp)->tr_remove, ip, &resblks,
&tp, &dontcare, XFS_ILOCK_EXCL);
&tp, &dontcare, 0);
if (error) {
ASSERT(error != -ENOSPC);
goto std_return;
goto drop_incompat;
}

/*
Expand Down Expand Up @@ -2919,12 +2936,22 @@ xfs_remove(
if (error)
goto out_trans_cancel;

error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks, NULL);
error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks, &dir_offset);
if (error) {
ASSERT(error != -ENOENT);
goto out_trans_cancel;
}

if (xfs_sb_version_hasparent(&mp->m_sb)) {
xfs_init_parent_name_rec(&rec, dp, dir_offset);
args.hashval = xfs_da_hashname(args.name, args.namelen);
args.trans = tp;

error = xfs_attr_defer_remove(&args);
if (error)
goto out_trans_cancel;
}

/*
* If this is a synchronous mount, make sure that the
* remove transaction goes to disk before returning to
Expand All @@ -2935,15 +2962,23 @@ xfs_remove(

error = xfs_trans_commit(tp);
if (error)
goto std_return;
goto out_unlock;

if (is_dir && xfs_inode_is_filestream(ip))
xfs_filestream_deassociate(ip);

xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
return 0;

out_trans_cancel:
xfs_trans_cancel(tp);
out_unlock:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
drop_incompat:
if (xfs_has_larp(mp))
xlog_drop_incompat_feat(mp->m_log);
std_return:
return error;
}
Expand Down

0 comments on commit 72ff733

Please sign in to comment.