summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorperrin <none@none>2006-04-06 06:28:44 -0700
committerperrin <none@none>2006-04-06 06:28:44 -0700
commit7885c754e607231ad1f14c765820d601690b6258 (patch)
treeb3268dac543f45071c9d5ac55ed91d9a64552cbe /usr
parentdcd3dacad308865c548b11e858fbdec783ec2a72 (diff)
downloadillumos-gate-7885c754e607231ad1f14c765820d601690b6258.tar.gz
6405008 Reboot hung after a stress test
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index d6d40afb82..76e2069e63 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -91,7 +91,10 @@
* cached atime changes. Third, zfs_zinactive() may require a new tx,
* which could deadlock the system if you were already holding one.
*
- * (3) Always pass zfsvfs->z_assign as the second argument to dmu_tx_assign().
+ * (3) All range locks must be grabbed before calling dmu_tx_assign(),
+ * as they can span dmu_tx_assign() calls.
+ *
+ * (4) Always pass zfsvfs->z_assign as the second argument to dmu_tx_assign().
* In normal operation, this will be TXG_NOWAIT. During ZIL replay,
* it will be a specific txg. Either way, dmu_tx_assign() never blocks.
* This is critical because we don't want to block while holding locks.
@@ -107,14 +110,14 @@
* If dmu_tx_assign() returns ERESTART and zfsvfs->z_assign is TXG_NOWAIT,
* then drop all locks, call txg_wait_open(), and try again.
*
- * (4) If the operation succeeded, generate the intent log entry for it
+ * (5) If the operation succeeded, generate the intent log entry for it
* before dropping locks. This ensures that the ordering of events
* in the intent log matches the order in which they actually occurred.
*
- * (5) At the end of each vnode op, the DMU tx must always commit,
+ * (6) At the end of each vnode op, the DMU tx must always commit,
* regardless of whether there were any errors.
*
- * (6) After dropping all locks, invoke zil_commit(zilog, seq, ioflag)
+ * (7) After dropping all locks, invoke zil_commit(zilog, seq, ioflag)
* to ensure that synchronous semantics are provided when necessary.
*
* In general, this is how things should be ordered in each vnode op:
@@ -1161,9 +1164,12 @@ top:
tx = dmu_tx_create(os);
dmu_tx_hold_bonus(tx, zoid);
dmu_tx_hold_free(tx, zoid, 0, DMU_OBJECT_END);
+ /* Lock the whole range of the file */
+ rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER);
error = dmu_tx_assign(tx, zfsvfs->z_assign);
if (error) {
dmu_tx_abort(tx);
+ zfs_range_unlock(zp, rl);
if (dl)
zfs_dirent_unlock(dl);
VN_RELE(ZTOV(zp));
@@ -1175,10 +1181,6 @@ top:
ZFS_EXIT(zfsvfs);
return (error);
}
- /*
- * Lock the whole range of the file
- */
- rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER);
error = zfs_freesp(zp, 0, 0, mode, tx, cr);
if (error == 0) {
zfs_time_stamper(zp, CONTENT_MODIFIED, tx);