Deleted Added
sdiff udiff text old ( 258632 ) new ( 258720 )
full compact
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 93 unchanged lines hidden (view full) ---

102 * pushing cached pages (which acquires range locks) and syncing out
103 * cached atime changes. Third, zfs_zinactive() may require a new tx,
104 * which could deadlock the system if you were already holding one.
105 * If you must call VN_RELE() within a tx then use VN_RELE_ASYNC().
106 *
107 * (3) All range locks must be grabbed before calling dmu_tx_assign(),
108 * as they can span dmu_tx_assign() calls.
109 *
110 * (4) Always pass TXG_NOWAIT as the second argument to dmu_tx_assign().
111 * This is critical because we don't want to block while holding locks.
112 * Note, in particular, that if a lock is sometimes acquired before
113 * the tx assigns, and sometimes after (e.g. z_lock), then failing to
114 * use a non-blocking assign can deadlock the system. The scenario:
115 *
116 * Thread A has grabbed a lock before calling dmu_tx_assign().
117 * Thread B is in an already-assigned tx, and blocks for this lock.
118 * Thread A calls dmu_tx_assign(TXG_WAIT) and blocks in txg_wait_open()
119 * forever, because the previous txg can't quiesce until B's tx commits.
120 *
121 * If dmu_tx_assign() returns ERESTART and zfsvfs->z_assign is TXG_NOWAIT,
122 * then drop all locks, call dmu_tx_wait(), and try again. On subsequent
123 * calls to dmu_tx_assign(), pass TXG_WAITED rather than TXG_NOWAIT,

--- 839 unchanged lines hidden (view full) ---

963 /*
964 * Write the file in reasonable size chunks. Each chunk is written
965 * in a separate transaction; this keeps the intent log records small
966 * and allows us to do more fine-grained space accounting.
967 */
968 while (n > 0) {
969 abuf = NULL;
970 woff = uio->uio_loffset;
971again:
972 if (zfs_owner_overquota(zfsvfs, zp, B_FALSE) ||
973 zfs_owner_overquota(zfsvfs, zp, B_TRUE)) {
974 if (abuf != NULL)
975 dmu_return_arcbuf(abuf);
976 error = SET_ERROR(EDQUOT);
977 break;
978 }
979

--- 35 unchanged lines hidden (view full) ---

1015
1016 /*
1017 * Start a transaction.
1018 */
1019 tx = dmu_tx_create(zfsvfs->z_os);
1020 dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
1021 dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz));
1022 zfs_sa_upgrade_txholds(tx, zp);
1023 error = dmu_tx_assign(tx, TXG_NOWAIT);
1024 if (error) {
1025 if (error == ERESTART) {
1026 dmu_tx_wait(tx);
1027 dmu_tx_abort(tx);
1028 goto again;
1029 }
1030 dmu_tx_abort(tx);
1031 if (abuf != NULL)
1032 dmu_return_arcbuf(abuf);
1033 break;
1034 }
1035
1036 /*
1037 * If zfs_range_lock() over-locked we grow the blocksize

--- 2367 unchanged lines hidden (view full) ---

3405 }
3406
3407 fuid_dirtied = zfsvfs->z_fuid_dirty;
3408 if (fuid_dirtied)
3409 zfs_fuid_txhold(zfsvfs, tx);
3410
3411 zfs_sa_upgrade_txholds(tx, zp);
3412
3413 err = dmu_tx_assign(tx, TXG_NOWAIT);
3414 if (err) {
3415 if (err == ERESTART)
3416 dmu_tx_wait(tx);
3417 goto out;
3418 }
3419
3420 count = 0;
3421 /*
3422 * Set each attribute requested.
3423 * We group settings according to the locks they need to acquire.
3424 *
3425 * Note: you cannot set ctime directly, although it will be
3426 * updated as a side-effect of calling this function.

--- 1096 unchanged lines hidden (view full) ---

4523 len = zp->z_size - off;
4524 }
4525
4526 if (zfs_owner_overquota(zfsvfs, zp, B_FALSE) ||
4527 zfs_owner_overquota(zfsvfs, zp, B_TRUE)) {
4528 err = SET_ERROR(EDQUOT);
4529 goto out;
4530 }
4531top:
4532 tx = dmu_tx_create(zfsvfs->z_os);
4533 dmu_tx_hold_write(tx, zp->z_id, off, len);
4534
4535 dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
4536 zfs_sa_upgrade_txholds(tx, zp);
4537 err = dmu_tx_assign(tx, TXG_NOWAIT);
4538 if (err != 0) {
4539 if (err == ERESTART) {
4540 dmu_tx_wait(tx);
4541 dmu_tx_abort(tx);
4542 goto top;
4543 }
4544 dmu_tx_abort(tx);
4545 goto out;
4546 }
4547
4548 if (zp->z_blksz <= PAGESIZE) {
4549 caddr_t va = zfs_map_page(pp, S_READ);
4550 ASSERT3U(len, <=, PAGESIZE);
4551 dmu_write(zfsvfs->z_os, zp->z_id, off, len, va, tx);

--- 2452 unchanged lines hidden ---