aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2017-02-07 18:57:50 -0500
committerBrian Behlendorf <[email protected]>2017-02-08 17:28:22 -0800
commitea7e86d8dbbfbaa96a3b018a80397cb24befcb72 (patch)
treea9edb551c5720add1f31540ab30cb81d543ec373 /module
parentd834b9ce5ba6be96ce13c31351cf92c89f7762fe (diff)
Fix iput() calls within a tx
As explicitly stated in section 2 of the 'Programming rules' comments at the top of zfs_vnops.c. If you must call iput() within a tx then use zfs_iput_async(). Move iput() calls after dmu_tx_commit() / dmu_tx_abort when possible. When not possible convert the iput() calls to zfs_iput_async(). Reviewed-by: Don Brady <[email protected]> Reviewed-by: Chunwei Chen <[email protected]> Reviewed-by: George Melikov <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #5758
Diffstat (limited to 'module')
-rw-r--r--module/zfs/zfs_vnops.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index b55445e0a..41572d34f 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -1778,18 +1778,21 @@ top:
error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
if (error) {
zfs_dirent_unlock(dl);
- iput(ip);
- if (xzp)
- iput(ZTOI(xzp));
if (error == ERESTART) {
waited = B_TRUE;
dmu_tx_wait(tx);
dmu_tx_abort(tx);
+ iput(ip);
+ if (xzp)
+ iput(ZTOI(xzp));
goto top;
}
if (realnmp)
pn_free(realnmp);
dmu_tx_abort(tx);
+ iput(ip);
+ if (xzp)
+ iput(ZTOI(xzp));
ZFS_EXIT(zsb);
return (error);
}
@@ -1847,8 +1850,6 @@ top:
*/
zfs_unlinked_add(zp, tx);
mutex_exit(&zp->z_lock);
- zfs_inode_update(zp);
- iput(ip);
} else if (unlinked) {
mutex_exit(&zp->z_lock);
zfs_unlinked_add(zp, tx);
@@ -1866,11 +1867,12 @@ out:
zfs_dirent_unlock(dl);
zfs_inode_update(dzp);
+ zfs_inode_update(zp);
- if (!delete_now) {
- zfs_inode_update(zp);
+ if (delete_now)
+ iput(ip);
+ else
zfs_iput_async(ip);
- }
if (xzp) {
zfs_inode_update(xzp);
@@ -2161,14 +2163,15 @@ top:
rw_exit(&zp->z_parent_lock);
rw_exit(&zp->z_name_lock);
zfs_dirent_unlock(dl);
- iput(ip);
if (error == ERESTART) {
waited = B_TRUE;
dmu_tx_wait(tx);
dmu_tx_abort(tx);
+ iput(ip);
goto top;
}
dmu_tx_abort(tx);
+ iput(ip);
ZFS_EXIT(zsb);
return (error);
}
@@ -3242,8 +3245,6 @@ out:
ASSERT(err2 == 0);
}
- if (attrzp)
- iput(ZTOI(attrzp));
if (aclp)
zfs_acl_free(aclp);
@@ -3254,11 +3255,15 @@ out:
if (err) {
dmu_tx_abort(tx);
+ if (attrzp)
+ iput(ZTOI(attrzp));
if (err == ERESTART)
goto top;
} else {
err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
dmu_tx_commit(tx);
+ if (attrzp)
+ iput(ZTOI(attrzp));
zfs_inode_update(zp);
}
@@ -3291,7 +3296,7 @@ zfs_rename_unlock(zfs_zlock_t **zlpp)
while ((zl = *zlpp) != NULL) {
if (zl->zl_znode != NULL)
- iput(ZTOI(zl->zl_znode));
+ zfs_iput_async(ZTOI(zl->zl_znode));
rw_exit(zl->zl_rwlock);
*zlpp = zl->zl_next;
kmem_free(zl, sizeof (*zl));
@@ -3636,16 +3641,19 @@ top:
if (sdzp == tdzp)
rw_exit(&sdzp->z_name_lock);
- iput(ZTOI(szp));
- if (tzp)
- iput(ZTOI(tzp));
if (error == ERESTART) {
waited = B_TRUE;
dmu_tx_wait(tx);
dmu_tx_abort(tx);
+ iput(ZTOI(szp));
+ if (tzp)
+ iput(ZTOI(tzp));
goto top;
}
dmu_tx_abort(tx);
+ iput(ZTOI(szp));
+ if (tzp)
+ iput(ZTOI(tzp));
ZFS_EXIT(zsb);
return (error);
}