summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c177
1 files changed, 53 insertions, 124 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5df4de666cc1..d957a46dc1cb 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -927,7 +927,7 @@ xfs_ialloc(
case S_IFLNK:
ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
ip->i_df.if_flags = XFS_IFEXTENTS;
- ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
+ ip->i_df.if_bytes = 0;
ip->i_df.if_u1.if_root = NULL;
break;
default:
@@ -1142,8 +1142,6 @@ xfs_create(
struct xfs_inode *ip = NULL;
struct xfs_trans *tp = NULL;
int error;
- struct xfs_defer_ops dfops;
- xfs_fsblock_t first_block;
bool unlock_dp_on_error = false;
prid_t prid;
struct xfs_dquot *udqp = NULL;
@@ -1195,9 +1193,6 @@ xfs_create(
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
unlock_dp_on_error = true;
- xfs_defer_init(&dfops, &first_block);
- tp->t_agfl_dfops = &dfops;
-
/*
* Reserve disk quota and the inode.
*/
@@ -1226,7 +1221,7 @@ xfs_create(
unlock_dp_on_error = false;
error = xfs_dir_createname(tp, dp, name, ip->i_ino,
- &first_block, &dfops, resblks ?
+ resblks ?
resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
if (error) {
ASSERT(error != -ENOSPC);
@@ -1238,11 +1233,11 @@ xfs_create(
if (is_dir) {
error = xfs_dir_init(tp, ip, dp);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
error = xfs_bumplink(tp, dp);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
}
/*
@@ -1260,10 +1255,6 @@ xfs_create(
*/
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
- error = xfs_defer_finish(&tp, &dfops);
- if (error)
- goto out_bmap_cancel;
-
error = xfs_trans_commit(tp);
if (error)
goto out_release_inode;
@@ -1275,8 +1266,6 @@ xfs_create(
*ipp = ip;
return 0;
- out_bmap_cancel:
- xfs_defer_cancel(&dfops);
out_trans_cancel:
xfs_trans_cancel(tp);
out_release_inode:
@@ -1287,7 +1276,7 @@ xfs_create(
*/
if (ip) {
xfs_finish_inode_setup(ip);
- IRELE(ip);
+ xfs_irele(ip);
}
xfs_qm_dqrele(udqp);
@@ -1382,7 +1371,7 @@ xfs_create_tmpfile(
*/
if (ip) {
xfs_finish_inode_setup(ip);
- IRELE(ip);
+ xfs_irele(ip);
}
xfs_qm_dqrele(udqp);
@@ -1401,8 +1390,6 @@ xfs_link(
xfs_mount_t *mp = tdp->i_mount;
xfs_trans_t *tp;
int error;
- struct xfs_defer_ops dfops;
- xfs_fsblock_t first_block;
int resblks;
trace_xfs_link(tdp, target_name);
@@ -1451,9 +1438,6 @@ xfs_link(
goto error_return;
}
- xfs_defer_init(&dfops, &first_block);
- tp->t_agfl_dfops = &dfops;
-
/*
* Handle initial link state of O_TMPFILE inode
*/
@@ -1464,7 +1448,7 @@ xfs_link(
}
error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
- &first_block, &dfops, resblks);
+ resblks);
if (error)
goto error_return;
xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -1482,12 +1466,6 @@ xfs_link(
if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
xfs_trans_set_sync(tp);
- error = xfs_defer_finish(&tp, &dfops);
- if (error) {
- xfs_defer_cancel(&dfops);
- goto error_return;
- }
-
return xfs_trans_commit(tp);
error_return:
@@ -1545,8 +1523,6 @@ xfs_itruncate_extents_flags(
{
struct xfs_mount *mp = ip->i_mount;
struct xfs_trans *tp = *tpp;
- struct xfs_defer_ops dfops;
- xfs_fsblock_t first_block;
xfs_fileoff_t first_unmap_block;
xfs_fileoff_t last_block;
xfs_filblks_t unmap_len;
@@ -1583,10 +1559,9 @@ xfs_itruncate_extents_flags(
ASSERT(first_unmap_block < last_block);
unmap_len = last_block - first_unmap_block + 1;
while (!done) {
- xfs_defer_init(&dfops, &first_block);
+ ASSERT(tp->t_firstblock == NULLFSBLOCK);
error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags,
- XFS_ITRUNC_MAX_EXTENTS, &first_block,
- &dfops, &done);
+ XFS_ITRUNC_MAX_EXTENTS, &done);
if (error)
goto out_bmap_cancel;
@@ -1594,10 +1569,9 @@ xfs_itruncate_extents_flags(
* Duplicate the transaction that has the permanent
* reservation and commit the old transaction.
*/
- xfs_defer_ijoin(&dfops, ip);
- error = xfs_defer_finish(&tp, &dfops);
+ error = xfs_defer_finish(&tp);
if (error)
- goto out_bmap_cancel;
+ goto out;
error = xfs_trans_roll_inode(&tp, ip);
if (error)
@@ -1631,7 +1605,7 @@ out_bmap_cancel:
* the transaction can be properly aborted. We just need to make sure
* we're not holding any resources that we were not when we came in.
*/
- xfs_defer_cancel(&dfops);
+ xfs_defer_cancel(tp);
goto out;
}
@@ -1733,7 +1707,6 @@ xfs_inactive_truncate(
ASSERT(XFS_FORCED_SHUTDOWN(mp));
return error;
}
-
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0);
@@ -1774,8 +1747,6 @@ STATIC int
xfs_inactive_ifree(
struct xfs_inode *ip)
{
- struct xfs_defer_ops dfops;
- xfs_fsblock_t first_block;
struct xfs_mount *mp = ip->i_mount;
struct xfs_trans *tp;
int error;
@@ -1812,9 +1783,7 @@ xfs_inactive_ifree(
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0);
- xfs_defer_init(&dfops, &first_block);
- tp->t_agfl_dfops = &dfops;
- error = xfs_ifree(tp, ip, &dfops);
+ error = xfs_ifree(tp, ip);
if (error) {
/*
* If we fail to free the inode, shut down. The cancel
@@ -1840,12 +1809,6 @@ xfs_inactive_ifree(
* Just ignore errors at this point. There is nothing we can do except
* to try to keep going. Make sure it's not a silent error.
*/
- error = xfs_defer_finish(&tp, &dfops);
- if (error) {
- xfs_notice(mp, "%s: xfs_defer_finish returned error %d",
- __func__, error);
- xfs_defer_cancel(&dfops);
- }
error = xfs_trans_commit(tp);
if (error)
xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
@@ -1868,7 +1831,6 @@ xfs_inactive(
xfs_inode_t *ip)
{
struct xfs_mount *mp;
- struct xfs_ifork *cow_ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
int error;
int truncate = 0;
@@ -1877,7 +1839,6 @@ xfs_inactive(
* to clean up here.
*/
if (VFS_I(ip)->i_mode == 0) {
- ASSERT(ip->i_df.if_real_bytes == 0);
ASSERT(ip->i_df.if_broot_bytes == 0);
return;
}
@@ -1890,7 +1851,7 @@ xfs_inactive(
return;
/* Try to clean out the cow blocks if there are any. */
- if (xfs_is_reflink_inode(ip) && cow_ifp->if_bytes > 0)
+ if (xfs_inode_has_cow_data(ip))
xfs_reflink_cancel_cow_range(ip, 0, NULLFILEOFF, true);
if (VFS_I(ip)->i_nlink != 0) {
@@ -2445,9 +2406,8 @@ xfs_ifree_local_data(
*/
int
xfs_ifree(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- struct xfs_defer_ops *dfops)
+ struct xfs_trans *tp,
+ struct xfs_inode *ip)
{
int error;
struct xfs_icluster xic = { 0 };
@@ -2466,7 +2426,7 @@ xfs_ifree(
if (error)
return error;
- error = xfs_difree(tp, ip->i_ino, dfops, &xic);
+ error = xfs_difree(tp, ip->i_ino, &xic);
if (error)
return error;
@@ -2577,8 +2537,6 @@ xfs_remove(
xfs_trans_t *tp = NULL;
int is_dir = S_ISDIR(VFS_I(ip)->i_mode);
int error = 0;
- struct xfs_defer_ops dfops;
- xfs_fsblock_t first_block;
uint resblks;
trace_xfs_remove(dp, name);
@@ -2658,13 +2616,10 @@ xfs_remove(
if (error)
goto out_trans_cancel;
- xfs_defer_init(&dfops, &first_block);
- tp->t_agfl_dfops = &dfops;
- error = xfs_dir_removename(tp, dp, name, ip->i_ino,
- &first_block, &dfops, resblks);
+ error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks);
if (error) {
ASSERT(error != -ENOENT);
- goto out_bmap_cancel;
+ goto out_trans_cancel;
}
/*
@@ -2675,10 +2630,6 @@ xfs_remove(
if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
xfs_trans_set_sync(tp);
- error = xfs_defer_finish(&tp, &dfops);
- if (error)
- goto out_bmap_cancel;
-
error = xfs_trans_commit(tp);
if (error)
goto std_return;
@@ -2688,8 +2639,6 @@ xfs_remove(
return 0;
- out_bmap_cancel:
- xfs_defer_cancel(&dfops);
out_trans_cancel:
xfs_trans_cancel(tp);
std_return:
@@ -2749,11 +2698,8 @@ xfs_sort_for_rename(
static int
xfs_finish_rename(
- struct xfs_trans *tp,
- struct xfs_defer_ops *dfops)
+ struct xfs_trans *tp)
{
- int error;
-
/*
* If this is a synchronous mount, make sure that the rename transaction
* goes to disk before returning to the user.
@@ -2761,13 +2707,6 @@ xfs_finish_rename(
if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
xfs_trans_set_sync(tp);
- error = xfs_defer_finish(&tp, dfops);
- if (error) {
- xfs_defer_cancel(dfops);
- xfs_trans_cancel(tp);
- return error;
- }
-
return xfs_trans_commit(tp);
}
@@ -2785,8 +2724,6 @@ xfs_cross_rename(
struct xfs_inode *dp2,
struct xfs_name *name2,
struct xfs_inode *ip2,
- struct xfs_defer_ops *dfops,
- xfs_fsblock_t *first_block,
int spaceres)
{
int error = 0;
@@ -2795,16 +2732,12 @@ xfs_cross_rename(
int dp2_flags = 0;
/* Swap inode number for dirent in first parent */
- error = xfs_dir_replace(tp, dp1, name1,
- ip2->i_ino,
- first_block, dfops, spaceres);
+ error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, spaceres);
if (error)
goto out_trans_abort;
/* Swap inode number for dirent in second parent */
- error = xfs_dir_replace(tp, dp2, name2,
- ip1->i_ino,
- first_block, dfops, spaceres);
+ error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, spaceres);
if (error)
goto out_trans_abort;
@@ -2818,8 +2751,7 @@ xfs_cross_rename(
if (S_ISDIR(VFS_I(ip2)->i_mode)) {
error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot,
- dp1->i_ino, first_block,
- dfops, spaceres);
+ dp1->i_ino, spaceres);
if (error)
goto out_trans_abort;
@@ -2845,8 +2777,7 @@ xfs_cross_rename(
if (S_ISDIR(VFS_I(ip1)->i_mode)) {
error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot,
- dp2->i_ino, first_block,
- dfops, spaceres);
+ dp2->i_ino, spaceres);
if (error)
goto out_trans_abort;
@@ -2885,10 +2816,9 @@ xfs_cross_rename(
}
xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
- return xfs_finish_rename(tp, dfops);
+ return xfs_finish_rename(tp);
out_trans_abort:
- xfs_defer_cancel(dfops);
xfs_trans_cancel(tp);
return error;
}
@@ -2943,8 +2873,6 @@ xfs_rename(
{
struct xfs_mount *mp = src_dp->i_mount;
struct xfs_trans *tp;
- struct xfs_defer_ops dfops;
- xfs_fsblock_t first_block;
struct xfs_inode *wip = NULL; /* whiteout inode */
struct xfs_inode *inodes[__XFS_SORT_INODES];
int num_inodes = __XFS_SORT_INODES;
@@ -3026,14 +2954,11 @@ xfs_rename(
goto out_trans_cancel;
}
- xfs_defer_init(&dfops, &first_block);
- tp->t_agfl_dfops = &dfops;
-
/* RENAME_EXCHANGE is unique from here on. */
if (flags & RENAME_EXCHANGE)
return xfs_cross_rename(tp, src_dp, src_name, src_ip,
target_dp, target_name, target_ip,
- &dfops, &first_block, spaceres);
+ spaceres);
/*
* Set up the target.
@@ -3054,10 +2979,9 @@ xfs_rename(
* to account for the ".." reference from the new entry.
*/
error = xfs_dir_createname(tp, target_dp, target_name,
- src_ip->i_ino, &first_block,
- &dfops, spaceres);
+ src_ip->i_ino, spaceres);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
xfs_trans_ichgtime(tp, target_dp,
XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -3065,7 +2989,7 @@ xfs_rename(
if (new_parent && src_is_directory) {
error = xfs_bumplink(tp, target_dp);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
}
} else { /* target_ip != NULL */
/*
@@ -3094,10 +3018,9 @@ xfs_rename(
* name at the destination directory, remove it first.
*/
error = xfs_dir_replace(tp, target_dp, target_name,
- src_ip->i_ino,
- &first_block, &dfops, spaceres);
+ src_ip->i_ino, spaceres);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
xfs_trans_ichgtime(tp, target_dp,
XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -3108,7 +3031,7 @@ xfs_rename(
*/
error = xfs_droplink(tp, target_ip);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
if (src_is_directory) {
/*
@@ -3116,7 +3039,7 @@ xfs_rename(
*/
error = xfs_droplink(tp, target_ip);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
}
} /* target_ip != NULL */
@@ -3129,11 +3052,10 @@ xfs_rename(
* directory.
*/
error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot,
- target_dp->i_ino,
- &first_block, &dfops, spaceres);
+ target_dp->i_ino, spaceres);
ASSERT(error != -EEXIST);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
}
/*
@@ -3159,7 +3081,7 @@ xfs_rename(
*/
error = xfs_droplink(tp, src_dp);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
}
/*
@@ -3169,12 +3091,12 @@ xfs_rename(
*/
if (wip) {
error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino,
- &first_block, &dfops, spaceres);
+ spaceres);
} else
error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
- &first_block, &dfops, spaceres);
+ spaceres);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
/*
* For whiteouts, we need to bump the link count on the whiteout inode.
@@ -3188,10 +3110,10 @@ xfs_rename(
ASSERT(VFS_I(wip)->i_nlink == 0);
error = xfs_bumplink(tp, wip);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
error = xfs_iunlink_remove(tp, wip);
if (error)
- goto out_bmap_cancel;
+ goto out_trans_cancel;
xfs_trans_log_inode(tp, wip, XFS_ILOG_CORE);
/*
@@ -3207,18 +3129,16 @@ xfs_rename(
if (new_parent)
xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
- error = xfs_finish_rename(tp, &dfops);
+ error = xfs_finish_rename(tp);
if (wip)
- IRELE(wip);
+ xfs_irele(wip);
return error;
-out_bmap_cancel:
- xfs_defer_cancel(&dfops);
out_trans_cancel:
xfs_trans_cancel(tp);
out_release_wip:
if (wip)
- IRELE(wip);
+ xfs_irele(wip);
return error;
}
@@ -3674,3 +3594,12 @@ xfs_iflush_int(
corrupt_out:
return -EFSCORRUPTED;
}
+
+/* Release an inode. */
+void
+xfs_irele(
+ struct xfs_inode *ip)
+{
+ trace_xfs_irele(ip, _RET_IP_);
+ iput(VFS_I(ip));
+}