diff options
author | Matthew Ahrens <[email protected]> | 2018-07-10 13:49:50 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-07-12 10:49:27 -0700 |
commit | 2e5dc449c1a65e0b0bf730fd69c9b5804bd57ee8 (patch) | |
tree | 8bbb44d8e88afa71ae1071c7a29369721711b0dd /module/zfs/zcp_iter.c | |
parent | e4e94ca3154a9e58ac20e5409c003895ec859964 (diff) |
OpenZFS 9337 - zfs get all is slow due to uncached metadata
This project's goal is to make read-heavy channel programs and zfs(1m)
administrative commands faster by caching all the metadata that they will
need in the dbuf layer. This will prevent the data from being evicted, so
that any future call to i.e. zfs get all won't have to go to disk (very
much). There are two parts:
The dbuf_metadata_cache. We identify what to put into the cache based on
the object type of each dbuf. Caching objset properties os
{version,normalization,utf8only,casesensitivity} in the objset_t. The reason
these needed to be cached is that although they are queried frequently,
they aren't stored in a dbuf type which we can easily recognize and cache in
the dbuf layer; instead, we have to explicitly store them. There's already
existing infrastructure for maintaining cached properties in the objset
setup code, so I simply used that.
Performance Testing:
- Disabled kmem_flags
- Tuned dbuf_cache_max_bytes very low (128K)
- Tuned zfs_arc_max very low (64M)
Created test pool with 400 filesystems, and 100 snapshots per filesystem.
Later on in testing, added 600 more filesystems (with no snapshots) to make
sure scaling didn't look different between snapshots and filesystems.
Results:
| Test | Time (trunk / diff) | I/Os (trunk / diff) |
+------------------------+---------------------+---------------------+
| zpool import | 0:05 / 0:06 | 12.9k / 12.9k |
| zfs get all (uncached) | 1:36 / 0:53 | 16.7k / 5.7k |
| zfs get all (cached) | 1:36 / 0:51 | 16.0k / 6.0k |
Authored by: Matthew Ahrens <[email protected]>
Reviewed by: Prakash Surya <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Thomas Caputi <[email protected]>
Reviewed by: Brian Behlendorf <[email protected]>
Approved by: Richard Lowe <[email protected]>
Ported-by: Alek Pinchuk <[email protected]>
Signed-off-by: Alek Pinchuk <[email protected]>
OpenZFS-issue: https://illumos.org/issues/9337
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/7dec52f
Closes #7668
Diffstat (limited to 'module/zfs/zcp_iter.c')
-rw-r--r-- | module/zfs/zcp_iter.c | 18 |
1 files changed, 3 insertions, 15 deletions
diff --git a/module/zfs/zcp_iter.c b/module/zfs/zcp_iter.c index d37172c88..f26445520 100644 --- a/module/zfs/zcp_iter.c +++ b/module/zfs/zcp_iter.c @@ -33,6 +33,8 @@ #include <sys/zcp.h> +#include "zfs_comutil.h" + typedef int (zcp_list_func_t)(lua_State *); typedef struct zcp_list_info { const char *name; @@ -232,20 +234,6 @@ zcp_snapshots_list(lua_State *state) return (1); } -/* - * Note: channel programs only run in the global zone, so all datasets - * are visible to this zone. - */ -static boolean_t -dataset_name_hidden(const char *name) -{ - if (strchr(name, '$') != NULL) - return (B_TRUE); - if (strchr(name, '%') != NULL) - return (B_TRUE); - return (B_FALSE); -} - static int zcp_children_iter(lua_State *state) { @@ -275,7 +263,7 @@ zcp_children_iter(lua_State *state) do { err = dmu_dir_list_next(os, sizeof (childname) - (p - childname), p, NULL, &cursor); - } while (err == 0 && dataset_name_hidden(childname)); + } while (err == 0 && zfs_dataset_name_hidden(childname)); dsl_dataset_rele(ds, FTAG); if (err == ENOENT) { |