diff options
author | Brian Behlendorf <[email protected]> | 2017-02-07 18:57:50 -0500 |
---|---|---|
committer | Tony Hutter <[email protected]> | 2017-06-09 14:05:15 -0700 |
commit | ebef1f2fb67c102f791c702386c6b8fe5bb8e9ae (patch) | |
tree | ba42bc68062109719c86b62e9e3a82304d6cdbd6 | |
parent | 00a1a11989a365a7672d99854d1a7fa6f0b36bf0 (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
-rw-r--r-- | module/zfs/zfs_vnops.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 384a37fea..437a63a63 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -1602,13 +1602,13 @@ 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; } #ifdef HAVE_PN_UTILS @@ -1616,6 +1616,9 @@ top: pn_free(realnmp); #endif /* HAVE_PN_UTILS */ dmu_tx_abort(tx); + iput(ip); + if (xzp) + iput(ZTOI(xzp)); ZFS_EXIT(zsb); return (error); } @@ -1944,14 +1947,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); } @@ -3025,8 +3029,6 @@ out: ASSERT(err2 == 0); } - if (attrzp) - iput(ZTOI(attrzp)); if (aclp) zfs_acl_free(aclp); @@ -3037,11 +3039,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); } @@ -3074,7 +3080,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)); @@ -3411,16 +3417,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); } |