summaryrefslogtreecommitdiffstats
path: root/module/zfs/dsl_synctask.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-05-28 13:45:14 -0700
committerBrian Behlendorf <[email protected]>2010-05-28 13:45:14 -0700
commit428870ff734fdaccc342b33fc53cf94724409a46 (patch)
tree164e83c0ceda52a843795ed7cd9e95637d02c177 /module/zfs/dsl_synctask.c
parent6119cb885a976e175a6e827894accf657ff1984f (diff)
Update core ZFS code from build 121 to build 141.
Diffstat (limited to 'module/zfs/dsl_synctask.c')
-rw-r--r--module/zfs/dsl_synctask.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/module/zfs/dsl_synctask.c b/module/zfs/dsl_synctask.c
index 21100225a..832685b0f 100644
--- a/module/zfs/dsl_synctask.c
+++ b/module/zfs/dsl_synctask.c
@@ -19,18 +19,15 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/dmu.h>
#include <sys/dmu_tx.h>
#include <sys/dsl_pool.h>
#include <sys/dsl_dir.h>
#include <sys/dsl_synctask.h>
-#include <sys/cred.h>
+#include <sys/metaslab.h>
#define DST_AVG_BLKSHIFT 14
@@ -50,7 +47,6 @@ dsl_sync_task_group_create(dsl_pool_t *dp)
list_create(&dstg->dstg_tasks, sizeof (dsl_sync_task_t),
offsetof(dsl_sync_task_t, dst_node));
dstg->dstg_pool = dp;
- dstg->dstg_cr = CRED();
return (dstg);
}
@@ -112,14 +108,21 @@ top:
return (dstg->dstg_err);
}
- VERIFY(0 == txg_list_add(&dstg->dstg_pool->dp_sync_tasks, dstg, txg));
+ /*
+ * We don't generally have many sync tasks, so pay the price of
+ * add_tail to get the tasks executed in the right order.
+ */
+ VERIFY(0 == txg_list_add_tail(&dstg->dstg_pool->dp_sync_tasks,
+ dstg, txg));
dmu_tx_commit(tx);
txg_wait_synced(dstg->dstg_pool, txg);
- if (dstg->dstg_err == EAGAIN)
+ if (dstg->dstg_err == EAGAIN) {
+ txg_wait_synced(dstg->dstg_pool, txg + TXG_DEFER_SIZE);
goto top;
+ }
return (dstg->dstg_err);
}
@@ -131,7 +134,12 @@ dsl_sync_task_group_nowait(dsl_sync_task_group_t *dstg, dmu_tx_t *tx)
dstg->dstg_nowaiter = B_TRUE;
txg = dmu_tx_get_txg(tx);
- VERIFY(0 == txg_list_add(&dstg->dstg_pool->dp_sync_tasks, dstg, txg));
+ /*
+ * We don't generally have many sync tasks, so pay the price of
+ * add_tail to get the tasks executed in the right order.
+ */
+ VERIFY(0 == txg_list_add_tail(&dstg->dstg_pool->dp_sync_tasks,
+ dstg, txg));
}
void
@@ -150,25 +158,30 @@ void
dsl_sync_task_group_sync(dsl_sync_task_group_t *dstg, dmu_tx_t *tx)
{
dsl_sync_task_t *dst;
- void *tr_cookie;
+ dsl_pool_t *dp = dstg->dstg_pool;
+ uint64_t quota, used;
ASSERT3U(dstg->dstg_err, ==, 0);
/*
- * Check for sufficient space.
+ * Check for sufficient space. We just check against what's
+ * on-disk; we don't want any in-flight accounting to get in our
+ * way, because open context may have already used up various
+ * in-core limits (arc_tempreserve, dsl_pool_tempreserve).
*/
- dstg->dstg_err = dsl_dir_tempreserve_space(dstg->dstg_pool->dp_mos_dir,
- dstg->dstg_space, dstg->dstg_space * 3, 0, 0, &tr_cookie, tx);
- /* don't bother trying again */
- if (dstg->dstg_err == ERESTART)
- dstg->dstg_err = EAGAIN;
- if (dstg->dstg_err)
+ quota = dsl_pool_adjustedsize(dp, B_FALSE) -
+ metaslab_class_get_deferred(spa_normal_class(dp->dp_spa));
+ used = dp->dp_root_dir->dd_phys->dd_used_bytes;
+ /* MOS space is triple-dittoed, so we multiply by 3. */
+ if (dstg->dstg_space > 0 && used + dstg->dstg_space * 3 > quota) {
+ dstg->dstg_err = ENOSPC;
return;
+ }
/*
* Check for errors by calling checkfuncs.
*/
- rw_enter(&dstg->dstg_pool->dp_config_rwlock, RW_WRITER);
+ rw_enter(&dp->dp_config_rwlock, RW_WRITER);
for (dst = list_head(&dstg->dstg_tasks); dst;
dst = list_next(&dstg->dstg_tasks, dst)) {
dst->dst_err =
@@ -183,13 +196,10 @@ dsl_sync_task_group_sync(dsl_sync_task_group_t *dstg, dmu_tx_t *tx)
*/
for (dst = list_head(&dstg->dstg_tasks); dst;
dst = list_next(&dstg->dstg_tasks, dst)) {
- dst->dst_syncfunc(dst->dst_arg1, dst->dst_arg2,
- dstg->dstg_cr, tx);
+ dst->dst_syncfunc(dst->dst_arg1, dst->dst_arg2, tx);
}
}
- rw_exit(&dstg->dstg_pool->dp_config_rwlock);
-
- dsl_dir_tempreserve_clear(tr_cookie, tx);
+ rw_exit(&dp->dp_config_rwlock);
if (dstg->dstg_nowaiter)
dsl_sync_task_group_destroy(dstg);