aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/module/zfs/dsl_dir.c
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2021-07-23 00:50:13 +0000
committerMartin Matuska <mm@FreeBSD.org>2021-07-23 00:50:13 +0000
commit3f9d360c82e0724bfb61346038236bf15c5d4d84 (patch)
treef21ca33e877b6bbba3f57f9b32a054f1793b841a /sys/contrib/openzfs/module/zfs/dsl_dir.c
parent95f0da5be1e3456c930f5f9538cbc099c65f2014 (diff)
parent14b43fbd9c13d802409ed886bb6b66fd528fb209 (diff)
downloadsrc-3f9d360c82e0724bfb61346038236bf15c5d4d84.tar.gz
src-3f9d360c82e0724bfb61346038236bf15c5d4d84.zip
zfs: merge openzfs/zfs@14b43fbd9 (master) into main
Notable upstream pull request merges: #12271 Tinker with slop space accounting with dedup #12279 Fix ARC ghost states eviction accounting #12284 Add Module Parameter Regarding Log Size Limit #12300 Introduce dsl_dir_diduse_transfer_space() #12314 Optimize allocation throttling #12348 Minor ARC optimizations #12350 Detect HAVE_LARGE_STACKS at compile time #12356 Use SET_ERROR for more errors in FreeBSD vnops #12375 FreeBSD: Ignore make_dev_s() errors #12378 FreeBSD: Switch from MAXPHYS to maxphys on FreeBSD 13+ Obtained from: OpenZFS OpenZFS commit: 14b43fbd9c13d802409ed886bb6b66fd528fb209
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/dsl_dir.c')
-rw-r--r--sys/contrib/openzfs/module/zfs/dsl_dir.c112
1 files changed, 79 insertions, 33 deletions
diff --git a/sys/contrib/openzfs/module/zfs/dsl_dir.c b/sys/contrib/openzfs/module/zfs/dsl_dir.c
index df2c3d8f0637..84caace4dbab 100644
--- a/sys/contrib/openzfs/module/zfs/dsl_dir.c
+++ b/sys/contrib/openzfs/module/zfs/dsl_dir.c
@@ -1517,6 +1517,11 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
{
int64_t accounted_delta;
+ ASSERT(dmu_tx_is_syncing(tx));
+ ASSERT(type < DD_USED_NUM);
+
+ dmu_buf_will_dirty(dd->dd_dbuf, tx);
+
/*
* dsl_dataset_set_refreservation_sync_impl() calls this with
* dd_lock held, so that it can atomically update
@@ -1525,36 +1530,28 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
* consistently.
*/
boolean_t needlock = !MUTEX_HELD(&dd->dd_lock);
-
- ASSERT(dmu_tx_is_syncing(tx));
- ASSERT(type < DD_USED_NUM);
-
- dmu_buf_will_dirty(dd->dd_dbuf, tx);
-
if (needlock)
mutex_enter(&dd->dd_lock);
- accounted_delta =
- parent_delta(dd, dsl_dir_phys(dd)->dd_used_bytes, used);
- ASSERT(used >= 0 || dsl_dir_phys(dd)->dd_used_bytes >= -used);
- ASSERT(compressed >= 0 ||
- dsl_dir_phys(dd)->dd_compressed_bytes >= -compressed);
+ dsl_dir_phys_t *ddp = dsl_dir_phys(dd);
+ accounted_delta = parent_delta(dd, ddp->dd_used_bytes, used);
+ ASSERT(used >= 0 || ddp->dd_used_bytes >= -used);
+ ASSERT(compressed >= 0 || ddp->dd_compressed_bytes >= -compressed);
ASSERT(uncompressed >= 0 ||
- dsl_dir_phys(dd)->dd_uncompressed_bytes >= -uncompressed);
- dsl_dir_phys(dd)->dd_used_bytes += used;
- dsl_dir_phys(dd)->dd_uncompressed_bytes += uncompressed;
- dsl_dir_phys(dd)->dd_compressed_bytes += compressed;
-
- if (dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN) {
- ASSERT(used > 0 ||
- dsl_dir_phys(dd)->dd_used_breakdown[type] >= -used);
- dsl_dir_phys(dd)->dd_used_breakdown[type] += used;
+ ddp->dd_uncompressed_bytes >= -uncompressed);
+ ddp->dd_used_bytes += used;
+ ddp->dd_uncompressed_bytes += uncompressed;
+ ddp->dd_compressed_bytes += compressed;
+
+ if (ddp->dd_flags & DD_FLAG_USED_BREAKDOWN) {
+ ASSERT(used >= 0 || ddp->dd_used_breakdown[type] >= -used);
+ ddp->dd_used_breakdown[type] += used;
#ifdef ZFS_DEBUG
{
dd_used_t t;
uint64_t u = 0;
for (t = 0; t < DD_USED_NUM; t++)
- u += dsl_dir_phys(dd)->dd_used_breakdown[t];
- ASSERT3U(u, ==, dsl_dir_phys(dd)->dd_used_bytes);
+ u += ddp->dd_used_breakdown[t];
+ ASSERT3U(u, ==, ddp->dd_used_bytes);
}
#endif
}
@@ -1562,11 +1559,9 @@ dsl_dir_diduse_space(dsl_dir_t *dd, dd_used_t type,
mutex_exit(&dd->dd_lock);
if (dd->dd_parent != NULL) {
- dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD,
- accounted_delta, compressed, uncompressed, tx);
- dsl_dir_transfer_space(dd->dd_parent,
- used - accounted_delta,
- DD_USED_CHILD_RSRV, DD_USED_CHILD, tx);
+ dsl_dir_diduse_transfer_space(dd->dd_parent,
+ accounted_delta, compressed, uncompressed,
+ used, DD_USED_CHILD_RSRV, DD_USED_CHILD, tx);
}
}
@@ -1578,21 +1573,72 @@ dsl_dir_transfer_space(dsl_dir_t *dd, int64_t delta,
ASSERT(oldtype < DD_USED_NUM);
ASSERT(newtype < DD_USED_NUM);
+ dsl_dir_phys_t *ddp = dsl_dir_phys(dd);
if (delta == 0 ||
- !(dsl_dir_phys(dd)->dd_flags & DD_FLAG_USED_BREAKDOWN))
+ !(ddp->dd_flags & DD_FLAG_USED_BREAKDOWN))
return;
dmu_buf_will_dirty(dd->dd_dbuf, tx);
mutex_enter(&dd->dd_lock);
ASSERT(delta > 0 ?
- dsl_dir_phys(dd)->dd_used_breakdown[oldtype] >= delta :
- dsl_dir_phys(dd)->dd_used_breakdown[newtype] >= -delta);
- ASSERT(dsl_dir_phys(dd)->dd_used_bytes >= ABS(delta));
- dsl_dir_phys(dd)->dd_used_breakdown[oldtype] -= delta;
- dsl_dir_phys(dd)->dd_used_breakdown[newtype] += delta;
+ ddp->dd_used_breakdown[oldtype] >= delta :
+ ddp->dd_used_breakdown[newtype] >= -delta);
+ ASSERT(ddp->dd_used_bytes >= ABS(delta));
+ ddp->dd_used_breakdown[oldtype] -= delta;
+ ddp->dd_used_breakdown[newtype] += delta;
mutex_exit(&dd->dd_lock);
}
+void
+dsl_dir_diduse_transfer_space(dsl_dir_t *dd, int64_t used,
+ int64_t compressed, int64_t uncompressed, int64_t tonew,
+ dd_used_t oldtype, dd_used_t newtype, dmu_tx_t *tx)
+{
+ int64_t accounted_delta;
+
+ ASSERT(dmu_tx_is_syncing(tx));
+ ASSERT(oldtype < DD_USED_NUM);
+ ASSERT(newtype < DD_USED_NUM);
+
+ dmu_buf_will_dirty(dd->dd_dbuf, tx);
+
+ mutex_enter(&dd->dd_lock);
+ dsl_dir_phys_t *ddp = dsl_dir_phys(dd);
+ accounted_delta = parent_delta(dd, ddp->dd_used_bytes, used);
+ ASSERT(used >= 0 || ddp->dd_used_bytes >= -used);
+ ASSERT(compressed >= 0 || ddp->dd_compressed_bytes >= -compressed);
+ ASSERT(uncompressed >= 0 ||
+ ddp->dd_uncompressed_bytes >= -uncompressed);
+ ddp->dd_used_bytes += used;
+ ddp->dd_uncompressed_bytes += uncompressed;
+ ddp->dd_compressed_bytes += compressed;
+
+ if (ddp->dd_flags & DD_FLAG_USED_BREAKDOWN) {
+ ASSERT(tonew - used <= 0 ||
+ ddp->dd_used_breakdown[oldtype] >= tonew - used);
+ ASSERT(tonew >= 0 ||
+ ddp->dd_used_breakdown[newtype] >= -tonew);
+ ddp->dd_used_breakdown[oldtype] -= tonew - used;
+ ddp->dd_used_breakdown[newtype] += tonew;
+#ifdef ZFS_DEBUG
+ {
+ dd_used_t t;
+ uint64_t u = 0;
+ for (t = 0; t < DD_USED_NUM; t++)
+ u += ddp->dd_used_breakdown[t];
+ ASSERT3U(u, ==, ddp->dd_used_bytes);
+ }
+#endif
+ }
+ mutex_exit(&dd->dd_lock);
+
+ if (dd->dd_parent != NULL) {
+ dsl_dir_diduse_transfer_space(dd->dd_parent,
+ accounted_delta, compressed, uncompressed,
+ used, DD_USED_CHILD_RSRV, DD_USED_CHILD, tx);
+ }
+}
+
typedef struct dsl_dir_set_qr_arg {
const char *ddsqra_name;
zprop_source_t ddsqra_source;