diff --git a/cmd/raidz_test/raidz_test.c b/cmd/raidz_test/raidz_test.c index 1ece55960d33..34f3f6f1ccc6 100644 --- a/cmd/raidz_test/raidz_test.c +++ b/cmd/raidz_test/raidz_test.c @@ -146,8 +146,6 @@ static void process_options(int argc, char **argv) memcpy(o, &rto_opts_defaults, sizeof (*o)); while ((opt = getopt(argc, argv, "TDBSvha:er:o:d:s:t:")) != -1) { - value = 0; - switch (opt) { case 'a': value = strtoull(optarg, NULL, 0); diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 2ab3eaf3cab8..286f5bebbd43 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -134,7 +134,7 @@ uint8_t dump_opt[256]; typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size); -uint64_t *zopt_metaslab = NULL; +static uint64_t *zopt_metaslab = NULL; static unsigned zopt_metaslab_args = 0; typedef struct zopt_object_range { @@ -142,7 +142,8 @@ typedef struct zopt_object_range { uint64_t zor_obj_end; uint64_t zor_flags; } zopt_object_range_t; -zopt_object_range_t *zopt_object_ranges = NULL; + +static zopt_object_range_t *zopt_object_ranges = NULL; static unsigned zopt_object_args = 0; static int flagbits[256]; @@ -166,7 +167,7 @@ static int flagbits[256]; #define ZDB_FLAG_PRINT_BLKPTR 0x0040 #define ZDB_FLAG_VERBOSE 0x0080 -uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */ +static uint64_t max_inflight_bytes = 256 * 1024 * 1024; /* 256MB */ static int leaked_objects = 0; static range_tree_t *mos_refd_objs; static int objstore = 0; @@ -3095,7 +3096,7 @@ open_objset(const char *path, const void *tag, objset_t **osp) } sa_os = *osp; - return (0); + return (err); } static void diff --git a/cmd/zed/agents/fmd_api.c b/cmd/zed/agents/fmd_api.c index 56c134b731b8..6858da5e7cf1 100644 --- a/cmd/zed/agents/fmd_api.c +++ b/cmd/zed/agents/fmd_api.c @@ -616,6 +616,7 @@ fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta) sev.sigev_notify_function = _timer_notify; sev.sigev_notify_attributes = NULL; sev.sigev_value.sival_ptr = ftp; + sev.sigev_signo = 0; timer_create(CLOCK_REALTIME, &sev, &ftp->ft_tid); timer_settime(ftp->ft_tid, 0, &its, NULL); diff --git a/cmd/zed/agents/zfs_mod.c b/cmd/zed/agents/zfs_mod.c index e149c27ee025..44abb4eb9a34 100644 --- a/cmd/zed/agents/zfs_mod.c +++ b/cmd/zed/agents/zfs_mod.c @@ -1135,6 +1135,7 @@ zfs_deliver_dle(nvlist_t *nvl) strlcpy(name, devname, MAXPATHLEN); zfs_append_partition(name, MAXPATHLEN); } else { + sprintf(name, "unknown"); zed_log_msg(LOG_INFO, "zfs_deliver_dle: no guid or physpath"); } diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 10a576f706cb..751aae1cce54 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -1454,8 +1454,13 @@ destroy_callback(zfs_handle_t *zhp, void *data) if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { cb->cb_snap_count++; fnvlist_add_boolean(cb->cb_batchedsnaps, name); - if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy) + if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy) { error = destroy_batched(cb); + if (error != 0) { + zfs_close(zhp); + return (-1); + } + } } else { error = destroy_batched(cb); if (error != 0 || @@ -2577,7 +2582,7 @@ zfs_do_upgrade(int argc, char **argv) cb.cb_foundone = B_FALSE; cb.cb_newer = B_TRUE; - ret = zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM, + ret |= zfs_for_each(0, NULL, flags, ZFS_TYPE_FILESYSTEM, NULL, NULL, 0, upgrade_list_callback, &cb); if (!cb.cb_foundone && !found) { @@ -4500,6 +4505,7 @@ zfs_do_send(int argc, char **argv) gettext("missing argument for '%s' " "option\n"), argv[optind - 1]); } + free(excludes.list); usage(B_FALSE); break; case '?': @@ -4518,6 +4524,7 @@ zfs_do_send(int argc, char **argv) argv[optind - 1]); } + free(excludes.list); usage(B_FALSE); } } @@ -4526,6 +4533,7 @@ zfs_do_send(int argc, char **argv) flags.verbosity = 1; if (excludes.count > 0 && !flags.replicate) { + free(excludes.list); (void) fprintf(stderr, gettext("Cannot specify " "dataset exclusion (-X) on a non-recursive " "send.\n")); @@ -4539,21 +4547,25 @@ zfs_do_send(int argc, char **argv) if (fromname != NULL || flags.replicate || flags.props || flags.backup || flags.holds || flags.saved || redactbook != NULL) { + free(excludes.list); (void) fprintf(stderr, gettext("invalid flags combined with -t\n")); usage(B_FALSE); } if (argc > 0) { + free(excludes.list); (void) fprintf(stderr, gettext("too many arguments\n")); usage(B_FALSE); } } else { if (argc < 1) { + free(excludes.list); (void) fprintf(stderr, gettext("missing snapshot argument\n")); usage(B_FALSE); } if (argc > 1) { + free(excludes.list); (void) fprintf(stderr, gettext("too many arguments\n")); usage(B_FALSE); } @@ -4564,11 +4576,15 @@ zfs_do_send(int argc, char **argv) flags.doall || flags.backup || flags.holds || flags.largeblock || flags.embed_data || flags.compress || flags.raw || redactbook != NULL) { + free(excludes.list); + (void) fprintf(stderr, gettext("incompatible flags " "combined with saved send flag\n")); usage(B_FALSE); } if (strchr(argv[0], '@') != NULL) { + free(excludes.list); + (void) fprintf(stderr, gettext("saved send must " "specify the dataset with partially-received " "state\n")); @@ -4577,12 +4593,14 @@ zfs_do_send(int argc, char **argv) } if (flags.raw && redactbook != NULL) { + free(excludes.list); (void) fprintf(stderr, gettext("Error: raw sends may not be redacted.\n")); return (1); } if (!flags.dryrun && isatty(STDOUT_FILENO)) { + free(excludes.list); (void) fprintf(stderr, gettext("Error: Stream can not be written to a terminal.\n" "You must redirect standard output.\n")); @@ -4591,19 +4609,24 @@ zfs_do_send(int argc, char **argv) if (flags.saved) { zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET); - if (zhp == NULL) + if (zhp == NULL) { + free(excludes.list); return (1); + } err = zfs_send_saved(zhp, &flags, STDOUT_FILENO, resume_token); + free(excludes.list); zfs_close(zhp); return (err != 0); } else if (resume_token != NULL) { + free(excludes.list); return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO, resume_token)); } if (flags.skipmissing && !flags.replicate) { + free(excludes.list); (void) fprintf(stderr, gettext("skip-missing flag can only be used in " "conjunction with replicate\n")); @@ -4646,10 +4669,14 @@ zfs_do_send(int argc, char **argv) } zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET); - if (zhp == NULL) + if (zhp == NULL) { + free(excludes.list); return (1); + } err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags, redactbook); + + free(excludes.list); zfs_close(zhp); return (err != 0); } @@ -4658,25 +4685,30 @@ zfs_do_send(int argc, char **argv) (void) fprintf(stderr, gettext("Error: multiple snapshots cannot be " "sent from a bookmark.\n")); + free(excludes.list); return (1); } if (redactbook != NULL) { (void) fprintf(stderr, gettext("Error: multiple snapshots " "cannot be sent redacted.\n")); + free(excludes.list); return (1); } if ((cp = strchr(argv[0], '@')) == NULL) { (void) fprintf(stderr, gettext("Error: " "Unsupported flag with filesystem or bookmark.\n")); + free(excludes.list); return (1); } *cp = '\0'; toname = cp + 1; zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); - if (zhp == NULL) + if (zhp == NULL) { + free(excludes.list); return (1); + } /* * If they specified the full path to the snapshot, chop off @@ -4696,6 +4728,8 @@ zfs_do_send(int argc, char **argv) } else { *cp = '\0'; if (cp != fromname && strcmp(argv[0], fromname)) { + zfs_close(zhp); + free(excludes.list); (void) fprintf(stderr, gettext("incremental source must be " "in same filesystem\n")); @@ -4703,6 +4737,8 @@ zfs_do_send(int argc, char **argv) } fromname = cp + 1; if (strchr(fromname, '@') || strchr(fromname, '/')) { + zfs_close(zhp); + free(excludes.list); (void) fprintf(stderr, gettext("invalid incremental source\n")); usage(B_FALSE); @@ -8519,7 +8555,7 @@ static int zfs_do_wait(int argc, char **argv) { boolean_t enabled[ZFS_WAIT_NUM_ACTIVITIES]; - int error, i; + int error = 0, i; int c; /* By default, wait for all types of activity. */ diff --git a/cmd/zstream/zstream_decompress.c b/cmd/zstream/zstream_decompress.c index 31d4b2d36982..e5527777bca3 100644 --- a/cmd/zstream/zstream_decompress.c +++ b/cmd/zstream/zstream_decompress.c @@ -115,7 +115,9 @@ zstream_do_decompress(int argc, char *argv[]) if (errno || *end != '\0') errx(1, "invalid value for offset"); if (argv[i]) { - if (0 == strcmp("lz4", argv[i])) + if (0 == strcmp("off", argv[i])) + type = ZIO_COMPRESS_OFF; + else if (0 == strcmp("lz4", argv[i])) type = ZIO_COMPRESS_LZ4; else if (0 == strcmp("lzjb", argv[i])) type = ZIO_COMPRESS_LZJB; @@ -127,8 +129,8 @@ zstream_do_decompress(int argc, char *argv[]) type = ZIO_COMPRESS_ZSTD; else { fprintf(stderr, "Invalid compression type %s.\n" - "Supported types are lz4, lzjb, gzip, zle, " - "and zstd\n", + "Supported types are off, lz4, lzjb, gzip, " + "zle, and zstd\n", argv[i]); exit(2); } @@ -240,6 +242,9 @@ zstream_do_decompress(int argc, char *argv[]) if (p != NULL) { zio_decompress_func_t *xfunc = NULL; switch ((enum zio_compress)(intptr_t)p->data) { + case ZIO_COMPRESS_OFF: + xfunc = NULL; + break; case ZIO_COMPRESS_LZJB: xfunc = lzjb_decompress; break; @@ -258,7 +263,6 @@ zstream_do_decompress(int argc, char *argv[]) default: assert(B_FALSE); } - assert(xfunc != NULL); /* @@ -266,12 +270,27 @@ zstream_do_decompress(int argc, char *argv[]) */ char *lzbuf = safe_calloc(payload_size); (void) sfread(lzbuf, payload_size, stdin); - if (0 != xfunc(lzbuf, buf, + if (xfunc == NULL) { + memcpy(buf, lzbuf, payload_size); + drrw->drr_compressiontype = + ZIO_COMPRESS_OFF; + if (verbose) + fprintf(stderr, "Resetting " + "compression type to off " + "for ino %llu offset " + "%llu\n", + (u_longlong_t) + drrw->drr_object, + (u_longlong_t) + drrw->drr_offset); + } else if (0 != xfunc(lzbuf, buf, payload_size, payload_size, 0)) { /* * The block must not be compressed, - * possibly because it gets written - * multiple times in this stream. + * at least not with this compression + * type, possibly because it gets + * written multiple times in this + * stream. */ warnx("decompression failed for " "ino %llu offset %llu", @@ -279,11 +298,16 @@ zstream_do_decompress(int argc, char *argv[]) (u_longlong_t)drrw->drr_offset); memcpy(buf, lzbuf, payload_size); } else if (verbose) { + drrw->drr_compressiontype = + ZIO_COMPRESS_OFF; fprintf(stderr, "successfully " "decompressed ino %llu " "offset %llu\n", (u_longlong_t)drrw->drr_object, (u_longlong_t)drrw->drr_offset); + } else { + drrw->drr_compressiontype = + ZIO_COMPRESS_OFF; } free(lzbuf); } else { diff --git a/cmd/zstream/zstream_dump.c b/cmd/zstream/zstream_dump.c index 4b562c237373..9955a1361e8d 100644 --- a/cmd/zstream/zstream_dump.c +++ b/cmd/zstream/zstream_dump.c @@ -54,10 +54,10 @@ */ #define DUMP_GROUPING 4 -uint64_t total_stream_len = 0; -FILE *send_stream = 0; -boolean_t do_byteswap = B_FALSE; -boolean_t do_cksum = B_TRUE; +static uint64_t total_stream_len = 0; +static FILE *send_stream = 0; +static boolean_t do_byteswap = B_FALSE; +static boolean_t do_cksum = B_TRUE; void * safe_malloc(size_t size) diff --git a/cmd/ztest.c b/cmd/ztest.c index 4023f0efc8e5..470a35ab68e9 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -272,7 +272,7 @@ static const ztest_shared_opts_t ztest_opts_defaults = { extern uint64_t metaslab_force_ganging; extern uint64_t metaslab_df_alloc_threshold; -extern unsigned long zfs_deadman_synctime_ms; +extern uint64_t zfs_deadman_synctime_ms; extern uint_t metaslab_preload_limit; extern int zfs_compressed_arc_enabled; extern int zfs_abd_scatter_enabled; @@ -443,11 +443,11 @@ ztest_func_t ztest_fletcher; ztest_func_t ztest_fletcher_incr; ztest_func_t ztest_verify_dnode_bt; -uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */ -uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */ -uint64_t zopt_often = 1ULL * NANOSEC; /* every second */ -uint64_t zopt_sometimes = 10ULL * NANOSEC; /* every 10 seconds */ -uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */ +static uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */ +static uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */ +static uint64_t zopt_often = 1ULL * NANOSEC; /* every second */ +static uint64_t zopt_sometimes = 10ULL * NANOSEC; /* every 10 seconds */ +static uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */ #define ZTI_INIT(func, iters, interval) \ { .zi_func = (func), \ @@ -455,7 +455,7 @@ uint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */ .zi_interval = (interval), \ .zi_funcname = # func } -ztest_info_t ztest_info[] = { +static ztest_info_t ztest_info[] = { ZTI_INIT(ztest_dmu_read_write, 1, &zopt_always), ZTI_INIT(ztest_dmu_write_parallel, 10, &zopt_always), ZTI_INIT(ztest_dmu_object_alloc_free, 1, &zopt_always), @@ -535,7 +535,7 @@ typedef struct ztest_shared { static char ztest_dev_template[] = "%s/%s.%llua"; static char ztest_aux_template[] = "%s/%s.%s.%llu"; -ztest_shared_t *ztest_shared; +static ztest_shared_t *ztest_shared; static spa_t *ztest_spa = NULL; static ztest_ds_t *ztest_ds; @@ -2467,7 +2467,7 @@ ztest_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) return (0); } -zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = { +static zil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = { NULL, /* 0 no such transaction type */ ztest_replay_create, /* TX_CREATE */ NULL, /* TX_MKDIR */ @@ -7322,9 +7322,9 @@ ztest_deadman_thread(void *arg) */ if (spa_suspended(spa) || spa->spa_root_vdev == NULL) { fatal(B_FALSE, - "aborting test after %lu seconds because " + "aborting test after %llu seconds because " "pool has transitioned to a suspended state.", - zfs_deadman_synctime_ms / 1000); + (u_longlong_t)zfs_deadman_synctime_ms / 1000); } vdev_deadman(spa->spa_root_vdev, FTAG); diff --git a/config/kernel-idmap_mnt_api.m4 b/config/kernel-idmap_mnt_api.m4 new file mode 100644 index 000000000000..47ddc5702fb7 --- /dev/null +++ b/config/kernel-idmap_mnt_api.m4 @@ -0,0 +1,25 @@ +dnl # +dnl # 5.12 API +dnl # +dnl # Check if APIs for idmapped mount are available +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_IDMAP_MNT_API], [ + ZFS_LINUX_TEST_SRC([idmap_mnt_api], [ + #include + ],[ + int fs_flags = 0; + fs_flags |= FS_ALLOW_IDMAP; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_IDMAP_MNT_API], [ + AC_MSG_CHECKING([whether APIs for idmapped mount are present]) + ZFS_LINUX_TEST_RESULT([idmap_mnt_api], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_IDMAP_MNT_API, 1, + [APIs for idmapped mount are present]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) + diff --git a/config/kernel-mod-param.m4 b/config/kernel-mod-param.m4 deleted file mode 100644 index e00f19d61e7d..000000000000 --- a/config/kernel-mod-param.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl # -dnl # Grsecurity kernel API change -dnl # constified parameters of module_param_call() methods -dnl # -AC_DEFUN([ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST], [ - ZFS_LINUX_TEST_SRC([module_param_call], [ - #include - #include - - int param_get(char *b, const struct kernel_param *kp) - { - return (0); - } - - int param_set(const char *b, const struct kernel_param *kp) - { - return (0); - } - - module_param_call(p, param_set, param_get, NULL, 0644); - ],[]) -]) - -AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [ - AC_MSG_CHECKING([whether module_param_call() is hardened]) - ZFS_LINUX_TEST_RESULT([module_param_call], [ - AC_MSG_RESULT(yes) - AC_DEFINE(MODULE_PARAM_CALL_CONST, 1, - [hardened module_param_call]) - ],[ - AC_MSG_RESULT(no) - ]) -]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 6aad2cf88e02..d4d13ddd1d1a 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -122,7 +122,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_FMODE_T ZFS_AC_KERNEL_SRC_KUIDGID_T ZFS_AC_KERNEL_SRC_KUID_HELPERS - ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST ZFS_AC_KERNEL_SRC_RENAME ZFS_AC_KERNEL_SRC_CURRENT_TIME ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES @@ -148,6 +147,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_ZERO_PAGE ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC ZFS_AC_KERNEL_SRC_USER_NS_COMMON_INUM + ZFS_AC_KERNEL_SRC_IDMAP_MNT_API AC_MSG_CHECKING([for available kernel interfaces]) ZFS_LINUX_TEST_COMPILE_ALL([kabi]) @@ -243,7 +243,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_FMODE_T ZFS_AC_KERNEL_KUIDGID_T ZFS_AC_KERNEL_KUID_HELPERS - ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST ZFS_AC_KERNEL_RENAME ZFS_AC_KERNEL_CURRENT_TIME ZFS_AC_KERNEL_USERNS_CAPABILITIES @@ -269,6 +268,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_ZERO_PAGE ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC ZFS_AC_KERNEL_USER_NS_COMMON_INUM + ZFS_AC_KERNEL_IDMAP_MNT_API ]) dnl # @@ -942,8 +942,15 @@ dnl # like ZFS_LINUX_TRY_COMPILE, except the contents conftest.h are dnl # provided via the fifth parameter dnl # AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [ - ZFS_LINUX_COMPILE_IFELSE( - [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]], [[ZFS_META_LICENSE]])], - [test -f build/conftest/conftest.ko], - [$3], [$4], [$5]) + AS_IF([test "x$enable_linux_builtin" = "xyes"], [ + ZFS_LINUX_COMPILE_IFELSE( + [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]], + [[ZFS_META_LICENSE]])], + [test -f build/conftest/conftest.o], [$3], [$4], [$5]) + ], [ + ZFS_LINUX_COMPILE_IFELSE( + [ZFS_LINUX_TEST_PROGRAM([[$1]], [[$2]], + [[ZFS_META_LICENSE]])], + [test -f build/conftest/conftest.ko], [$3], [$4], [$5]) + ]) ]) diff --git a/contrib/coverity/model.c b/contrib/coverity/model.c index 8baa3a7e2d31..8e3e83cada19 100644 --- a/contrib/coverity/model.c +++ b/contrib/coverity/model.c @@ -29,11 +29,20 @@ #define NULL (0) +typedef enum { + B_FALSE = 0, + B_TRUE = 1 +} boolean_t; + +typedef unsigned int uint_t; + int condition0, condition1; int ddi_copyin(const void *from, void *to, size_t len, int flags) { + (void) flags; + __coverity_negative_sink__(len); __coverity_tainted_data_argument__(from); __coverity_tainted_data_argument__(to); __coverity_writeall__(to); @@ -42,13 +51,21 @@ ddi_copyin(const void *from, void *to, size_t len, int flags) void * memset(void *dst, int c, size_t len) { - __coverity_writeall__(dst); + __coverity_negative_sink__(len); + if (c == 0) + __coverity_writeall0__(dst); + else + __coverity_writeall__(dst); return (dst); } void * memmove(void *dst, void *src, size_t len) { + int first = ((char *)src)[0]; + int last = ((char *)src)[len-1]; + + __coverity_negative_sink__(len); __coverity_writeall__(dst); return (dst); } @@ -56,6 +73,10 @@ memmove(void *dst, void *src, size_t len) void * memcpy(void *dst, void *src, size_t len) { + int first = ((char *)src)[0]; + int last = ((char *)src)[len-1]; + + __coverity_negative_sink__(len); __coverity_writeall__(dst); return (dst); } @@ -63,43 +84,53 @@ memcpy(void *dst, void *src, size_t len) void * umem_alloc_aligned(size_t size, size_t align, int kmflags) { - (void) align; + __coverity_negative_sink__(size); + __coverity_negative_sink__(align); - if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) - return (__coverity_alloc__(size)); - else if (condition0) - return (__coverity_alloc__(size)); - else - return (NULL); + if (((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) || condition0) { + void *buf = __coverity_alloc__(size); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "umem_free"); + return (buf); + } + + return (NULL); } void * umem_alloc(size_t size, int kmflags) { - if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) - return (__coverity_alloc__(size)); - else if (condition0) - return (__coverity_alloc__(size)); - else - return (NULL); + __coverity_negative_sink__(size); + + if (((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) || condition0) { + void *buf = __coverity_alloc__(size); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "umem_free"); + return (buf); + } + + return (NULL); } void * umem_zalloc(size_t size, int kmflags) { - if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) - return (__coverity_alloc__(size)); - else if (condition0) - return (__coverity_alloc__(size)); - else - return (NULL); + __coverity_negative_sink__(size); + + if (((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL) || condition0) { + void *buf = __coverity_alloc__(size); + __coverity_writeall0__(buf); + __coverity_mark_as_afm_allocated__(buf, "umem_free"); + return (buf); + } + + return (NULL); } void umem_free(void *buf, size_t size) { - (void) size; - + __coverity_negative_sink__(size); __coverity_free__(buf); } @@ -113,12 +144,14 @@ umem_cache_alloc(umem_cache_t *skc, int flags) if (condition1) __coverity_sleep__(); - if ((UMEM_NOFAIL & flags) == UMEM_NOFAIL) - return (__coverity_alloc_nosize__()); - else if (condition0) - return (__coverity_alloc_nosize__()); - else - return (NULL); + if (((UMEM_NOFAIL & flags) == UMEM_NOFAIL) || condition0) { + void *buf = __coverity_alloc_nosize__(); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "umem_cache_free"); + return (buf); + } + + return (NULL); } void @@ -135,15 +168,19 @@ spl_kmem_alloc(size_t sz, int fl, const char *func, int line) (void) func; (void) line; + __coverity_negative_sink__(sz); + if (condition1) __coverity_sleep__(); - if (fl == 0) { - return (__coverity_alloc__(sz)); - } else if (condition0) - return (__coverity_alloc__(sz)); - else - return (NULL); + if ((fl == 0) || condition0) { + void *buf = __coverity_alloc__(sz); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "spl_kmem_free"); + return (buf); + } + + return (NULL); } void * @@ -152,22 +189,126 @@ spl_kmem_zalloc(size_t sz, int fl, const char *func, int line) (void) func; (void) line; + __coverity_negative_sink__(sz); + if (condition1) __coverity_sleep__(); - if (fl == 0) { - return (__coverity_alloc__(sz)); - } else if (condition0) - return (__coverity_alloc__(sz)); - else - return (NULL); + if ((fl == 0) || condition0) { + void *buf = __coverity_alloc__(sz); + __coverity_writeall0__(buf); + __coverity_mark_as_afm_allocated__(buf, "spl_kmem_free"); + return (buf); + } + + return (NULL); } void spl_kmem_free(const void *ptr, size_t sz) { - (void) sz; + __coverity_negative_sink__(sz); + __coverity_free__(ptr); +} + +char * +kmem_vasprintf(const char *fmt, va_list ap) +{ + char *buf = __coverity_alloc_nosize__(); + (void) ap; + + __coverity_string_null_sink__(fmt); + __coverity_string_size_sink__(fmt); + + __coverity_writeall__(buf); + + __coverity_mark_as_afm_allocated__(buf, "kmem_strfree"); + + return (buf); +} + +char * +kmem_asprintf(const char *fmt, ...) +{ + char *buf = __coverity_alloc_nosize__(); + __coverity_string_null_sink__(fmt); + __coverity_string_size_sink__(fmt); + + __coverity_writeall__(buf); + + __coverity_mark_as_afm_allocated__(buf, "kmem_strfree"); + + return (buf); +} + +char * +kmem_strdup(const char *str) +{ + char *buf = __coverity_alloc_nosize__(); + + __coverity_string_null_sink__(str); + __coverity_string_size_sink__(str); + + __coverity_writeall__(buf); + + __coverity_mark_as_afm_allocated__(buf, "kmem_strfree"); + + return (buf); + + +} + +void +kmem_strfree(char *str) +{ + __coverity_free__(str); +} + +void * +spl_vmem_alloc(size_t sz, int fl, const char *func, int line) +{ + (void) func; + (void) line; + + __coverity_negative_sink__(sz); + + if (condition1) + __coverity_sleep__(); + + if ((fl == 0) || condition0) { + void *buf = __coverity_alloc__(sz); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "spl_vmem_free"); + return (buf); + } + + return (NULL); +} + +void * +spl_vmem_zalloc(size_t sz, int fl, const char *func, int line) +{ + (void) func; + (void) line; + + if (condition1) + __coverity_sleep__(); + + if ((fl == 0) || condition0) { + void *buf = __coverity_alloc__(sz); + __coverity_writeall0__(buf); + __coverity_mark_as_afm_allocated__(buf, "spl_vmem_free"); + return (buf); + } + + return (NULL); +} + +void +spl_vmem_free(const void *ptr, size_t sz) +{ + __coverity_negative_sink__(sz); __coverity_free__(ptr); } @@ -181,12 +322,12 @@ spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags) if (condition1) __coverity_sleep__(); - if (flags == 0) { - return (__coverity_alloc_nosize__()); - } else if (condition0) - return (__coverity_alloc_nosize__()); - else - return (NULL); + if ((flags == 0) || condition0) { + void *buf = __coverity_alloc_nosize__(); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "spl_kmem_cache_free"); + return (buf); + } } void @@ -197,12 +338,164 @@ spl_kmem_cache_free(spl_kmem_cache_t *skc, void *obj) __coverity_free__(obj); } +typedef struct {} zfsvfs_t; + +int +zfsvfs_create(const char *osname, boolean_t readonly, zfsvfs_t **zfvp) +{ + (void) osname; + (void) readonly; + + if (condition1) + __coverity_sleep__(); + + if (condition0) { + *zfvp = __coverity_alloc_nosize__(); + __coverity_writeall__(*zfvp); + return (0); + } + + return (1); +} + void +zfsvfs_free(zfsvfs_t *zfsvfs) +{ + __coverity_free__(zfsvfs); +} + +typedef struct {} nvlist_t; + +int +nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag) +{ + (void) nvflag; + + if (condition1) + __coverity_sleep__(); + + if ((kmflag == 0) || condition0) { + *nvlp = __coverity_alloc_nosize__(); + __coverity_mark_as_afm_allocated__(*nvlp, "nvlist_free"); + __coverity_writeall__(*nvlp); + return (0); + } + + return (-1); + +} + +int +nvlist_dup(const nvlist_t *nvl, nvlist_t **nvlp, int kmflag) +{ + nvlist_t read = *nvl; + + if (condition1) + __coverity_sleep__(); + + if ((kmflag == 0) || condition0) { + nvlist_t *nvl = __coverity_alloc_nosize__(); + __coverity_mark_as_afm_allocated__(nvl, "nvlist_free"); + __coverity_writeall__(nvl); + *nvlp = nvl; + return (0); + } + + return (-1); +} + +void +nvlist_free(nvlist_t *nvl) +{ + __coverity_free__(nvl); +} + +int +nvlist_pack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding, + int kmflag) +{ + (void) nvl; + (void) encoding; + + if (*bufp == NULL) { + if (condition1) + __coverity_sleep__(); + + if ((kmflag == 0) || condition0) { + char *buf = __coverity_alloc_nosize__(); + __coverity_writeall__(buf); + /* + * We cannot use __coverity_mark_as_afm_allocated__() + * because the free function varies between the kernel + * and userspace. + */ + *bufp = buf; + return (0); + } + + return (-1); + } + + /* + * Unfortunately, errors from the buffer being too small are not + * possible to model, so we assume success. + */ + __coverity_negative_sink__(*buflen); + __coverity_writeall__(*bufp); + return (0); +} + + +int +nvlist_unpack(char *buf, size_t buflen, nvlist_t **nvlp, int kmflag) +{ + __coverity_negative_sink__(buflen); + + if (condition1) + __coverity_sleep__(); + + if ((kmflag == 0) || condition0) { + nvlist_t *nvl = __coverity_alloc_nosize__(); + __coverity_mark_as_afm_allocated__(nvl, "nvlist_free"); + __coverity_writeall__(nvl); + *nvlp = nvl; + int first = buf[0]; + int last = buf[buflen-1]; + return (0); + } + + return (-1); + +} + +void * malloc(size_t size) { - __coverity_alloc__(size); + void *buf = __coverity_alloc__(size); + + if (condition1) + __coverity_sleep__(); + + __coverity_negative_sink__(size); + __coverity_mark_as_uninitialized_buffer__(buf); + __coverity_mark_as_afm_allocated__(buf, "free"); + + return (buf); } +void * +calloc(size_t nmemb, size_t size) +{ + void *buf = __coverity_alloc__(size * nmemb); + + if (condition1) + __coverity_sleep__(); + + __coverity_negative_sink__(size); + __coverity_writeall0__(buf); + __coverity_mark_as_afm_allocated__(buf, "free"); + return (buf); +} void free(void *buf) { diff --git a/debian/zfsutils-linux.install b/debian/zfsutils-linux.install index c36bff97708d..2d1a4ce63193 100644 --- a/debian/zfsutils-linux.install +++ b/debian/zfsutils-linux.install @@ -5,6 +5,7 @@ lib/systemd/system/zfs-import-scan.service lib/systemd/system/zfs-import-cache.service lib/systemd/system/zfs.target lib/systemd/system/zfs-import.service +lib/systemd/system/zfs-load-key.service lib/systemd/system/zfs-import.target lib/systemd/system/zfs-object-agent.service lib/systemd/system/zfs-trim-weekly@.timer diff --git a/etc/Makefile.am b/etc/Makefile.am index 2fb547c081ec..ee9fe5cc445b 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -79,6 +79,7 @@ INSTALL_DATA_HOOKS += systemd-install-data-hook systemd-install-data-hook: $(MKDIR_P) "$(DESTDIR)$(systemdunitdir)" ln -sf /dev/null "$(DESTDIR)$(systemdunitdir)/zfs-import.service" + ln -sf /dev/null "$(DESTDIR)$(systemdunitdir)/zfs-load-key.service" systemdgenerator_PROGRAMS = \ diff --git a/include/os/freebsd/spl/sys/mod_os.h b/include/os/freebsd/spl/sys/mod_os.h index e2815ce9e543..48e8a2adb8d2 100644 --- a/include/os/freebsd/spl/sys/mod_os.h +++ b/include/os/freebsd/spl/sys/mod_os.h @@ -52,17 +52,17 @@ #define ZFS_MODULE_VIRTUAL_PARAM_CALL ZFS_MODULE_PARAM_CALL -#define param_set_arc_long_args(var) \ - CTLTYPE_ULONG, &var, 0, param_set_arc_long, "LU" +#define param_set_arc_u64_args(var) \ + CTLTYPE_U64, &var, 0, param_set_arc_u64, "QU" #define param_set_arc_int_args(var) \ CTLTYPE_INT, &var, 0, param_set_arc_int, "I" #define param_set_arc_min_args(var) \ - CTLTYPE_ULONG, NULL, 0, param_set_arc_min, "LU" + CTLTYPE_U64, NULL, 0, param_set_arc_min, "QU" #define param_set_arc_max_args(var) \ - CTLTYPE_ULONG, NULL, 0, param_set_arc_max, "LU" + CTLTYPE_U64, NULL, 0, param_set_arc_max, "QU" #define param_set_arc_free_target_args(var) \ CTLTYPE_UINT, NULL, 0, param_set_arc_free_target, "IU" @@ -74,22 +74,22 @@ CTLTYPE_STRING, NULL, 0, param_set_deadman_failmode, "A" #define param_set_deadman_synctime_args(var) \ - CTLTYPE_ULONG, NULL, 0, param_set_deadman_synctime, "LU" + CTLTYPE_U64, NULL, 0, param_set_deadman_synctime, "QU" #define param_set_deadman_ziotime_args(var) \ - CTLTYPE_ULONG, NULL, 0, param_set_deadman_ziotime, "LU" + CTLTYPE_U64, NULL, 0, param_set_deadman_ziotime, "QU" #define param_set_multihost_interval_args(var) \ - CTLTYPE_ULONG, NULL, 0, param_set_multihost_interval, "LU" + CTLTYPE_U64, NULL, 0, param_set_multihost_interval, "QU" #define param_set_slop_shift_args(var) \ CTLTYPE_INT, NULL, 0, param_set_slop_shift, "I" #define param_set_min_auto_ashift_args(var) \ - CTLTYPE_U64, NULL, 0, param_set_min_auto_ashift, "QU" + CTLTYPE_UINT, NULL, 0, param_set_min_auto_ashift, "IU" #define param_set_max_auto_ashift_args(var) \ - CTLTYPE_U64, NULL, 0, param_set_max_auto_ashift, "QU" + CTLTYPE_UINT, NULL, 0, param_set_max_auto_ashift, "IU" #define fletcher_4_param_set_args(var) \ CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A" diff --git a/include/os/freebsd/spl/sys/types.h b/include/os/freebsd/spl/sys/types.h index b1308df29503..558843dcaa74 100644 --- a/include/os/freebsd/spl/sys/types.h +++ b/include/os/freebsd/spl/sys/types.h @@ -105,5 +105,7 @@ typedef u_longlong_t len_t; typedef longlong_t diskaddr_t; +typedef void zuserns_t; + #include #endif /* !_OPENSOLARIS_SYS_TYPES_H_ */ diff --git a/include/os/freebsd/zfs/sys/zfs_vnops_os.h b/include/os/freebsd/zfs/sys/zfs_vnops_os.h index bf5e03b24c06..460aecd2e708 100644 --- a/include/os/freebsd/zfs/sys/zfs_vnops_os.h +++ b/include/os/freebsd/zfs/sys/zfs_vnops_os.h @@ -35,20 +35,22 @@ int dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count, int *rbehind, int *rahead, int last_size); extern int zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags); extern int zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, - znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp); + znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns); extern int zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd, cred_t *cr, int flags); -extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr); +extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr, + zuserns_t *mnt_ns); extern int zfs_rename(znode_t *sdzp, const char *snm, znode_t *tdzp, - const char *tnm, cred_t *cr, int flags); + const char *tnm, cred_t *cr, int flags, zuserns_t *mnt_ns); extern int zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap, - const char *link, znode_t **zpp, cred_t *cr, int flags); + const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns); extern int zfs_link(znode_t *tdzp, znode_t *sp, const char *name, cred_t *cr, int flags); extern int zfs_space(znode_t *zp, int cmd, struct flock *bfp, int flag, offset_t offset, cred_t *cr); extern int zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, - int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp); + int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp, + zuserns_t *mnt_ns); extern int zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag, cred_t *cr); extern int zfs_write_simple(znode_t *zp, const void *data, size_t len, diff --git a/include/os/linux/kernel/linux/mod_compat.h b/include/os/linux/kernel/linux/mod_compat.h index 39863784e22a..5aa0f12c04b7 100644 --- a/include/os/linux/kernel/linux/mod_compat.h +++ b/include/os/linux/kernel/linux/mod_compat.h @@ -30,24 +30,20 @@ #include #include -/* Grsecurity kernel API change */ -#ifdef MODULE_PARAM_CALL_CONST +/* + * Despite constifying struct kernel_param_ops, some older kernels define a + * `__check_old_set_param()` function in their headers that checks for a + * non-constified `->set()`. This has long been fixed in Linux mainline, but + * since we support older kernels, we workaround it by using a preprocessor + * definition to disable it. + */ +#define __check_old_set_param(_) (0) + typedef const struct kernel_param zfs_kernel_param_t; -#else -typedef struct kernel_param zfs_kernel_param_t; -#endif #define ZMOD_RW 0644 #define ZMOD_RD 0444 -#define INT int -#define LONG long -/* BEGIN CSTYLED */ -#define UINT uint -#define ULONG ulong -/* END CSTYLED */ -#define STRING charp - enum scope_prefix_types { zfs, zfs_arc, @@ -81,6 +77,50 @@ enum scope_prefix_types { zfs_zil }; +/* + * While we define our own s64/u64 types, there is no reason to reimplement the + * existing Linux kernel types, so we use the preprocessor to remap our + * "custom" implementations to the kernel ones. This is done because the CPP + * does not allow us to write conditional definitions. The fourth definition + * exists because the CPP will not allow us to replace things like INT with int + * before string concatenation. + */ + +#define spl_param_set_int param_set_int +#define spl_param_get_int param_get_int +#define spl_param_ops_int param_ops_int +#define spl_param_ops_INT param_ops_int + +#define spl_param_set_long param_set_long +#define spl_param_get_long param_get_long +#define spl_param_ops_long param_ops_long +#define spl_param_ops_LONG param_ops_long + +#define spl_param_set_uint param_set_uint +#define spl_param_get_uint param_get_uint +#define spl_param_ops_uint param_ops_uint +#define spl_param_ops_UINT param_ops_uint + +#define spl_param_set_ulong param_set_ulong +#define spl_param_get_ulong param_get_ulong +#define spl_param_ops_ulong param_ops_ulong +#define spl_param_ops_ULONG param_ops_ulong + +#define spl_param_set_charp param_set_charp +#define spl_param_get_charp param_get_charp +#define spl_param_ops_charp param_ops_charp +#define spl_param_ops_STRING param_ops_charp + +int spl_param_set_s64(const char *val, zfs_kernel_param_t *kp); +extern int spl_param_get_s64(char *buffer, zfs_kernel_param_t *kp); +extern const struct kernel_param_ops spl_param_ops_s64; +#define spl_param_ops_S64 spl_param_ops_s64 + +extern int spl_param_set_u64(const char *val, zfs_kernel_param_t *kp); +extern int spl_param_get_u64(char *buffer, zfs_kernel_param_t *kp); +extern const struct kernel_param_ops spl_param_ops_u64; +#define spl_param_ops_U64 spl_param_ops_u64 + /* * Declare a module parameter / sysctl node * @@ -113,7 +153,8 @@ enum scope_prefix_types { _Static_assert( \ sizeof (scope_prefix) == sizeof (enum scope_prefix_types), \ "" #scope_prefix " size mismatch with enum scope_prefix_types"); \ - module_param(name_prefix ## name, type, perm); \ + module_param_cb(name_prefix ## name, &spl_param_ops_ ## type, \ + &name_prefix ## name, perm); \ MODULE_PARM_DESC(name_prefix ## name, desc) /* diff --git a/include/os/linux/spl/sys/cred.h b/include/os/linux/spl/sys/cred.h index b7d3f38d70bb..dc3c260dbbab 100644 --- a/include/os/linux/spl/sys/cred.h +++ b/include/os/linux/spl/sys/cred.h @@ -45,6 +45,34 @@ typedef struct cred cred_t; #define SGID_TO_KGID(x) (KGIDT_INIT(x)) #define KGIDP_TO_SGIDP(x) (&(x)->val) +static inline uid_t zfs_uid_into_mnt(struct user_namespace *mnt_ns, uid_t uid) +{ + if (mnt_ns) + return (__kuid_val(make_kuid(mnt_ns, uid))); + return (uid); +} + +static inline gid_t zfs_gid_into_mnt(struct user_namespace *mnt_ns, gid_t gid) +{ + if (mnt_ns) + return (__kgid_val(make_kgid(mnt_ns, gid))); + return (gid); +} + +static inline uid_t zfs_uid_from_mnt(struct user_namespace *mnt_ns, uid_t uid) +{ + if (mnt_ns) + return (from_kuid(mnt_ns, KUIDT_INIT(uid))); + return (uid); +} + +static inline gid_t zfs_gid_from_mnt(struct user_namespace *mnt_ns, gid_t gid) +{ + if (mnt_ns) + return (from_kgid(mnt_ns, KGIDT_INIT(gid))); + return (gid); +} + extern void crhold(cred_t *cr); extern void crfree(cred_t *cr); extern uid_t crgetuid(const cred_t *cr); diff --git a/include/os/linux/spl/sys/types.h b/include/os/linux/spl/sys/types.h index b44c94518750..cae1bbddf105 100644 --- a/include/os/linux/spl/sys/types.h +++ b/include/os/linux/spl/sys/types.h @@ -54,4 +54,7 @@ typedef ulong_t pgcnt_t; typedef int major_t; typedef int minor_t; +struct user_namespace; +typedef struct user_namespace zuserns_t; + #endif /* _SPL_TYPES_H */ diff --git a/include/os/linux/zfs/sys/policy.h b/include/os/linux/zfs/sys/policy.h index 3bd7ce36b85d..ee7fda761a3b 100644 --- a/include/os/linux/zfs/sys/policy.h +++ b/include/os/linux/zfs/sys/policy.h @@ -47,13 +47,13 @@ int secpolicy_vnode_create_gid(const cred_t *); int secpolicy_vnode_remove(const cred_t *); int secpolicy_vnode_setdac(const cred_t *, uid_t); int secpolicy_vnode_setid_retain(struct znode *, const cred_t *, boolean_t); -int secpolicy_vnode_setids_setgids(const cred_t *, gid_t); +int secpolicy_vnode_setids_setgids(const cred_t *, gid_t, zuserns_t *); int secpolicy_zinject(const cred_t *); int secpolicy_zfs(const cred_t *); int secpolicy_zfs_proc(const cred_t *, proc_t *); void secpolicy_setid_clear(vattr_t *, cred_t *); int secpolicy_setid_setsticky_clear(struct inode *, vattr_t *, - const vattr_t *, cred_t *); + const vattr_t *, cred_t *, zuserns_t *); int secpolicy_xvattr(xvattr_t *, uid_t, cred_t *, mode_t); int secpolicy_vnode_setattr(cred_t *, struct inode *, struct vattr *, const struct vattr *, int, int (void *, int, cred_t *), void *); diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h index 22ca625023b0..787d258e1388 100644 --- a/include/os/linux/zfs/sys/zfs_vnops_os.h +++ b/include/os/linux/zfs/sys/zfs_vnops_os.h @@ -45,22 +45,25 @@ extern int zfs_write_simple(znode_t *zp, const void *data, size_t len, extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp, int flags, cred_t *cr, int *direntflags, pathname_t *realpnp); extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, - int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp); + int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp, + zuserns_t *mnt_ns); extern int zfs_tmpfile(struct inode *dip, vattr_t *vapzfs, int excl, - int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp); + int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp, + zuserns_t *mnt_ns); extern int zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags); extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, - znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp); + znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns); extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, cred_t *cr, int flags); extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr); extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip, struct kstat *sp); -extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr); +extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr, + zuserns_t *mnt_ns); extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, - char *tnm, cred_t *cr, int flags); + char *tnm, cred_t *cr, int flags, zuserns_t *mnt_ns); extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, - char *link, znode_t **zpp, cred_t *cr, int flags); + char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns); extern int zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr); extern int zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr, int flags); diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h index 95f08f5416d0..30d73db6b9e8 100644 --- a/include/os/linux/zfs/sys/zpl.h +++ b/include/os/linux/zfs/sys/zpl.h @@ -39,7 +39,7 @@ /* zpl_inode.c */ extern void zpl_vap_init(vattr_t *vap, struct inode *dir, - umode_t mode, cred_t *cr); + umode_t mode, cred_t *cr, zuserns_t *mnt_ns); extern const struct inode_operations zpl_inode_operations; extern const struct inode_operations zpl_dir_inode_operations; diff --git a/include/sys/arc_impl.h b/include/sys/arc_impl.h index 0f2cd956eb64..03eebafa9952 100644 --- a/include/sys/arc_impl.h +++ b/include/sys/arc_impl.h @@ -985,8 +985,8 @@ extern arc_state_t ARC_mfu; extern arc_state_t ARC_mru; extern uint_t zfs_arc_pc_percent; extern uint_t arc_lotsfree_percent; -extern unsigned long zfs_arc_min; -extern unsigned long zfs_arc_max; +extern uint64_t zfs_arc_min; +extern uint64_t zfs_arc_max; extern void arc_reduce_target_size(int64_t to_free); extern boolean_t arc_reclaim_needed(void); @@ -1003,7 +1003,7 @@ extern void arc_tuning_update(boolean_t); extern void arc_register_hotplug(void); extern void arc_unregister_hotplug(void); -extern int param_set_arc_long(ZFS_MODULE_PARAM_ARGS); +extern int param_set_arc_u64(ZFS_MODULE_PARAM_ARGS); extern int param_set_arc_int(ZFS_MODULE_PARAM_ARGS); extern int param_set_arc_min(ZFS_MODULE_PARAM_ARGS); extern int param_set_arc_max(ZFS_MODULE_PARAM_ARGS); diff --git a/include/sys/dmu.h b/include/sys/dmu.h index 906c73781b19..92a0a5cfa627 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -27,6 +27,7 @@ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. * Copyright (c) 2017, Intel Corporation. + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ /* Portions Copyright 2010 Robert Milkowski */ @@ -142,6 +143,12 @@ typedef enum dmu_object_byteswap { #define DMU_OT_IS_DDT(ot) \ ((ot) == DMU_OT_DDT_ZAP) +#define DMU_OT_IS_CRITICAL(ot) \ + (DMU_OT_IS_METADATA(ot) && \ + (ot) != DMU_OT_DNODE && \ + (ot) != DMU_OT_DIRECTORY_CONTENTS && \ + (ot) != DMU_OT_SA) + /* Note: ztest uses DMU_OT_UINT64_OTHER as a proxy for file blocks */ #define DMU_OT_IS_FILE(ot) \ ((ot) == DMU_OT_PLAIN_FILE_CONTENTS || (ot) == DMU_OT_UINT64_OTHER) diff --git a/include/sys/dmu_zfetch.h b/include/sys/dmu_zfetch.h index ad3bc040756c..0fbc3bacffb9 100644 --- a/include/sys/dmu_zfetch.h +++ b/include/sys/dmu_zfetch.h @@ -36,7 +36,7 @@ extern "C" { #endif -extern unsigned long zfetch_array_rd_sz; +extern uint64_t zfetch_array_rd_sz; struct dnode; /* so we can reference dnode */ diff --git a/include/sys/dsl_deadlist.h b/include/sys/dsl_deadlist.h index a94bba56ff7a..3feb3bbf062f 100644 --- a/include/sys/dsl_deadlist.h +++ b/include/sys/dsl_deadlist.h @@ -84,7 +84,7 @@ typedef struct livelist_condense_entry { boolean_t cancelled; } livelist_condense_entry_t; -extern unsigned long zfs_livelist_max_entries; +extern uint64_t zfs_livelist_max_entries; extern int zfs_livelist_min_percent_shared; typedef int deadlist_iter_t(void *args, dsl_deadlist_entry_t *dle); diff --git a/include/sys/dsl_pool.h b/include/sys/dsl_pool.h index 7113808c84e7..845fc33ba3a2 100644 --- a/include/sys/dsl_pool.h +++ b/include/sys/dsl_pool.h @@ -57,13 +57,13 @@ struct dsl_scan; struct dsl_crypto_params; struct dsl_deadlist; -extern unsigned long zfs_dirty_data_max; -extern unsigned long zfs_dirty_data_max_max; -extern unsigned long zfs_wrlog_data_max; +extern uint64_t zfs_dirty_data_max; +extern uint64_t zfs_dirty_data_max_max; +extern uint64_t zfs_wrlog_data_max; extern uint_t zfs_dirty_data_max_percent; extern uint_t zfs_dirty_data_max_max_percent; extern uint_t zfs_delay_min_dirty_percent; -extern unsigned long zfs_delay_scale; +extern uint64_t zfs_delay_scale; /* These macros are for indexing into the zfs_all_blkstats_t. */ #define DMU_OT_DEFERRED DMU_OT_NONE diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index c6b64ff93aac..f55582a512be 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -29,6 +29,7 @@ * Copyright (c) 2019 Datto Inc. * Portions Copyright 2010 Robert Milkowski * Copyright (c) 2021, Colm Buckley + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ #ifndef _SYS_FS_ZFS_H @@ -505,7 +506,9 @@ typedef enum { typedef enum { ZFS_REDUNDANT_METADATA_ALL, - ZFS_REDUNDANT_METADATA_MOST + ZFS_REDUNDANT_METADATA_MOST, + ZFS_REDUNDANT_METADATA_SOME, + ZFS_REDUNDANT_METADATA_NONE } zfs_redundant_metadata_type_t; typedef enum { diff --git a/include/sys/mmp.h b/include/sys/mmp.h index ce9c4496a04f..1023334098d8 100644 --- a/include/sys/mmp.h +++ b/include/sys/mmp.h @@ -64,7 +64,7 @@ extern void mmp_signal_all_threads(void); /* Global tuning */ extern int param_set_multihost_interval(ZFS_MODULE_PARAM_ARGS); -extern ulong_t zfs_multihost_interval; +extern uint64_t zfs_multihost_interval; extern uint_t zfs_multihost_fail_intervals; extern uint_t zfs_multihost_import_intervals; diff --git a/include/sys/spa.h b/include/sys/spa.h index a806b5dd8863..49acb617da6e 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -1223,9 +1223,9 @@ int param_set_deadman_failmode(ZFS_MODULE_PARAM_ARGS); extern spa_mode_t spa_mode_global; extern int zfs_deadman_enabled; -extern unsigned long zfs_deadman_synctime_ms; -extern unsigned long zfs_deadman_ziotime_ms; -extern unsigned long zfs_deadman_checktime_ms; +extern uint64_t zfs_deadman_synctime_ms; +extern uint64_t zfs_deadman_ziotime_ms; +extern uint64_t zfs_deadman_checktime_ms; extern kmem_cache_t *zio_buf_cache[]; extern kmem_cache_t *zio_data_buf_cache[]; diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h index d536cbc0c7cc..a8f2803c3f23 100644 --- a/include/sys/vdev_impl.h +++ b/include/sys/vdev_impl.h @@ -659,8 +659,8 @@ extern void vdev_queue_pending_remove(vdev_queue_t *vq, zio_t *zio); /* * Vdev ashift optimization tunables */ -extern uint64_t zfs_vdev_min_auto_ashift; -extern uint64_t zfs_vdev_max_auto_ashift; +extern uint_t zfs_vdev_min_auto_ashift; +extern uint_t zfs_vdev_max_auto_ashift; int param_set_min_auto_ashift(ZFS_MODULE_PARAM_ARGS); int param_set_max_auto_ashift(ZFS_MODULE_PARAM_ARGS); diff --git a/include/sys/zcp.h b/include/sys/zcp.h index f0a78f9cb5c4..6301cc08e7ea 100644 --- a/include/sys/zcp.h +++ b/include/sys/zcp.h @@ -33,8 +33,8 @@ extern "C" { #define ZCP_RUN_INFO_KEY "runinfo" -extern unsigned long zfs_lua_max_instrlimit; -extern unsigned long zfs_lua_max_memlimit; +extern uint64_t zfs_lua_max_instrlimit; +extern uint64_t zfs_lua_max_memlimit; int zcp_argerror(lua_State *, int, const char *, ...); diff --git a/include/sys/zfs_acl.h b/include/sys/zfs_acl.h index c4d2dddd7b1f..82fb98c9fb89 100644 --- a/include/sys/zfs_acl.h +++ b/include/sys/zfs_acl.h @@ -206,7 +206,7 @@ struct zfsvfs; #ifdef _KERNEL int zfs_acl_ids_create(struct znode *, int, vattr_t *, - cred_t *, vsecattr_t *, zfs_acl_ids_t *); + cred_t *, vsecattr_t *, zfs_acl_ids_t *, zuserns_t *); void zfs_acl_ids_free(zfs_acl_ids_t *); boolean_t zfs_acl_ids_overquota(struct zfsvfs *, zfs_acl_ids_t *, uint64_t); int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); @@ -215,15 +215,16 @@ void zfs_acl_rele(void *); void zfs_oldace_byteswap(ace_t *, int); void zfs_ace_byteswap(void *, size_t, boolean_t); extern boolean_t zfs_has_access(struct znode *zp, cred_t *cr); -extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *); +extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *, + zuserns_t *); int zfs_fastaccesschk_execute(struct znode *, cred_t *); -extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *); +extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *, zuserns_t *); extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *); extern int zfs_acl_access(struct znode *, int, cred_t *); int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t); -int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *); +int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *, zuserns_t *); int zfs_zaccess_rename(struct znode *, struct znode *, - struct znode *, struct znode *, cred_t *cr); + struct znode *, struct znode *, cred_t *cr, zuserns_t *mnt_ns); void zfs_acl_free(zfs_acl_t *); int zfs_vsec_2_aclp(struct zfsvfs *, umode_t, vsecattr_t *, cred_t *, struct zfs_fuid_info **, zfs_acl_t **); diff --git a/include/sys/zfs_ioctl_impl.h b/include/sys/zfs_ioctl_impl.h index 0bf9fa6ff193..cb852c5577fd 100644 --- a/include/sys/zfs_ioctl_impl.h +++ b/include/sys/zfs_ioctl_impl.h @@ -24,7 +24,7 @@ #define _ZFS_IOCTL_IMPL_H_ extern kmutex_t zfsdev_state_lock; -extern unsigned long zfs_max_nvlist_src_size; +extern uint64_t zfs_max_nvlist_src_size; typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *); typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *); diff --git a/lib/libefi/rdwr_efi.c b/lib/libefi/rdwr_efi.c index f159a022496c..3501c3ea391c 100644 --- a/lib/libefi/rdwr_efi.c +++ b/lib/libefi/rdwr_efi.c @@ -423,7 +423,6 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc) void *tmp; length = (int) sizeof (struct dk_gpt) + (int) sizeof (struct dk_part) * (vptr->efi_nparts - 1); - nparts = vptr->efi_nparts; if ((tmp = realloc(vptr, length)) == NULL) { /* cppcheck-suppress doubleFree */ free(vptr); @@ -565,10 +564,9 @@ int efi_rescan(int fd) { int retry = 10; - int error; /* Notify the kernel a devices partition table has been updated */ - while ((error = ioctl(fd, BLKRRPART)) != 0) { + while (ioctl(fd, BLKRRPART) != 0) { if ((--retry == 0) || (errno != EBUSY)) { (void) fprintf(stderr, "the kernel failed to rescan " "the partition table: %d\n", errno); diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 2ef51c675186..69649196bc7f 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -2031,7 +2031,7 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received) if ((ret = changelist_prefix(cl)) != 0) goto error; - if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) { + if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) { changelist_free(cl); return (zfs_standard_error(hdl, errno, errbuf)); } else { diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c index 80588a860c18..84e140ede665 100644 --- a/lib/libzfs/libzfs_diff.c +++ b/lib/libzfs/libzfs_diff.c @@ -377,7 +377,7 @@ write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr) if (zc.zc_obj > dr->ddr_last) { break; } - err = describe_free(fp, di, zc.zc_obj, fobjname, + (void) describe_free(fp, di, zc.zc_obj, fobjname, MAXPATHLEN); } else if (errno == ESRCH) { break; diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 88515f459094..cde92d2d100e 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -2262,7 +2262,6 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname, ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), nv); } nvlist_free(nv); - return (0); } return (ret); @@ -2727,7 +2726,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare, if (zfs_strcmp_pathname(srchval, val, wholedisk) == 0) return (nv); - } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) { + } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0) { char *type, *idx, *end, *p; uint64_t id, vdev_id; diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index f5bda5be3a22..175af85501c9 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -2117,9 +2117,9 @@ send_prelim_records(zfs_handle_t *zhp, const char *from, int fd, fnvlist_add_boolean(hdrnv, "raw"); } - if ((err = gather_nvlist(zhp->zfs_hdl, tofs, + if (gather_nvlist(zhp->zfs_hdl, tofs, from, tosnap, recursive, raw, doall, replicate, skipmissing, - verbose, backup, holds, props, &fss, fsavlp)) != 0) { + verbose, backup, holds, props, &fss, fsavlp) != 0) { return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP, errbuf)); } diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index a98ef034d395..1a58b1bebd21 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -1249,7 +1249,7 @@ zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp) static void zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type) { - zprop_list_t *pl = cbp->cb_proplist; + zprop_list_t *pl; int i; char *title; size_t len; diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c index 993753a29eda..8121a91b8d51 100644 --- a/lib/libzfs_core/libzfs_core.c +++ b/lib/libzfs_core/libzfs_core.c @@ -235,7 +235,7 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name, break; } } - if (zc.zc_nvlist_dst_filled) { + if (zc.zc_nvlist_dst_filled && resultp != NULL) { *resultp = fnvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst, zc.zc_nvlist_dst_size); } diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c index 0ce7822a3563..a310255d7a7d 100644 --- a/lib/libzpool/util.c +++ b/lib/libzpool/util.c @@ -229,13 +229,14 @@ set_global_var(char const *arg) fprintf(stderr, "Failed to open libzpool.so to set global " "variable\n"); ret = EIO; - goto out_dlclose; + goto out_free; } ret = 0; out_dlclose: dlclose(zpoolhdl); +out_free: free(varname); out_ret: return (ret); diff --git a/lib/libzutil/os/linux/zutil_device_path_os.c b/lib/libzutil/os/linux/zutil_device_path_os.c index 05dbb39954fa..900d5e5bacd2 100644 --- a/lib/libzutil/os/linux/zutil_device_path_os.c +++ b/lib/libzutil/os/linux/zutil_device_path_os.c @@ -428,7 +428,6 @@ dm_get_underlying_path(const char *dm_name) char *tmp = NULL; char *path = NULL; char *dev_str; - int size; char *first_path = NULL; char *enclosure_path; @@ -450,7 +449,7 @@ dm_get_underlying_path(const char *dm_name) else dev_str = tmp; - if ((size = asprintf(&tmp, "/sys/block/%s/slaves/", dev_str)) == -1) { + if (asprintf(&tmp, "/sys/block/%s/slaves/", dev_str) == -1) { tmp = NULL; goto end; } @@ -479,8 +478,7 @@ dm_get_underlying_path(const char *dm_name) if (!enclosure_path) continue; - if ((size = asprintf( - &path, "/dev/%s", ep->d_name)) == -1) + if (asprintf(&path, "/dev/%s", ep->d_name) == -1) path = NULL; free(enclosure_path); break; @@ -499,7 +497,7 @@ dm_get_underlying_path(const char *dm_name) * enclosure devices. Throw up out hands and return the first * underlying path. */ - if ((size = asprintf(&path, "/dev/%s", first_path)) == -1) + if (asprintf(&path, "/dev/%s", first_path) == -1) path = NULL; } diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index f0e4c9d06814..b6d4e302381c 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -516,11 +516,9 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok, uint64_t guid; uint_t children = 0; nvlist_t **child = NULL; - uint_t holes; uint64_t *hole_array, max_id; uint_t c; boolean_t isactive; - uint64_t hostid; nvlist_t *nvl; boolean_t valid_top_config = B_FALSE; @@ -528,7 +526,8 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok, goto nomem; for (pe = pl->pools; pe != NULL; pe = pe->pe_next) { - uint64_t id, max_txg = 0; + uint64_t id, max_txg = 0, hostid = 0; + uint_t holes = 0; if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0) goto nomem; diff --git a/man/man4/zfs.4 b/man/man4/zfs.4 index da1aa9c34287..2bfa3601fbcd 100644 --- a/man/man4/zfs.4 +++ b/man/man4/zfs.4 @@ -26,7 +26,7 @@ .Sh DESCRIPTION The ZFS module supports these parameters: .Bl -tag -width Ds -.It Sy dbuf_cache_max_bytes Ns = Ns Sy ULONG_MAX Ns B Pq ulong +.It Sy dbuf_cache_max_bytes Ns = Ns Sy UINT64_MAX Ns B Pq u64 Maximum size in bytes of the dbuf cache. The target size is determined by the MIN versus .No 1/2^ Ns Sy dbuf_cache_shift Pq 1/32nd @@ -36,7 +36,7 @@ can be observed via the .Pa /proc/spl/kstat/zfs/dbufstats kstat. . -.It Sy dbuf_metadata_cache_max_bytes Ns = Ns Sy ULONG_MAX Ns B Pq ulong +.It Sy dbuf_metadata_cache_max_bytes Ns = Ns Sy UINT64_MAX Ns B Pq u64 Maximum size in bytes of the metadata dbuf cache. The target size is determined by the MIN versus .No 1/2^ Ns Sy dbuf_metadata_cache_shift Pq 1/64th @@ -88,16 +88,16 @@ Alias for Turbo L2ARC warm-up. When the L2ARC is cold the fill interval will be set as fast as possible. . -.It Sy l2arc_feed_min_ms Ns = Ns Sy 200 Pq ulong +.It Sy l2arc_feed_min_ms Ns = Ns Sy 200 Pq u64 Min feed interval in milliseconds. Requires .Sy l2arc_feed_again Ns = Ns Ar 1 and only applicable in related situations. . -.It Sy l2arc_feed_secs Ns = Ns Sy 1 Pq ulong +.It Sy l2arc_feed_secs Ns = Ns Sy 1 Pq u64 Seconds between L2ARC writing. . -.It Sy l2arc_headroom Ns = Ns Sy 2 Pq ulong +.It Sy l2arc_headroom Ns = Ns Sy 2 Pq u64 How far through the ARC lists to search for L2ARC cacheable content, expressed as a multiplier of .Sy l2arc_write_max . @@ -106,7 +106,7 @@ by setting this parameter to .Sy 0 , allowing the full length of ARC lists to be searched for cacheable content. . -.It Sy l2arc_headroom_boost Ns = Ns Sy 200 Ns % Pq ulong +.It Sy l2arc_headroom_boost Ns = Ns Sy 200 Ns % Pq u64 Scales .Sy l2arc_headroom by this percentage when L2ARC contents are being successfully compressed @@ -162,7 +162,7 @@ too many headers on a system with an irrationally large L2ARC can render it slow or unusable. This parameter limits L2ARC writes and rebuilds to achieve the target. . -.It Sy l2arc_trim_ahead Ns = Ns Sy 0 Ns % Pq ulong +.It Sy l2arc_trim_ahead Ns = Ns Sy 0 Ns % Pq u64 Trims ahead of the current write size .Pq Sy l2arc_write_max on L2ARC devices by this percentage of write size if we have filled the device. @@ -200,12 +200,12 @@ to enable caching/reading prefetches to/from L2ARC. .It Sy l2arc_norw Ns = Ns Sy 0 Ns | Ns 1 Pq int No reads during writes. . -.It Sy l2arc_write_boost Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq ulong +.It Sy l2arc_write_boost Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq u64 Cold L2ARC devices will have .Sy l2arc_write_max increased by this amount while they remain cold. . -.It Sy l2arc_write_max Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq ulong +.It Sy l2arc_write_max Ns = Ns Sy 8388608 Ns B Po 8 MiB Pc Pq u64 Max write bytes per interval. . .It Sy l2arc_rebuild_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int @@ -215,7 +215,7 @@ or attaching an L2ARC device (e.g. the L2ARC device is slow in reading stored log metadata, or the metadata has become somehow fragmented/unusable). . -.It Sy l2arc_rebuild_blocks_min_l2size Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq ulong +.It Sy l2arc_rebuild_blocks_min_l2size Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64 Mininum size of an L2ARC device required in order to write log blocks in it. The log blocks are used upon importing the pool to rebuild the persistent L2ARC. .Pp @@ -224,7 +224,7 @@ For L2ARC devices less than 1 GiB, the amount of data evicts is significant compared to the amount of restored L2ARC data. In this case, do not write log blocks in L2ARC in order not to waste space. . -.It Sy metaslab_aliquot Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong +.It Sy metaslab_aliquot Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 Metaslab granularity, in bytes. This is roughly similar to what would be referred to as the "stripe size" in traditional RAID arrays. @@ -235,11 +235,11 @@ before moving on to the next top-level vdev. Enable metaslab group biasing based on their vdevs' over- or under-utilization relative to the pool. . -.It Sy metaslab_force_ganging Ns = Ns Sy 16777217 Ns B Po 16 MiB + 1 B Pc Pq ulong +.It Sy metaslab_force_ganging Ns = Ns Sy 16777217 Ns B Po 16 MiB + 1 B Pc Pq u64 Make some blocks above a certain size be gang blocks. This option is used by the test suite to facilitate testing. . -.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq int +.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 When attempting to log an output nvlist of an ioctl in the on-disk history, the output will not be stored if it is larger than this size (in bytes). This must be less than @@ -299,7 +299,7 @@ this tunable controls which segment is used. If set, we will use the largest free segment. If unset, we will use a segment of at least the requested size. . -.It Sy zfs_metaslab_max_size_cache_sec Ns = Ns Sy 3600 Ns s Po 1 hour Pc Pq ulong +.It Sy zfs_metaslab_max_size_cache_sec Ns = Ns Sy 3600 Ns s Po 1 hour Pc Pq u64 When we unload a metaslab, we cache the size of the largest free chunk. We use that cached size to determine whether or not to load a metaslab for a given allocation. @@ -353,14 +353,14 @@ When a vdev is added, target this number of metaslabs per top-level vdev. .It Sy zfs_vdev_default_ms_shift Ns = Ns Sy 29 Po 512 MiB Pc Pq uint Default limit for metaslab size. . -.It Sy zfs_vdev_max_auto_ashift Ns = Ns Sy 14 Pq ulong +.It Sy zfs_vdev_max_auto_ashift Ns = Ns Sy 14 Pq uint Maximum ashift used when optimizing for logical \[->] physical sector size on new top-level vdevs. May be increased up to .Sy ASHIFT_MAX Po 16 Pc , but this may negatively impact pool space efficiency. . -.It Sy zfs_vdev_min_auto_ashift Ns = Ns Sy ASHIFT_MIN Po 9 Pc Pq ulong +.It Sy zfs_vdev_min_auto_ashift Ns = Ns Sy ASHIFT_MIN Po 9 Pc Pq uint Minimum ashift used when creating new top-level vdevs. . .It Sy zfs_vdev_min_ms_count Ns = Ns Sy 16 Pq uint @@ -481,10 +481,10 @@ The default value here was chosen to align with which is a similar concept when doing regular reads (but there's no reason it has to be the same). . -.It Sy vdev_file_logical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq ulong +.It Sy vdev_file_logical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq u64 Logical ashift for file-based devices. . -.It Sy vdev_file_physical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq ulong +.It Sy vdev_file_physical_ashift Ns = Ns Sy 9 Po 512 B Pc Pq u64 Physical ashift for file-based devices. . .It Sy zap_iterate_prefetch Ns = Ns Sy 1 Ns | Ns 0 Pq int @@ -493,7 +493,7 @@ prefetch the entire object (all leaf blocks). However, this is limited by .Sy dmu_prefetch_max . . -.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong +.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 If prefetching is enabled, disable prefetching for reads larger than this size. . .It Sy zfetch_min_distance Ns = Ns Sy 4194304 Ns B Po 4 MiB Pc Pq uint @@ -537,7 +537,7 @@ depends on kernel configuration. This is the minimum allocation size that will use scatter (page-based) ABDs. Smaller allocations will use linear ABDs. . -.It Sy zfs_arc_dnode_limit Ns = Ns Sy 0 Ns B Pq ulong +.It Sy zfs_arc_dnode_limit Ns = Ns Sy 0 Ns B Pq u64 When the number of bytes consumed by dnodes in the ARC exceeds this number of bytes, try to unpin some of it in response to demand for non-metadata. This value acts as a ceiling to the amount of dnode metadata, and defaults to @@ -553,14 +553,14 @@ when the amount of metadata in the ARC exceeds .Sy zfs_arc_meta_limit rather than in response to overall demand for non-metadata. . -.It Sy zfs_arc_dnode_limit_percent Ns = Ns Sy 10 Ns % Pq ulong +.It Sy zfs_arc_dnode_limit_percent Ns = Ns Sy 10 Ns % Pq u64 Percentage that can be consumed by dnodes of ARC meta buffers. .Pp See also .Sy zfs_arc_dnode_limit , which serves a similar purpose but has a higher priority if nonzero. . -.It Sy zfs_arc_dnode_reduce_percent Ns = Ns Sy 10 Ns % Pq ulong +.It Sy zfs_arc_dnode_reduce_percent Ns = Ns Sy 10 Ns % Pq u64 Percentage of ARC dnodes to try to scan in response to demand for non-metadata when the number of bytes consumed by dnodes exceeds .Sy zfs_arc_dnode_limit . @@ -613,7 +613,7 @@ Setting this value to .Sy 0 will disable the throttle. . -.It Sy zfs_arc_max Ns = Ns Sy 0 Ns B Pq ulong +.It Sy zfs_arc_max Ns = Ns Sy 0 Ns B Pq u64 Max size of ARC in bytes. If .Sy 0 , @@ -642,7 +642,7 @@ the free buffers in order to stay below the This value should not need to be tuned but is available to facilitate performance analysis. . -.It Sy zfs_arc_meta_limit Ns = Ns Sy 0 Ns B Pq ulong +.It Sy zfs_arc_meta_limit Ns = Ns Sy 0 Ns B Pq u64 The maximum allowed size in bytes that metadata buffers are allowed to consume in the ARC. When this limit is reached, metadata buffers will be reclaimed, @@ -658,14 +658,14 @@ of the ARC may be used for metadata. This value my be changed dynamically, except that must be set to an explicit value .Pq cannot be set back to Sy 0 . . -.It Sy zfs_arc_meta_limit_percent Ns = Ns Sy 75 Ns % Pq ulong +.It Sy zfs_arc_meta_limit_percent Ns = Ns Sy 75 Ns % Pq u64 Percentage of ARC buffers that can be used for metadata. .Pp See also .Sy zfs_arc_meta_limit , which serves a similar purpose but has a higher priority if nonzero. . -.It Sy zfs_arc_meta_min Ns = Ns Sy 0 Ns B Pq ulong +.It Sy zfs_arc_meta_min Ns = Ns Sy 0 Ns B Pq u64 The minimum allowed size in bytes that metadata buffers may consume in the ARC. . @@ -691,7 +691,7 @@ additional data buffers may be evicted if required to evict the required number of metadata buffers. .El . -.It Sy zfs_arc_min Ns = Ns Sy 0 Ns B Pq ulong +.It Sy zfs_arc_min Ns = Ns Sy 0 Ns B Pq u64 Min size of ARC in bytes. .No If set to Sy 0 , arc_c_min will default to consuming the larger of @@ -718,7 +718,7 @@ but that was not proven to be useful. Number of missing top-level vdevs which will be allowed during pool import (only in read-only mode). . -.It Sy zfs_max_nvlist_src_size Ns = Sy 0 Pq ulong +.It Sy zfs_max_nvlist_src_size Ns = Sy 0 Pq u64 Maximum size in bytes allowed to be passed as .Sy zc_nvlist_src_size for ioctls on @@ -822,7 +822,7 @@ even with a small average compressed block size of ~8 KiB. The parameter can be set to 0 (zero) to disable the limit, and only applies on Linux. . -.It Sy zfs_arc_sys_free Ns = Ns Sy 0 Ns B Pq ulong +.It Sy zfs_arc_sys_free Ns = Ns Sy 0 Ns B Pq u64 The target number of bytes the ARC should leave as free memory on the system. If zero, equivalent to the bigger of .Sy 512 KiB No and Sy all_system_memory/64 . @@ -866,12 +866,12 @@ bytes of memory and if the obsolete space map object uses more than bytes on-disk. The condensing process is an attempt to save memory by removing obsolete mappings. . -.It Sy zfs_condense_max_obsolete_bytes Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq ulong +.It Sy zfs_condense_max_obsolete_bytes Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64 Only attempt to condense indirect vdev mappings if the on-disk size of the obsolete space map object is greater than this number of bytes .Pq see Sy zfs_condense_indirect_vdevs_enable . . -.It Sy zfs_condense_min_mapping_bytes Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq ulong +.It Sy zfs_condense_min_mapping_bytes Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq u64 Minimum size vdev mapping to attempt to condense .Pq see Sy zfs_condense_indirect_vdevs_enable . . @@ -927,21 +927,21 @@ This can be used to facilitate automatic fail-over to a properly configured fail-over partner. .El . -.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1 min Pc Pq int +.It Sy zfs_deadman_checktime_ms Ns = Ns Sy 60000 Ns ms Po 1 min Pc Pq u64 Check time in milliseconds. This defines the frequency at which we check for hung I/O requests and potentially invoke the .Sy zfs_deadman_failmode behavior. . -.It Sy zfs_deadman_synctime_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq ulong +.It Sy zfs_deadman_synctime_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq u64 Interval in milliseconds after which the deadman is triggered and also the interval after which a pool sync operation is considered to be "hung". Once this limit is exceeded the deadman will be invoked every .Sy zfs_deadman_checktime_ms milliseconds until the pool sync completes. . -.It Sy zfs_deadman_ziotime_ms Ns = Ns Sy 300000 Ns ms Po 5 min Pc Pq ulong +.It Sy zfs_deadman_ziotime_ms Ns = Ns Sy 300000 Ns ms Po 5 min Pc Pq u64 Interval in milliseconds after which the deadman is triggered and an individual I/O operation is considered to be "hung". As long as the operation remains "hung", @@ -994,15 +994,15 @@ same object. Rate limit delay and deadman zevents (which report slow I/O operations) to this many per second. . -.It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq ulong +.It Sy zfs_unflushed_max_mem_amt Ns = Ns Sy 1073741824 Ns B Po 1 GiB Pc Pq u64 Upper-bound limit for unflushed metadata changes to be held by the log spacemap in memory, in bytes. . -.It Sy zfs_unflushed_max_mem_ppm Ns = Ns Sy 1000 Ns ppm Po 0.1% Pc Pq ulong +.It Sy zfs_unflushed_max_mem_ppm Ns = Ns Sy 1000 Ns ppm Po 0.1% Pc Pq u64 Part of overall system memory that ZFS allows to be used for unflushed metadata changes by the log spacemap, in millionths. . -.It Sy zfs_unflushed_log_block_max Ns = Ns Sy 131072 Po 128k Pc Pq ulong +.It Sy zfs_unflushed_log_block_max Ns = Ns Sy 131072 Po 128k Pc Pq u64 Describes the maximum number of log spacemap blocks allowed for each pool. The default value means that the space in all the log spacemaps can add up to no more than @@ -1030,17 +1030,17 @@ one extra logical I/O issued. This is the reason why this tunable is exposed in terms of blocks rather than space used. . -.It Sy zfs_unflushed_log_block_min Ns = Ns Sy 1000 Pq ulong +.It Sy zfs_unflushed_log_block_min Ns = Ns Sy 1000 Pq u64 If the number of metaslabs is small and our incoming rate is high, we could get into a situation that we are flushing all our metaslabs every TXG. Thus we always allow at least this many log blocks. . -.It Sy zfs_unflushed_log_block_pct Ns = Ns Sy 400 Ns % Pq ulong +.It Sy zfs_unflushed_log_block_pct Ns = Ns Sy 400 Ns % Pq u64 Tunable used to determine the number of blocks that can be used for the spacemap log, expressed as a percentage of the total number of unflushed metaslabs in the pool. . -.It Sy zfs_unflushed_log_txg_max Ns = Ns Sy 1000 Pq ulong +.It Sy zfs_unflushed_log_txg_max Ns = Ns Sy 1000 Pq u64 Tunable limiting maximum time in TXGs any metaslab may remain unflushed. It effectively limits maximum number of unflushed per-TXG spacemap logs that need to be read after unclean pool export. @@ -1060,6 +1060,7 @@ will be deleted asynchronously, while smaller files are deleted synchronously. Decreasing this value will reduce the time spent in an .Xr unlink 2 system call, at the expense of a longer delay before the freed space is available. +This only applies on Linux. . .It Sy zfs_dirty_data_max Ns = Pq int Determines the dirty space limit in bytes. @@ -1185,10 +1186,10 @@ benchmark results by reading this kstat file: .It Sy zfs_free_bpobj_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int Enable/disable the processing of the free_bpobj object. . -.It Sy zfs_async_block_max_blocks Ns = Ns Sy ULONG_MAX Po unlimited Pc Pq ulong +.It Sy zfs_async_block_max_blocks Ns = Ns Sy UINT64_MAX Po unlimited Pc Pq u64 Maximum number of blocks freed in a single TXG. . -.It Sy zfs_max_async_dedup_frees Ns = Ns Sy 100000 Po 10^5 Pc Pq ulong +.It Sy zfs_max_async_dedup_frees Ns = Ns Sy 100000 Po 10^5 Pc Pq u64 Maximum number of dedup blocks freed in a single TXG. . .It Sy zfs_vdev_async_read_max_active Ns = Ns Sy 3 Pq uint @@ -1444,22 +1445,22 @@ Similar to .Sy zfs_free_min_time_ms , but for cleanup of old indirection records for removed vdevs. . -.It Sy zfs_immediate_write_sz Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq long +.It Sy zfs_immediate_write_sz Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq s64 Largest data block to write to the ZIL. Larger blocks will be treated as if the dataset being written to had the .Sy logbias Ns = Ns Sy throughput property set. . -.It Sy zfs_initialize_value Ns = Ns Sy 16045690984833335022 Po 0xDEADBEEFDEADBEEE Pc Pq ulong +.It Sy zfs_initialize_value Ns = Ns Sy 16045690984833335022 Po 0xDEADBEEFDEADBEEE Pc Pq u64 Pattern written to vdev free space by .Xr zpool-initialize 8 . . -.It Sy zfs_initialize_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong +.It Sy zfs_initialize_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 Size of writes used by .Xr zpool-initialize 8 . This option is used by the test suite. . -.It Sy zfs_livelist_max_entries Ns = Ns Sy 500000 Po 5*10^5 Pc Pq ulong +.It Sy zfs_livelist_max_entries Ns = Ns Sy 500000 Po 5*10^5 Pc Pq u64 The threshold size (in block pointers) at which we create a new sub-livelist. Larger sublists are more costly from a memory perspective but the fewer sublists there are, the lower the cost of insertion. @@ -1498,11 +1499,11 @@ executing the open context condensing work in .Fn spa_livelist_condense_cb . This option is used by the test suite to trigger race conditions. . -.It Sy zfs_lua_max_instrlimit Ns = Ns Sy 100000000 Po 10^8 Pc Pq ulong +.It Sy zfs_lua_max_instrlimit Ns = Ns Sy 100000000 Po 10^8 Pc Pq u64 The maximum execution time limit that can be set for a ZFS channel program, specified as a number of Lua instructions. . -.It Sy zfs_lua_max_memlimit Ns = Ns Sy 104857600 Po 100 MiB Pc Pq ulong +.It Sy zfs_lua_max_memlimit Ns = Ns Sy 104857600 Po 100 MiB Pc Pq u64 The maximum memory limit that can be set for a ZFS channel program, specified in bytes. . @@ -1511,11 +1512,11 @@ The maximum depth of nested datasets. This value can be tuned temporarily to fix existing datasets that exceed the predefined limit. . -.It Sy zfs_max_log_walking Ns = Ns Sy 5 Pq ulong +.It Sy zfs_max_log_walking Ns = Ns Sy 5 Pq u64 The number of past TXGs that the flushing algorithm of the log spacemap feature uses to estimate incoming log blocks. . -.It Sy zfs_max_logsm_summary_length Ns = Ns Sy 10 Pq ulong +.It Sy zfs_max_logsm_summary_length Ns = Ns Sy 10 Pq u64 Maximum number of rows allowed in the summary of the spacemap log. . .It Sy zfs_max_recordsize Ns = Ns Sy 16777216 Po 16 MiB Pc Pq uint @@ -1534,7 +1535,7 @@ regardless of this setting. Allow datasets received with redacted send/receive to be mounted. Normally disabled because these datasets may be missing key data. . -.It Sy zfs_min_metaslabs_to_flush Ns = Ns Sy 1 Pq ulong +.It Sy zfs_min_metaslabs_to_flush Ns = Ns Sy 1 Pq u64 Minimum number of metaslabs to flush per dirty TXG. . .It Sy zfs_metaslab_fragmentation_threshold Ns = Ns Sy 70 Ns % Pq uint @@ -1584,7 +1585,7 @@ into the special allocation class. Historical statistics for this many latest multihost updates will be available in .Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /multihost . . -.It Sy zfs_multihost_interval Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq ulong +.It Sy zfs_multihost_interval Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq u64 Used to control the frequency of multihost writes which are performed when the .Sy multihost pool property is on. @@ -1677,7 +1678,7 @@ prefetched during a pool traversal, like .Nm zfs Cm send or other data crawling operations. . -.It Sy zfs_per_txg_dirty_frees_percent Ns = Ns Sy 30 Ns % Pq ulong +.It Sy zfs_per_txg_dirty_frees_percent Ns = Ns Sy 30 Ns % Pq u64 Control percentage of dirtied indirect blocks from frees allowed into one TXG. After this threshold is crossed, additional frees will wait until the next TXG. .Sy 0 No disables this throttle. @@ -1705,7 +1706,7 @@ Disable QAT hardware acceleration for AES-GCM encryption. May be unset after the ZFS modules have been loaded to initialize the QAT hardware as long as support is compiled in and the QAT driver is present. . -.It Sy zfs_vnops_read_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq long +.It Sy zfs_vnops_read_chunk_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 Bytes to read per chunk. . .It Sy zfs_read_history Ns = Ns Sy 0 Pq uint @@ -1715,7 +1716,7 @@ Historical statistics for this many latest reads will be available in .It Sy zfs_read_history_hits Ns = Ns Sy 0 Ns | Ns 1 Pq int Include cache hits in read history . -.It Sy zfs_rebuild_max_segment Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq ulong +.It Sy zfs_rebuild_max_segment Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 Maximum read segment size to issue when sequentially resilvering a top-level vdev. . @@ -1725,7 +1726,7 @@ completes in order to verify the checksums of all blocks which have been resilvered. This is enabled by default and strongly recommended. . -.It Sy zfs_rebuild_vdev_limit Ns = Ns Sy 33554432 Ns B Po 32 MiB Pc Pq ulong +.It Sy zfs_rebuild_vdev_limit Ns = Ns Sy 33554432 Ns B Po 32 MiB Pc Pq u64 Maximum amount of I/O that can be concurrently issued for a sequential resilver per leaf device, given in bytes. . @@ -2166,7 +2167,7 @@ if a volatile out-of-order write cache is enabled. Disable intent logging replay. Can be disabled for recovery from corrupted ZIL. . -.It Sy zil_slog_bulk Ns = Ns Sy 786432 Ns B Po 768 KiB Pc Pq ulong +.It Sy zil_slog_bulk Ns = Ns Sy 786432 Ns B Po 768 KiB Pc Pq u64 Limit SLOG write size per commit executed with synchronous priority. Any writes above that will be executed with lower (asynchronous) priority to limit potential SLOG device abuse by single active ZIL writer. @@ -2276,7 +2277,7 @@ systems with a very large number of zvols. .It Sy zvol_major Ns = Ns Sy 230 Pq uint Major number for zvol block devices. . -.It Sy zvol_max_discard_blocks Ns = Ns Sy 16384 Pq ulong +.It Sy zvol_max_discard_blocks Ns = Ns Sy 16384 Pq long Discard (TRIM) operations done on zvols will be done in batches of this many blocks, where block size is determined by the .Sy volblocksize diff --git a/man/man7/zfsprops.7 b/man/man7/zfsprops.7 index 803523adc3dc..3bd488a21792 100644 --- a/man/man7/zfsprops.7 +++ b/man/man7/zfsprops.7 @@ -36,8 +36,9 @@ .\" Copyright 2018 Nexenta Systems, Inc. .\" Copyright 2019 Joyent, Inc. .\" Copyright (c) 2019, Kjeld Schouten-Lebbing +.\" Copyright (c) 2022 Hewlett Packard Enterprise Development LP. .\" -.Dd May 24, 2021 +.Dd July 21, 2022 .Dt ZFSPROPS 7 .Os . @@ -1458,7 +1459,7 @@ affects only files created afterward; existing files are unaffected. .Pp This property can also be referred to by its shortened column name, .Sy recsize . -.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most +.It Sy redundant_metadata Ns = Ns Sy all Ns | Ns Sy most Ns | Ns Sy some Ns | Ns Sy none Controls what types of metadata are stored redundantly. ZFS stores an extra copy of metadata, so that if a single block is corrupted, the amount of user data lost is limited. @@ -1490,7 +1491,7 @@ When set to ZFS stores an extra copy of most types of metadata. This can improve performance of random writes, because less metadata must be written. -In practice, at worst about 100 blocks +In practice, at worst about 1000 blocks .Po of .Sy recordsize bytes each @@ -1499,6 +1500,17 @@ of user data can be lost if a single on-disk block is corrupt. The exact behavior of which metadata blocks are stored redundantly may change in future releases. .Pp +When set to +.Sy some , +ZFS stores an extra copy of only critical metadata. +This can improve file create performance since less metadata needs to be written. +If a single on-disk block is corrupt, at worst a single user file can be lost. +.Pp +When set to +.Sy none , +ZFS does not store any copies of metadata redundantly. +If a single on-disk block is corrupt, an entire dataset can be lost. +.Pp The default value is .Sy all . .It Sy refquota Ns = Ns Ar size Ns | Ns Sy none diff --git a/man/man8/zstream.8 b/man/man8/zstream.8 index dd5342000216..bfe7ac3f6535 100644 --- a/man/man8/zstream.8 +++ b/man/man8/zstream.8 @@ -20,7 +20,7 @@ .\" .\" Copyright (c) 2020 by Delphix. All rights reserved. .\" -.Dd March 25, 2022 +.Dd October 4, 2022 .Dt ZSTREAM 8 .Os . @@ -96,6 +96,7 @@ Specify the object number and byte offset of each record that you wish to decompress. Optionally specify the compression type. Valid compression types include +.Sy off , .Sy gzip , .Sy lz4 , .Sy lzjb , @@ -108,6 +109,11 @@ Every record for that object beginning at that offset will be decompressed, if possible. It may not be possible, because the record may be corrupted in some but not all of the stream's snapshots. +Specifying a compression type of +.Sy off +will change the stream's metadata accordingly, without attempting decompression. +This can be useful if the record is already uncompressed but the metadata +insists otherwise. The repaired stream will be written to standard output. .Bl -tag -width "-v" .It Fl v diff --git a/module/icp/algs/blake3/blake3.c b/module/icp/algs/blake3/blake3.c index 5f7018598820..604e05847ee6 100644 --- a/module/icp/algs/blake3/blake3.c +++ b/module/icp/algs/blake3/blake3.c @@ -189,9 +189,7 @@ static void chunk_state_update(const blake3_ops_t *ops, input_len -= BLAKE3_BLOCK_LEN; } - size_t take = chunk_state_fill_buf(ctx, input, input_len); - input += take; - input_len -= take; + chunk_state_fill_buf(ctx, input, input_len); } static output_t chunk_state_output(const blake3_chunk_state_t *ctx) diff --git a/module/icp/algs/modes/ccm.c b/module/icp/algs/modes/ccm.c index ed5498dafaa1..4a8bb9bbc2c8 100644 --- a/module/icp/algs/modes/ccm.c +++ b/module/icp/algs/modes/ccm.c @@ -67,7 +67,6 @@ ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length, return (CRYPTO_SUCCESS); } - lastp = (uint8_t *)ctx->ccm_cb; crypto_init_ptrs(out, &iov_or_mp, &offset); mac_buf = (uint8_t *)ctx->ccm_mac_buf; diff --git a/module/icp/algs/modes/ctr.c b/module/icp/algs/modes/ctr.c index c116ba3662ba..db6b1c71d5cd 100644 --- a/module/icp/algs/modes/ctr.c +++ b/module/icp/algs/modes/ctr.c @@ -60,7 +60,6 @@ ctr_mode_contiguous_blocks(ctr_ctx_t *ctx, char *data, size_t length, return (CRYPTO_SUCCESS); } - lastp = (uint8_t *)ctx->ctr_cb; crypto_init_ptrs(out, &iov_or_mp, &offset); do { diff --git a/module/icp/algs/modes/gcm.c b/module/icp/algs/modes/gcm.c index ca328d54a7e6..16ef14b8ccaf 100644 --- a/module/icp/algs/modes/gcm.c +++ b/module/icp/algs/modes/gcm.c @@ -118,7 +118,6 @@ gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *ctx, char *data, size_t length, return (CRYPTO_SUCCESS); } - lastp = (uint8_t *)ctx->gcm_cb; crypto_init_ptrs(out, &iov_or_mp, &offset); gops = gcm_impl_get_ops(); diff --git a/module/icp/algs/modes/modes.c b/module/icp/algs/modes/modes.c index b98db0ac14ec..2d1b5ff1a919 100644 --- a/module/icp/algs/modes/modes.c +++ b/module/icp/algs/modes/modes.c @@ -106,8 +106,10 @@ crypto_get_ptrs(crypto_data_t *out, void **iov_or_mp, offset_t *current_offset, } else { /* one block spans two iovecs */ *out_data_1_len = iov_len - offset; - if (vec_idx == zfs_uio_iovcnt(uio)) + if (vec_idx == zfs_uio_iovcnt(uio)) { + *out_data_2 = NULL; return; + } vec_idx++; zfs_uio_iov_at_index(uio, vec_idx, &iov_base, &iov_len); *out_data_2 = (uint8_t *)iov_base; diff --git a/module/icp/io/sha2_mod.c b/module/icp/io/sha2_mod.c index fadb58b81881..a58f0982c8c0 100644 --- a/module/icp/io/sha2_mod.c +++ b/module/icp/io/sha2_mod.c @@ -737,12 +737,15 @@ sha2_mac_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, */ if (mechanism->cm_type % 3 == 2) { if (mechanism->cm_param == NULL || - mechanism->cm_param_len != sizeof (ulong_t)) - ret = CRYPTO_MECHANISM_PARAM_INVALID; - PROV_SHA2_GET_DIGEST_LEN(mechanism, - PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len); - if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > sha_digest_len) + mechanism->cm_param_len != sizeof (ulong_t)) { ret = CRYPTO_MECHANISM_PARAM_INVALID; + } else { + PROV_SHA2_GET_DIGEST_LEN(mechanism, + PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len); + if (PROV_SHA2_HMAC_CTX(ctx)->hc_digest_len > + sha_digest_len) + ret = CRYPTO_MECHANISM_PARAM_INVALID; + } } if (ret != CRYPTO_SUCCESS) { diff --git a/module/lua/lapi.c b/module/lua/lapi.c index 726e5c2ad4bb..ed3a0f4cf9ec 100644 --- a/module/lua/lapi.c +++ b/module/lua/lapi.c @@ -250,6 +250,8 @@ LUA_API int lua_type (lua_State *L, int idx) { LUA_API const char *lua_typename (lua_State *L, int t) { UNUSED(L); + if (t > 8 || t < 0) + return "internal_type_error"; return ttypename(t); } diff --git a/module/lua/ldo.c b/module/lua/ldo.c index 24677596de12..6bef80514ce2 100644 --- a/module/lua/ldo.c +++ b/module/lua/ldo.c @@ -452,7 +452,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) { } res = ci->func; /* res == final position of 1st result */ wanted = ci->nresults; - L->ci = ci = ci->previous; /* back to caller */ + L->ci = ci->previous; /* back to caller */ /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); diff --git a/module/os/freebsd/zfs/sysctl_os.c b/module/os/freebsd/zfs/sysctl_os.c index 980bb1c0f941..48af1eaf8ea7 100644 --- a/module/os/freebsd/zfs/sysctl_os.c +++ b/module/os/freebsd/zfs/sysctl_os.c @@ -137,11 +137,11 @@ SYSCTL_CONST_STRING(_vfs_zfs_version, OID_AUTO, module, CTLFLAG_RD, /* arc.c */ int -param_set_arc_long(SYSCTL_HANDLER_ARGS) +param_set_arc_u64(SYSCTL_HANDLER_ARGS) { int err; - err = sysctl_handle_long(oidp, arg1, 0, req); + err = sysctl_handle_64(oidp, arg1, 0, req); if (err != 0 || req->newptr == NULL) return (err); @@ -171,7 +171,7 @@ param_set_arc_max(SYSCTL_HANDLER_ARGS) int err; val = zfs_arc_max; - err = sysctl_handle_long(oidp, &val, 0, req); + err = sysctl_handle_64(oidp, &val, 0, req); if (err != 0 || req->newptr == NULL) return (SET_ERROR(err)); @@ -203,7 +203,7 @@ param_set_arc_min(SYSCTL_HANDLER_ARGS) int err; val = zfs_arc_min; - err = sysctl_handle_long(oidp, &val, 0, req); + err = sysctl_handle_64(oidp, &val, 0, req); if (err != 0 || req->newptr == NULL) return (SET_ERROR(err)); @@ -599,7 +599,7 @@ param_set_multihost_interval(SYSCTL_HANDLER_ARGS) { int err; - err = sysctl_handle_long(oidp, &zfs_multihost_interval, 0, req); + err = sysctl_handle_64(oidp, &zfs_multihost_interval, 0, req); if (err != 0 || req->newptr == NULL) return (err); @@ -676,7 +676,7 @@ param_set_deadman_synctime(SYSCTL_HANDLER_ARGS) int err; val = zfs_deadman_synctime_ms; - err = sysctl_handle_long(oidp, &val, 0, req); + err = sysctl_handle_64(oidp, &val, 0, req); if (err != 0 || req->newptr == NULL) return (err); zfs_deadman_synctime_ms = val; @@ -693,7 +693,7 @@ param_set_deadman_ziotime(SYSCTL_HANDLER_ARGS) int err; val = zfs_deadman_ziotime_ms; - err = sysctl_handle_long(oidp, &val, 0, req); + err = sysctl_handle_64(oidp, &val, 0, req); if (err != 0 || req->newptr == NULL) return (err); zfs_deadman_ziotime_ms = val; @@ -761,11 +761,11 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, space_map_ibs, CTLFLAG_RWTUN, int param_set_min_auto_ashift(SYSCTL_HANDLER_ARGS) { - uint64_t val; + int val; int err; val = zfs_vdev_min_auto_ashift; - err = sysctl_handle_64(oidp, &val, 0, req); + err = sysctl_handle_int(oidp, &val, 0, req); if (err != 0 || req->newptr == NULL) return (SET_ERROR(err)); @@ -779,20 +779,20 @@ param_set_min_auto_ashift(SYSCTL_HANDLER_ARGS) /* BEGIN CSTYLED */ SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift, - CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, + CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &zfs_vdev_min_auto_ashift, sizeof (zfs_vdev_min_auto_ashift), - param_set_min_auto_ashift, "QU", + param_set_min_auto_ashift, "IU", "Min ashift used when creating new top-level vdev. (LEGACY)"); /* END CSTYLED */ int param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS) { - uint64_t val; + int val; int err; val = zfs_vdev_max_auto_ashift; - err = sysctl_handle_64(oidp, &val, 0, req); + err = sysctl_handle_int(oidp, &val, 0, req); if (err != 0 || req->newptr == NULL) return (SET_ERROR(err)); @@ -806,9 +806,9 @@ param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS) /* BEGIN CSTYLED */ SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift, - CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, + CTLTYPE_UINT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, &zfs_vdev_max_auto_ashift, sizeof (zfs_vdev_max_auto_ashift), - param_set_max_auto_ashift, "QU", + param_set_max_auto_ashift, "IU", "Max ashift used when optimizing for logical -> physical sector size on" " new top-level vdevs. (LEGACY)"); /* END CSTYLED */ diff --git a/module/os/freebsd/zfs/vdev_file.c b/module/os/freebsd/zfs/vdev_file.c index 73cc6aa48c0b..a65dfec86caf 100644 --- a/module/os/freebsd/zfs/vdev_file.c +++ b/module/os/freebsd/zfs/vdev_file.c @@ -40,8 +40,8 @@ static taskq_t *vdev_file_taskq; -static unsigned long vdev_file_logical_ashift = SPA_MINBLOCKSHIFT; -static unsigned long vdev_file_physical_ashift = SPA_MINBLOCKSHIFT; +static uint_t vdev_file_logical_ashift = SPA_MINBLOCKSHIFT; +static uint_t vdev_file_physical_ashift = SPA_MINBLOCKSHIFT; void vdev_file_init(void) @@ -350,7 +350,7 @@ vdev_ops_t vdev_disk_ops = { #endif -ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, UINT, ZMOD_RW, "Logical ashift for file-based devices"); -ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, UINT, ZMOD_RW, "Physical ashift for file-based devices"); diff --git a/module/os/freebsd/zfs/zfs_acl.c b/module/os/freebsd/zfs/zfs_acl.c index a85d4c24178b..c075e180a860 100644 --- a/module/os/freebsd/zfs/zfs_acl.c +++ b/module/os/freebsd/zfs/zfs_acl.c @@ -1619,7 +1619,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, */ int zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, - vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids) + vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns) { int error; zfsvfs_t *zfsvfs = dzp->z_zfsvfs; @@ -1789,7 +1789,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if (mask == 0) return (SET_ERROR(ENOSYS)); - if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr))) + if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr, NULL))) return (error); mutex_enter(&zp->z_acl_lock); @@ -1952,7 +1952,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if (zp->z_pflags & ZFS_IMMUTABLE) return (SET_ERROR(EPERM)); - if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr))) + if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL))) return (error); error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp, @@ -2341,7 +2341,8 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) * can define any form of access. */ int -zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) +zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr, + zuserns_t *mnt_ns) { uint32_t working_mode; int error; @@ -2471,9 +2472,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) * NFSv4-style ZFS ACL format and call zfs_zaccess() */ int -zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr) +zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr, + zuserns_t *mnt_ns) { - return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr)); + return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr, + mnt_ns)); } /* @@ -2484,7 +2487,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr) { int v4_mode = zfs_unix_to_v4(mode >> 6); - return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr)); + return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL)); } static int @@ -2540,7 +2543,7 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp, * */ int -zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) +zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns) { uint32_t dzp_working_mode = 0; uint32_t zp_working_mode = 0; @@ -2627,7 +2630,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) int zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, - znode_t *tzp, cred_t *cr) + znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns) { int add_perm; int error; @@ -2647,7 +2650,8 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, * to another. */ if (ZTOV(szp)->v_type == VDIR && ZTOV(sdzp) != ZTOV(tdzp)) { - if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr))) + if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr, + mnt_ns))) return (error); } @@ -2657,19 +2661,19 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, * If that succeeds then check for add_file/add_subdir permissions */ - if ((error = zfs_zaccess_delete(sdzp, szp, cr))) + if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns))) return (error); /* * If we have a tzp, see if we can delete it? */ - if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr))) + if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns))) return (error); /* * Now check for add permissions */ - error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr); + error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns); return (error); } diff --git a/module/os/freebsd/zfs/zfs_dir.c b/module/os/freebsd/zfs/zfs_dir.c index 778e4151656d..07232086d52b 100644 --- a/module/os/freebsd/zfs/zfs_dir.c +++ b/module/os/freebsd/zfs/zfs_dir.c @@ -809,7 +809,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xvpp, cred_t *cr) *xvpp = NULL; if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL, - &acl_ids)) != 0) + &acl_ids, NULL)) != 0) return (error); if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, 0)) { zfs_acl_ids_free(&acl_ids); @@ -955,7 +955,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr) if ((uid = crgetuid(cr)) == downer || uid == fowner || (ZTOV(zp)->v_type == VREG && - zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0)) + zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0)) return (0); else return (secpolicy_vnode_remove(ZTOV(zp), cr)); diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index fae390a148d6..362e02751ee4 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -837,7 +837,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, /* * Do we have permission to get into attribute directory? */ - error = zfs_zaccess(zp, ACE_EXECUTE, 0, B_FALSE, cr); + error = zfs_zaccess(zp, ACE_EXECUTE, 0, B_FALSE, cr, NULL); if (error) { vrele(ZTOV(zp)); } @@ -856,7 +856,8 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, cnp->cn_flags &= ~NOEXECCHECK; } else #endif - if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, + NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -1036,6 +1037,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, * flag - large file flag [UNUSED]. * ct - caller context * vsecp - ACL to be set + * mnt_ns - Unused on FreeBSD * * OUT: vpp - vnode of created or trunc'd entry. * @@ -1047,7 +1049,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, */ int zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode, - znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp) + znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp, zuserns_t *mnt_ns) { (void) excl, (void) mode, (void) flag; znode_t *zp; @@ -1110,7 +1112,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode, * Create a new file object and update the directory * to reference it. */ - if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) { goto out; } @@ -1126,7 +1128,7 @@ zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl, int mode, } if ((error = zfs_acl_ids_create(dzp, 0, vap, - cr, vsecp, &acl_ids)) != 0) + cr, vsecp, &acl_ids, NULL)) != 0) goto out; if (S_ISREG(vap->va_mode) || S_ISDIR(vap->va_mode)) @@ -1231,7 +1233,7 @@ zfs_remove_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr) xattr_obj = 0; xzp = NULL; - if ((error = zfs_zaccess_delete(dzp, zp, cr))) { + if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) { goto out; } @@ -1387,6 +1389,7 @@ zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags) * ct - caller context * flags - case flags * vsecp - ACL to be set + * mnt_ns - Unused on FreeBSD * * OUT: vpp - vnode of created directory. * @@ -1398,7 +1401,7 @@ zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags) */ int zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp, - cred_t *cr, int flags, vsecattr_t *vsecp) + cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns) { (void) flags, (void) vsecp; znode_t *zp; @@ -1447,7 +1450,7 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp, } if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, - NULL, &acl_ids)) != 0) { + NULL, &acl_ids, NULL)) != 0) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -1468,7 +1471,8 @@ zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap, znode_t **zpp, } ASSERT3P(zp, ==, NULL); - if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr, + mnt_ns))) { zfs_acl_ids_free(&acl_ids); zfs_exit(zfsvfs, FTAG); return (error); @@ -1585,7 +1589,7 @@ zfs_rmdir_(vnode_t *dvp, vnode_t *vp, const char *name, cred_t *cr) zilog = zfsvfs->z_log; - if ((error = zfs_zaccess_delete(dzp, zp, cr))) { + if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) { goto out; } @@ -1976,7 +1980,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr) if (!(zp->z_pflags & ZFS_ACL_TRIVIAL) && (vap->va_uid != crgetuid(cr))) { if ((error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, 0, - skipaclchk, cr))) { + skipaclchk, cr, NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -2142,7 +2146,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr) * flags - ATTR_UTIME set if non-default time values provided. * - ATTR_NOACLCHECK (CIFS context only). * cr - credentials of caller. - * ct - caller context + * mnt_ns - Unused on FreeBSD * * RETURN: 0 on success, error code on failure. * @@ -2150,7 +2154,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr) * vp - ctime updated, mtime updated if size changed. */ int -zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) +zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns) { vnode_t *vp = ZTOV(zp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; @@ -2322,7 +2326,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) XVA_ISSET_REQ(xvap, XAT_CREATETIME) || XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) { need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0, - skipaclchk, cr); + skipaclchk, cr, mnt_ns); } if (mask & (AT_UID|AT_GID)) { @@ -2359,7 +2363,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) ((idmask == AT_UID) && take_owner) || ((idmask == AT_GID) && take_group)) { if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0, - skipaclchk, cr) == 0) { + skipaclchk, cr, mnt_ns) == 0) { /* * Remove setuid/setgid for non-privileged users */ @@ -2468,7 +2472,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) } if (mask & AT_MODE) { - if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) { + if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, + mnt_ns) == 0) { err = secpolicy_setid_setsticky_clear(vp, vap, &oldva, cr); if (err) { @@ -3264,7 +3269,7 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp, * Note that if target and source are the same, this can be * done in a single check. */ - if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr))) + if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, NULL))) goto out; if ((*svpp)->v_type == VDIR) { @@ -3415,7 +3420,7 @@ zfs_do_rename_impl(vnode_t *sdvp, vnode_t **svpp, struct componentname *scnp, int zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname, - cred_t *cr, int flags) + cred_t *cr, int flags, zuserns_t *mnt_ns) { struct componentname scn, tcn; vnode_t *sdvp, *tdvp; @@ -3460,6 +3465,7 @@ zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname, * cr - credentials of caller. * ct - caller context * flags - case flags + * mnt_ns - Unused on FreeBSD * * RETURN: 0 on success, error code on failure. * @@ -3468,7 +3474,7 @@ zfs_rename(znode_t *sdzp, const char *sname, znode_t *tdzp, const char *tname, */ int zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap, - const char *link, znode_t **zpp, cred_t *cr, int flags) + const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns) { (void) flags; znode_t *zp; @@ -3499,7 +3505,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap, } if ((error = zfs_acl_ids_create(dzp, 0, - vap, cr, NULL, &acl_ids)) != 0) { + vap, cr, NULL, &acl_ids, NULL)) != 0) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -3514,7 +3520,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap, return (error); } - if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) { zfs_acl_ids_free(&acl_ids); zfs_exit(zfsvfs, FTAG); return (error); @@ -3730,7 +3736,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, const char *name, cred_t *cr, return (SET_ERROR(EPERM)); } - if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -3831,7 +3837,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag, * On Linux we can get here through truncate_range() which * operates directly on inodes, so we need to check access rights. */ - if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -4607,7 +4613,7 @@ zfs_freebsd_create(struct vop_create_args *ap) *ap->a_vpp = NULL; rc = zfs_create(VTOZ(ap->a_dvp), cnp->cn_nameptr, vap, 0, mode, - &zp, cnp->cn_cred, 0 /* flag */, NULL /* vsecattr */); + &zp, cnp->cn_cred, 0 /* flag */, NULL /* vsecattr */, NULL); if (rc == 0) *ap->a_vpp = ZTOV(zp); if (zfsvfs->z_use_namecache && @@ -4661,7 +4667,7 @@ zfs_freebsd_mkdir(struct vop_mkdir_args *ap) *ap->a_vpp = NULL; rc = zfs_mkdir(VTOZ(ap->a_dvp), ap->a_cnp->cn_nameptr, vap, &zp, - ap->a_cnp->cn_cred, 0, NULL); + ap->a_cnp->cn_cred, 0, NULL, NULL); if (rc == 0) *ap->a_vpp = ZTOV(zp); @@ -4914,7 +4920,7 @@ zfs_freebsd_setattr(struct vop_setattr_args *ap) xvap.xva_vattr.va_mask |= AT_XVATTR; XVA_SET_REQ(&xvap, XAT_CREATETIME); } - return (zfs_setattr(VTOZ(vp), (vattr_t *)&xvap, 0, cred)); + return (zfs_setattr(VTOZ(vp), (vattr_t *)&xvap, 0, cred, NULL)); } #ifndef _SYS_SYSPROTO_H_ @@ -4985,7 +4991,7 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap) *ap->a_vpp = NULL; rc = zfs_symlink(VTOZ(ap->a_dvp), cnp->cn_nameptr, vap, - ap->a_target, &zp, cnp->cn_cred, 0 /* flags */); + ap->a_target, &zp, cnp->cn_cred, 0 /* flags */, NULL); if (rc == 0) { *ap->a_vpp = ZTOV(zp); ASSERT_VOP_ELOCKED(ZTOV(zp), __func__); diff --git a/module/os/freebsd/zfs/zfs_znode.c b/module/os/freebsd/zfs/zfs_znode.c index 6345e9e69d30..6c269480cb4b 100644 --- a/module/os/freebsd/zfs/zfs_znode.c +++ b/module/os/freebsd/zfs/zfs_znode.c @@ -298,7 +298,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) sharezp->z_is_sa = zfsvfs->z_use_sa; VERIFY0(zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr, - kcred, NULL, &acl_ids)); + kcred, NULL, &acl_ids, NULL)); zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, &zp, &acl_ids); ASSERT3P(zp, ==, sharezp); POINTER_INVALIDATE(&sharezp->z_zfsvfs); @@ -1773,7 +1773,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) rootzp->z_zfsvfs = zfsvfs; VERIFY0(zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, - cr, NULL, &acl_ids)); + cr, NULL, &acl_ids, NULL)); zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids); ASSERT3P(zp, ==, rootzp); error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); @@ -1949,7 +1949,6 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, } else if (error != ENOENT) { return (error); } - error = 0; for (;;) { uint64_t pobj; diff --git a/module/os/freebsd/zfs/zio_crypt.c b/module/os/freebsd/zfs/zio_crypt.c index 0410ddd65a5c..c5e745f7d196 100644 --- a/module/os/freebsd/zfs/zio_crypt.c +++ b/module/os/freebsd/zfs/zio_crypt.c @@ -1735,7 +1735,6 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key, goto error; if (locked) { rw_exit(&key->zk_salt_lock); - locked = B_FALSE; } if (authbuf != NULL) diff --git a/module/os/linux/spl/spl-condvar.c b/module/os/linux/spl/spl-condvar.c index d0461a9f1298..e87954714e3a 100644 --- a/module/os/linux/spl/spl-condvar.c +++ b/module/os/linux/spl/spl-condvar.c @@ -37,7 +37,7 @@ #endif #define MAX_HRTIMEOUT_SLACK_US 1000 -unsigned int spl_schedule_hrtimeout_slack_us = 0; +static unsigned int spl_schedule_hrtimeout_slack_us = 0; static int param_set_hrtimeout_slack(const char *buf, zfs_kernel_param_t *kp) diff --git a/module/os/linux/spl/spl-err.c b/module/os/linux/spl/spl-err.c index 7d3f6127c4af..29781b9515b2 100644 --- a/module/os/linux/spl/spl-err.c +++ b/module/os/linux/spl/spl-err.c @@ -32,7 +32,7 @@ * analysis and other such goodies. * But we would still default to the current default of not to do that. */ -unsigned int spl_panic_halt; +static unsigned int spl_panic_halt; /* CSTYLED */ module_param(spl_panic_halt, uint, 0644); MODULE_PARM_DESC(spl_panic_halt, "Cause kernel panic on assertion failures"); diff --git a/module/os/linux/spl/spl-generic.c b/module/os/linux/spl/spl-generic.c index bc39ece9a427..e3aa900ba6dd 100644 --- a/module/os/linux/spl/spl-generic.c +++ b/module/os/linux/spl/spl-generic.c @@ -48,6 +48,7 @@ #include #include #include +#include unsigned long spl_hostid = 0; EXPORT_SYMBOL(spl_hostid); @@ -89,7 +90,7 @@ EXPORT_SYMBOL(p0); * and use them when in_interrupt() from linux/preempt_mask.h evaluates to * true. */ -void __percpu *spl_pseudo_entropy; +static void __percpu *spl_pseudo_entropy; /* * spl_rand_next()/spl_rand_jump() are copied from the following CC-0 licensed @@ -518,6 +519,29 @@ ddi_copyin(const void *from, void *to, size_t len, int flags) } EXPORT_SYMBOL(ddi_copyin); +#define define_spl_param(type, fmt) \ +int \ +spl_param_get_##type(char *buf, zfs_kernel_param_t *kp) \ +{ \ + return (scnprintf(buf, PAGE_SIZE, fmt "\n", \ + *(type *)kp->arg)); \ +} \ +int \ +spl_param_set_##type(const char *buf, zfs_kernel_param_t *kp) \ +{ \ + return (kstrto##type(buf, 0, (type *)kp->arg)); \ +} \ +const struct kernel_param_ops spl_param_ops_##type = { \ + .set = spl_param_set_##type, \ + .get = spl_param_get_##type, \ +}; \ +EXPORT_SYMBOL(spl_param_get_##type); \ +EXPORT_SYMBOL(spl_param_set_##type); \ +EXPORT_SYMBOL(spl_param_ops_##type); + +define_spl_param(s64, "%lld") +define_spl_param(u64, "%llu") + /* * Post a uevent to userspace whenever a new vdev adds to the pool. It is * necessary to sync blkid information with udev, which zed daemon uses diff --git a/module/os/linux/spl/spl-kmem-cache.c b/module/os/linux/spl/spl-kmem-cache.c index e355e2bfc3a0..edd04783b363 100644 --- a/module/os/linux/spl/spl-kmem-cache.c +++ b/module/os/linux/spl/spl-kmem-cache.c @@ -151,7 +151,7 @@ MODULE_PARM_DESC(spl_kmem_cache_kmem_threads, struct list_head spl_kmem_cache_list; /* List of caches */ struct rw_semaphore spl_kmem_cache_sem; /* Cache list lock */ -taskq_t *spl_kmem_cache_taskq; /* Task queue for aging / reclaim */ +static taskq_t *spl_kmem_cache_taskq; /* Task queue for aging / reclaim */ static void spl_cache_shrink(spl_kmem_cache_t *skc, void *obj); diff --git a/module/os/linux/spl/spl-procfs-list.c b/module/os/linux/spl/spl-procfs-list.c index a4a24dcae2bd..5e073950d61a 100644 --- a/module/os/linux/spl/spl-procfs-list.c +++ b/module/os/linux/spl/spl-procfs-list.c @@ -23,9 +23,9 @@ */ #include -#include #include #include +#include /* * A procfs_list is a wrapper around a linked list which implements the seq_file diff --git a/module/os/linux/spl/spl-zone.c b/module/os/linux/spl/spl-zone.c index 9421f81bf0c8..b489179f1257 100644 --- a/module/os/linux/spl/spl-zone.c +++ b/module/os/linux/spl/spl-zone.c @@ -25,7 +25,6 @@ */ #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #endif +#include + static kmutex_t zone_datasets_lock; static struct list_head zone_datasets; diff --git a/module/os/linux/zfs/abd_os.c b/module/os/linux/zfs/abd_os.c index 2ab85f8cccd0..e9b28becf6a0 100644 --- a/module/os/linux/zfs/abd_os.c +++ b/module/os/linux/zfs/abd_os.c @@ -132,7 +132,7 @@ static abd_stats_t abd_stats = { { "scatter_sg_table_retry", KSTAT_DATA_UINT64 }, }; -struct { +static struct { wmsum_t abdstat_struct_size; wmsum_t abdstat_linear_cnt; wmsum_t abdstat_linear_data_size; @@ -597,10 +597,8 @@ abd_free_chunks(abd_t *abd) struct scatterlist *sg; abd_for_each_sg(abd, sg, n, i) { - for (int j = 0; j < sg->length; j += PAGESIZE) { - struct page *p = nth_page(sg_page(sg), j >> PAGE_SHIFT); - umem_free(p, PAGESIZE); - } + struct page *p = nth_page(sg_page(sg), 0); + umem_free(p, PAGESIZE); } abd_free_sg_table(abd); } diff --git a/module/os/linux/zfs/arc_os.c b/module/os/linux/zfs/arc_os.c index 2fc47ddd1329..68d4fbaadb20 100644 --- a/module/os/linux/zfs/arc_os.c +++ b/module/os/linux/zfs/arc_os.c @@ -336,11 +336,11 @@ arc_lowmem_fini(void) } int -param_set_arc_long(const char *buf, zfs_kernel_param_t *kp) +param_set_arc_u64(const char *buf, zfs_kernel_param_t *kp) { int error; - error = param_set_long(buf, kp); + error = spl_param_set_u64(buf, kp); if (error < 0) return (SET_ERROR(error)); @@ -352,13 +352,13 @@ param_set_arc_long(const char *buf, zfs_kernel_param_t *kp) int param_set_arc_min(const char *buf, zfs_kernel_param_t *kp) { - return (param_set_arc_long(buf, kp)); + return (param_set_arc_u64(buf, kp)); } int param_set_arc_max(const char *buf, zfs_kernel_param_t *kp) { - return (param_set_arc_long(buf, kp)); + return (param_set_arc_u64(buf, kp)); } int diff --git a/module/os/linux/zfs/mmp_os.c b/module/os/linux/zfs/mmp_os.c index d502127b5ba3..7e5bd392437e 100644 --- a/module/os/linux/zfs/mmp_os.c +++ b/module/os/linux/zfs/mmp_os.c @@ -30,7 +30,7 @@ param_set_multihost_interval(const char *val, zfs_kernel_param_t *kp) { int ret; - ret = param_set_ulong(val, kp); + ret = spl_param_set_u64(val, kp); if (ret < 0) return (ret); diff --git a/module/os/linux/zfs/policy.c b/module/os/linux/zfs/policy.c index a69618978622..50eb7cfaa61c 100644 --- a/module/os/linux/zfs/policy.c +++ b/module/os/linux/zfs/policy.c @@ -214,8 +214,9 @@ secpolicy_vnode_setid_retain(struct znode *zp __maybe_unused, const cred_t *cr, * Determine that subject can set the file setgid flag. */ int -secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid) +secpolicy_vnode_setids_setgids(const cred_t *cr, gid_t gid, zuserns_t *mnt_ns) { + gid = zfs_gid_into_mnt(mnt_ns, gid); #if defined(CONFIG_USER_NS) if (!kgid_has_mapping(cr->user_ns, SGID_TO_KGID(gid))) return (EPERM); @@ -284,8 +285,10 @@ secpolicy_setid_clear(vattr_t *vap, cred_t *cr) * Determine that subject can set the file setid flags. */ static int -secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner) +secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner, zuserns_t *mnt_ns) { + owner = zfs_uid_into_mnt(mnt_ns, owner); + if (crgetuid(cr) == owner) return (0); @@ -310,13 +313,13 @@ secpolicy_vnode_stky_modify(const cred_t *cr) int secpolicy_setid_setsticky_clear(struct inode *ip, vattr_t *vap, - const vattr_t *ovap, cred_t *cr) + const vattr_t *ovap, cred_t *cr, zuserns_t *mnt_ns) { int error; if ((vap->va_mode & S_ISUID) != 0 && (error = secpolicy_vnode_setid_modify(cr, - ovap->va_uid)) != 0) { + ovap->va_uid, mnt_ns)) != 0) { return (error); } @@ -334,7 +337,7 @@ secpolicy_setid_setsticky_clear(struct inode *ip, vattr_t *vap, * group-id bit. */ if ((vap->va_mode & S_ISGID) != 0 && - secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) { + secpolicy_vnode_setids_setgids(cr, ovap->va_gid, mnt_ns) != 0) { vap->va_mode &= ~S_ISGID; } diff --git a/module/os/linux/zfs/spa_misc_os.c b/module/os/linux/zfs/spa_misc_os.c index f999df3b7db9..3efc8b9644fd 100644 --- a/module/os/linux/zfs/spa_misc_os.c +++ b/module/os/linux/zfs/spa_misc_os.c @@ -60,7 +60,7 @@ param_set_deadman_ziotime(const char *val, zfs_kernel_param_t *kp) { int error; - error = param_set_ulong(val, kp); + error = spl_param_set_u64(val, kp); if (error < 0) return (SET_ERROR(error)); @@ -74,7 +74,7 @@ param_set_deadman_synctime(const char *val, zfs_kernel_param_t *kp) { int error; - error = param_set_ulong(val, kp); + error = spl_param_set_u64(val, kp); if (error < 0) return (SET_ERROR(error)); diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c index d976e3a067ad..4bbd18b66a29 100644 --- a/module/os/linux/zfs/vdev_disk.c +++ b/module/os/linux/zfs/vdev_disk.c @@ -1006,17 +1006,17 @@ MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler"); int param_set_min_auto_ashift(const char *buf, zfs_kernel_param_t *kp) { - uint64_t val; + uint_t val; int error; - error = kstrtoull(buf, 0, &val); + error = kstrtouint(buf, 0, &val); if (error < 0) return (SET_ERROR(error)); if (val < ASHIFT_MIN || val > zfs_vdev_max_auto_ashift) return (SET_ERROR(-EINVAL)); - error = param_set_ulong(buf, kp); + error = param_set_uint(buf, kp); if (error < 0) return (SET_ERROR(error)); @@ -1026,17 +1026,17 @@ param_set_min_auto_ashift(const char *buf, zfs_kernel_param_t *kp) int param_set_max_auto_ashift(const char *buf, zfs_kernel_param_t *kp) { - uint64_t val; + uint_t val; int error; - error = kstrtoull(buf, 0, &val); + error = kstrtouint(buf, 0, &val); if (error < 0) return (SET_ERROR(error)); if (val > ASHIFT_MAX || val < zfs_vdev_min_auto_ashift) return (SET_ERROR(-EINVAL)); - error = param_set_ulong(buf, kp); + error = param_set_uint(buf, kp); if (error < 0) return (SET_ERROR(error)); diff --git a/module/os/linux/zfs/vdev_file.c b/module/os/linux/zfs/vdev_file.c index 46e412f6eeb4..5abc0426d1a7 100644 --- a/module/os/linux/zfs/vdev_file.c +++ b/module/os/linux/zfs/vdev_file.c @@ -53,8 +53,8 @@ static taskq_t *vdev_file_taskq; * impact the vdev_ashift setting which can only be set at vdev creation * time. */ -static unsigned long vdev_file_logical_ashift = SPA_MINBLOCKSHIFT; -static unsigned long vdev_file_physical_ashift = SPA_MINBLOCKSHIFT; +static uint_t vdev_file_logical_ashift = SPA_MINBLOCKSHIFT; +static uint_t vdev_file_physical_ashift = SPA_MINBLOCKSHIFT; static void vdev_file_hold(vdev_t *vd) @@ -376,7 +376,7 @@ vdev_ops_t vdev_disk_ops = { #endif -ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, logical_ashift, UINT, ZMOD_RW, "Logical ashift for file-based devices"); -ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_vdev_file, vdev_file_, physical_ashift, UINT, ZMOD_RW, "Physical ashift for file-based devices"); diff --git a/module/os/linux/zfs/zfs_acl.c b/module/os/linux/zfs/zfs_acl.c index d5cd5de890ab..d04034490758 100644 --- a/module/os/linux/zfs/zfs_acl.c +++ b/module/os/linux/zfs/zfs_acl.c @@ -1802,7 +1802,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, umode_t va_mode, zfs_acl_t *paclp, */ int zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, - vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids) + vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns) { int error; zfsvfs_t *zfsvfs = ZTOZSB(dzp); @@ -1889,8 +1889,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, acl_ids->z_mode |= S_ISGID; } else { if ((acl_ids->z_mode & S_ISGID) && - secpolicy_vnode_setids_setgids(cr, gid) != 0) + secpolicy_vnode_setids_setgids(cr, gid, mnt_ns) != 0) { acl_ids->z_mode &= ~S_ISGID; + } } if (acl_ids->z_aclp == NULL) { @@ -1978,7 +1979,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if (mask == 0) return (SET_ERROR(ENOSYS)); - if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr))) + if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr, NULL))) return (error); mutex_enter(&zp->z_acl_lock); @@ -2137,7 +2138,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) if (zp->z_pflags & ZFS_IMMUTABLE) return (SET_ERROR(EPERM)); - if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr))) + if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL))) return (error); error = zfs_vsec_2_aclp(zfsvfs, ZTOI(zp)->i_mode, vsecp, cr, &fuidp, @@ -2283,7 +2284,7 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode) */ static int zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, - boolean_t anyaccess, cred_t *cr) + boolean_t anyaccess, cred_t *cr, zuserns_t *mnt_ns) { zfsvfs_t *zfsvfs = ZTOZSB(zp); zfs_acl_t *aclp; @@ -2299,7 +2300,13 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, uid_t gowner; uid_t fowner; - zfs_fuid_map_ids(zp, cr, &fowner, &gowner); + if (mnt_ns) { + fowner = zfs_uid_into_mnt(mnt_ns, + KUID_TO_SUID(ZTOI(zp)->i_uid)); + gowner = zfs_gid_into_mnt(mnt_ns, + KGID_TO_SGID(ZTOI(zp)->i_gid)); + } else + zfs_fuid_map_ids(zp, cr, &fowner, &gowner); mutex_enter(&zp->z_acl_lock); @@ -2410,7 +2417,7 @@ zfs_has_access(znode_t *zp, cred_t *cr) { uint32_t have = ACE_ALL_PERMS; - if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) { + if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr, NULL) != 0) { uid_t owner; owner = zfs_fuid_map_id(ZTOZSB(zp), @@ -2440,7 +2447,8 @@ zfs_has_access(znode_t *zp, cred_t *cr) * we want to avoid that here. */ static int -zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr) +zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr, + zuserns_t *mnt_ns) { int err, mask; int unmapped = 0; @@ -2454,7 +2462,10 @@ zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr) } #if defined(HAVE_IOPS_PERMISSION_USERNS) - err = generic_permission(cr->user_ns, ZTOI(zp), mask); + if (mnt_ns) + err = generic_permission(mnt_ns, ZTOI(zp), mask); + else + err = generic_permission(cr->user_ns, ZTOI(zp), mask); #else err = generic_permission(ZTOI(zp), mask); #endif @@ -2469,7 +2480,7 @@ zfs_zaccess_trivial(znode_t *zp, uint32_t *working_mode, cred_t *cr) static int zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, - boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr) + boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr, zuserns_t *mnt_ns) { zfsvfs_t *zfsvfs = ZTOZSB(zp); int err; @@ -2519,20 +2530,20 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, } if (zp->z_pflags & ZFS_ACL_TRIVIAL) - return (zfs_zaccess_trivial(zp, working_mode, cr)); + return (zfs_zaccess_trivial(zp, working_mode, cr, mnt_ns)); - return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr)); + return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr, mnt_ns)); } static int zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs, - cred_t *cr) + cred_t *cr, zuserns_t *mnt_ns) { if (*working_mode != ACE_WRITE_DATA) return (SET_ERROR(EACCES)); return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode, - check_privs, B_FALSE, cr)); + check_privs, B_FALSE, cr, mnt_ns)); } int @@ -2599,7 +2610,7 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) DTRACE_PROBE(zfs__fastpath__execute__access__miss); if ((error = zfs_enter(ZTOZSB(zdp), FTAG)) != 0) return (error); - error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); + error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, NULL); zfs_exit(ZTOZSB(zdp), FTAG); return (error); } @@ -2611,7 +2622,8 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr) * can define any form of access. */ int -zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) +zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr, + zuserns_t *mnt_ns) { uint32_t working_mode; int error; @@ -2650,8 +2662,9 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) } } - owner = zfs_fuid_map_id(ZTOZSB(zp), KUID_TO_SUID(ZTOI(zp)->i_uid), - cr, ZFS_OWNER); + owner = zfs_uid_into_mnt(mnt_ns, KUID_TO_SUID(ZTOI(zp)->i_uid)); + owner = zfs_fuid_map_id(ZTOZSB(zp), owner, cr, ZFS_OWNER); + /* * Map the bits required to the standard inode flags * S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits @@ -2676,7 +2689,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) needed_bits |= S_IXUSR; if ((error = zfs_zaccess_common(check_zp, mode, &working_mode, - &check_privs, skipaclchk, cr)) == 0) { + &check_privs, skipaclchk, cr, mnt_ns)) == 0) { if (is_attr) zrele(xzp); return (secpolicy_vnode_access2(cr, ZTOI(zp), owner, @@ -2690,7 +2703,8 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) } if (error && (flags & V_APPEND)) { - error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr); + error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr, + mnt_ns); } if (error && check_privs) { @@ -2757,9 +2771,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) * NFSv4-style ZFS ACL format and call zfs_zaccess() */ int -zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr) +zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr, + zuserns_t *mnt_ns) { - return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr)); + return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr, + mnt_ns)); } /* @@ -2770,7 +2786,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr) { int v4_mode = zfs_unix_to_v4(mode >> 6); - return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr)); + return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL)); } /* See zfs_zaccess_delete() */ @@ -2847,7 +2863,7 @@ static const boolean_t zfs_write_implies_delete_child = B_TRUE; * zfs_write_implies_delete_child */ int -zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) +zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns) { uint32_t wanted_dirperms; uint32_t dzp_working_mode = 0; @@ -2874,7 +2890,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) * (This is part of why we're checking the target first.) */ zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode, - &zpcheck_privs, B_FALSE, cr); + &zpcheck_privs, B_FALSE, cr, mnt_ns); if (zp_error == EACCES) { /* We hit a DENY ACE. */ if (!zpcheck_privs) @@ -2896,7 +2912,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) if (zfs_write_implies_delete_child) wanted_dirperms |= ACE_WRITE_DATA; dzp_error = zfs_zaccess_common(dzp, wanted_dirperms, - &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr); + &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr, mnt_ns); if (dzp_error == EACCES) { /* We hit a DENY ACE. */ if (!dzpcheck_privs) @@ -2978,7 +2994,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) int zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, - znode_t *tzp, cred_t *cr) + znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns) { int add_perm; int error; @@ -3000,21 +3016,21 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, * If that succeeds then check for add_file/add_subdir permissions */ - if ((error = zfs_zaccess_delete(sdzp, szp, cr))) + if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns))) return (error); /* * If we have a tzp, see if we can delete it? */ if (tzp) { - if ((error = zfs_zaccess_delete(tdzp, tzp, cr))) + if ((error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns))) return (error); } /* * Now check for add permissions */ - error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr); + error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns); return (error); } diff --git a/module/os/linux/zfs/zfs_debug.c b/module/os/linux/zfs/zfs_debug.c index 819416b68d5f..e5a600250659 100644 --- a/module/os/linux/zfs/zfs_debug.c +++ b/module/os/linux/zfs/zfs_debug.c @@ -35,7 +35,7 @@ typedef struct zfs_dbgmsg { static procfs_list_t zfs_dbgmsgs; static uint_t zfs_dbgmsg_size = 0; -uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */ +static uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */ /* * Internal ZFS debug messages are enabled by default. diff --git a/module/os/linux/zfs/zfs_dir.c b/module/os/linux/zfs/zfs_dir.c index 6738d237b923..611a2471dd94 100644 --- a/module/os/linux/zfs/zfs_dir.c +++ b/module/os/linux/zfs/zfs_dir.c @@ -1066,11 +1066,12 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr) *xzpp = NULL; - if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr))) + if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr, + NULL))) return (error); if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL, - &acl_ids)) != 0) + &acl_ids, NULL)) != 0) return (error); if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, zp->z_projid)) { zfs_acl_ids_free(&acl_ids); @@ -1218,7 +1219,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr) cr, ZFS_OWNER); if ((uid = crgetuid(cr)) == downer || uid == fowner || - zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0) + zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0) return (0); else return (secpolicy_vnode_remove(cr)); diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index 64d6b4616e1c..7b682e49d84e 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -1556,6 +1556,7 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent) error = zfs_root(zfsvfs, &root_inode); if (error) { (void) zfs_umount(sb); + zfsvfs = NULL; /* avoid double-free; first in zfs_umount */ goto out; } @@ -1563,6 +1564,7 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent) sb->s_root = d_make_root(root_inode); if (sb->s_root == NULL) { (void) zfs_umount(sb); + zfsvfs = NULL; /* avoid double-free; first in zfs_umount */ error = SET_ERROR(ENOMEM); goto out; } diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c index 1ff88c121a79..9160f3e77390 100644 --- a/module/os/linux/zfs/zfs_vnops_os.c +++ b/module/os/linux/zfs/zfs_vnops_os.c @@ -476,7 +476,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr, */ if ((error = zfs_zaccess(*zpp, ACE_EXECUTE, 0, - B_TRUE, cr))) { + B_TRUE, cr, NULL))) { zrele(*zpp); *zpp = NULL; } @@ -494,7 +494,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr, * Check accessibility of directory. */ - if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr, NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -526,6 +526,7 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr, * cr - credentials of caller. * flag - file flag. * vsecp - ACL to be set + * mnt_ns - user namespace of the mount * * OUT: zpp - znode of created or trunc'd entry. * @@ -537,7 +538,8 @@ zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags, cred_t *cr, */ int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, - int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp) + int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp, + zuserns_t *mnt_ns) { znode_t *zp; zfsvfs_t *zfsvfs = ZTOZSB(dzp); @@ -624,7 +626,8 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, * Create a new file object and update the directory * to reference it. */ - if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, + mnt_ns))) { if (have_acl) zfs_acl_ids_free(&acl_ids); goto out; @@ -643,7 +646,7 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, } if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap, - cr, vsecp, &acl_ids)) != 0) + cr, vsecp, &acl_ids, mnt_ns)) != 0) goto out; have_acl = B_TRUE; @@ -738,7 +741,8 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, /* * Verify requested access to file. */ - if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr))) { + if (mode && (error = zfs_zaccess_rwx(zp, mode, aflags, cr, + mnt_ns))) { goto out; } @@ -782,7 +786,8 @@ zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl, int zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl, - int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp) + int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp, + zuserns_t *mnt_ns) { (void) excl, (void) mode, (void) flag; znode_t *zp = NULL, *dzp = ITOZ(dip); @@ -829,14 +834,14 @@ zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl, * Create a new file object and update the directory * to reference it. */ - if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) { if (have_acl) zfs_acl_ids_free(&acl_ids); goto out; } if (!have_acl && (error = zfs_acl_ids_create(dzp, 0, vap, - cr, vsecp, &acl_ids)) != 0) + cr, vsecp, &acl_ids, mnt_ns)) != 0) goto out; have_acl = B_TRUE; @@ -967,7 +972,7 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags) return (error); } - if ((error = zfs_zaccess_delete(dzp, zp, cr))) { + if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) { goto out; } @@ -1147,6 +1152,7 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags) * cr - credentials of caller. * flags - case flags. * vsecp - ACL to be set + * mnt_ns - user namespace of the mount * * OUT: zpp - znode of created directory. * @@ -1159,7 +1165,7 @@ zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags) */ int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp, - cred_t *cr, int flags, vsecattr_t *vsecp) + cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns) { znode_t *zp; zfsvfs_t *zfsvfs = ZTOZSB(dzp); @@ -1216,7 +1222,7 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp, } if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, - vsecp, &acl_ids)) != 0) { + vsecp, &acl_ids, mnt_ns)) != 0) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -1237,7 +1243,8 @@ zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp, return (error); } - if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr, + mnt_ns))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); zfs_exit(zfsvfs, FTAG); @@ -1379,7 +1386,7 @@ zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, cred_t *cr, return (error); } - if ((error = zfs_zaccess_delete(dzp, zp, cr))) { + if ((error = zfs_zaccess_delete(dzp, zp, cr, NULL))) { goto out; } @@ -1811,6 +1818,7 @@ zfs_setattr_dir(znode_t *dzp) * flags - ATTR_UTIME set if non-default time values provided. * - ATTR_NOACLCHECK (CIFS context only). * cr - credentials of caller. + * mnt_ns - user namespace of the mount * * RETURN: 0 if success * error code if failure @@ -1819,7 +1827,7 @@ zfs_setattr_dir(znode_t *dzp) * ip - ctime updated, mtime updated if size changed. */ int -zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) +zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zuserns_t *mnt_ns) { struct inode *ip; zfsvfs_t *zfsvfs = ZTOZSB(zp); @@ -1968,7 +1976,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) */ if (mask & ATTR_SIZE) { - err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr); + err = zfs_zaccess(zp, ACE_WRITE_DATA, 0, skipaclchk, cr, + mnt_ns); if (err) goto out3; @@ -1993,13 +2002,15 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) XVA_ISSET_REQ(xvap, XAT_CREATETIME) || XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) { need_policy = zfs_zaccess(zp, ACE_WRITE_ATTRIBUTES, 0, - skipaclchk, cr); + skipaclchk, cr, mnt_ns); } if (mask & (ATTR_UID|ATTR_GID)) { int idmask = (mask & (ATTR_UID|ATTR_GID)); int take_owner; int take_group; + uid_t uid; + gid_t gid; /* * NOTE: even if a new mode is being set, @@ -2013,9 +2024,13 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) * Take ownership or chgrp to group we are a member of */ - take_owner = (mask & ATTR_UID) && (vap->va_uid == crgetuid(cr)); + uid = zfs_uid_into_mnt((struct user_namespace *)mnt_ns, + vap->va_uid); + gid = zfs_gid_into_mnt((struct user_namespace *)mnt_ns, + vap->va_gid); + take_owner = (mask & ATTR_UID) && (uid == crgetuid(cr)); take_group = (mask & ATTR_GID) && - zfs_groupmember(zfsvfs, vap->va_gid, cr); + zfs_groupmember(zfsvfs, gid, cr); /* * If both ATTR_UID and ATTR_GID are set then take_owner and @@ -2031,7 +2046,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) ((idmask == ATTR_UID) && take_owner) || ((idmask == ATTR_GID) && take_group)) { if (zfs_zaccess(zp, ACE_WRITE_OWNER, 0, - skipaclchk, cr) == 0) { + skipaclchk, cr, mnt_ns) == 0) { /* * Remove setuid/setgid for non-privileged users */ @@ -2144,12 +2159,12 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr) mutex_exit(&zp->z_lock); if (mask & ATTR_MODE) { - if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr) == 0) { + if (zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, + mnt_ns) == 0) { err = secpolicy_setid_setsticky_clear(ip, vap, - &oldva, cr); + &oldva, cr, mnt_ns); if (err) goto out3; - trim_mask |= ATTR_MODE; } else { need_policy = TRUE; @@ -2640,6 +2655,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp) * tnm - New entry name. * cr - credentials of caller. * flags - case flags + * mnt_ns - user namespace of the mount * * RETURN: 0 on success, error code on failure. * @@ -2648,7 +2664,7 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp) */ int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm, - cred_t *cr, int flags) + cred_t *cr, int flags, zuserns_t *mnt_ns) { znode_t *szp, *tzp; zfsvfs_t *zfsvfs = ZTOZSB(sdzp); @@ -2841,7 +2857,7 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm, * done in a single check. */ - if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr))) + if ((error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr, mnt_ns))) goto out; if (S_ISDIR(ZTOI(szp)->i_mode)) { @@ -3008,6 +3024,7 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm, * link - Name for new symlink entry. * cr - credentials of caller. * flags - case flags + * mnt_ns - user namespace of the mount * * OUT: zpp - Znode for new symbolic link. * @@ -3018,7 +3035,7 @@ zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm, */ int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link, - znode_t **zpp, cred_t *cr, int flags) + znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns) { znode_t *zp; zfs_dirlock_t *dl; @@ -3056,7 +3073,7 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link, } if ((error = zfs_acl_ids_create(dzp, 0, - vap, cr, NULL, &acl_ids)) != 0) { + vap, cr, NULL, &acl_ids, mnt_ns)) != 0) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -3073,7 +3090,7 @@ zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link, return (error); } - if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr, mnt_ns))) { zfs_acl_ids_free(&acl_ids); zfs_dirent_unlock(dl); zfs_exit(zfsvfs, FTAG); @@ -3325,7 +3342,7 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr, return (SET_ERROR(EPERM)); } - if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr, NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } @@ -3951,7 +3968,7 @@ zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag, * On Linux we can get here through truncate_range() which * operates directly on inodes, so we need to check access rights. */ - if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) { + if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL))) { zfs_exit(zfsvfs, FTAG); return (error); } diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c index 73c21b6c00a8..9aeffba86150 100644 --- a/module/os/linux/zfs/zfs_znode.c +++ b/module/os/linux/zfs/zfs_znode.c @@ -1960,7 +1960,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) } VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, - cr, NULL, &acl_ids)); + cr, NULL, &acl_ids, NULL)); zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids); ASSERT3P(zp, ==, rootzp); error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); @@ -2136,7 +2136,6 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl, } else if (error != ENOENT) { return (error); } - error = 0; for (;;) { uint64_t pobj = 0; diff --git a/module/os/linux/zfs/zio_crypt.c b/module/os/linux/zfs/zio_crypt.c index 2bc1482e91ec..6f2bf7ed7569 100644 --- a/module/os/linux/zfs/zio_crypt.c +++ b/module/os/linux/zfs/zio_crypt.c @@ -1968,7 +1968,6 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key, if (locked) { rw_exit(&key->zk_salt_lock); - locked = B_FALSE; } if (authbuf != NULL) diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c index 837629e4a5e0..8bc4a9b39f22 100644 --- a/module/os/linux/zfs/zpl_ctldir.c +++ b/module/os/linux/zfs/zpl_ctldir.c @@ -371,7 +371,11 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) crhold(cr); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); - zpl_vap_init(vap, dip, mode | S_IFDIR, cr); +#ifdef HAVE_IOPS_MKDIR_USERNS + zpl_vap_init(vap, dip, mode | S_IFDIR, cr, user_ns); +#else + zpl_vap_init(vap, dip, mode | S_IFDIR, cr, NULL); +#endif error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0); if (error == 0) { diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c index 6b76b2162c5e..27af3acec357 100644 --- a/module/os/linux/zfs/zpl_file.c +++ b/module/os/linux/zfs/zpl_file.c @@ -1085,7 +1085,7 @@ zpl_ioctl_setflags(struct file *filp, void __user *arg) crhold(cr); cookie = spl_fstrans_mark(); - err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr); + err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, NULL); spl_fstrans_unmark(cookie); crfree(cr); @@ -1133,7 +1133,7 @@ zpl_ioctl_setxattr(struct file *filp, void __user *arg) crhold(cr); cookie = spl_fstrans_mark(); - err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr); + err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, NULL); spl_fstrans_unmark(cookie); crfree(cr); @@ -1221,7 +1221,7 @@ zpl_ioctl_setdosflags(struct file *filp, void __user *arg) crhold(cr); cookie = spl_fstrans_mark(); - err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr); + err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr, NULL); spl_fstrans_unmark(cookie); crfree(cr); diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c index 7578753ed8ce..8d073ff8cbd3 100644 --- a/module/os/linux/zfs/zpl_inode.c +++ b/module/os/linux/zfs/zpl_inode.c @@ -33,7 +33,6 @@ #include #include - static struct dentry * zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { @@ -112,18 +111,22 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) } void -zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr) +zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr, + zuserns_t *mnt_ns) { vap->va_mask = ATTR_MODE; vap->va_mode = mode; - vap->va_uid = crgetuid(cr); + + vap->va_uid = zfs_uid_from_mnt((struct user_namespace *)mnt_ns, + crgetuid(cr)); if (dir && dir->i_mode & S_ISGID) { vap->va_gid = KGID_TO_SGID(dir->i_gid); if (S_ISDIR(mode)) vap->va_mode |= S_ISGID; } else { - vap->va_gid = crgetgid(cr); + vap->va_gid = zfs_gid_from_mnt((struct user_namespace *)mnt_ns, + crgetgid(cr)); } } @@ -140,14 +143,17 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag) vattr_t *vap; int error; fstrans_cookie_t cookie; +#ifndef HAVE_IOPS_CREATE_USERNS + zuserns_t *user_ns = NULL; +#endif crhold(cr); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); - zpl_vap_init(vap, dir, mode, cr); + zpl_vap_init(vap, dir, mode, cr, user_ns); cookie = spl_fstrans_mark(); error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0, - mode, &zp, cr, 0, NULL); + mode, &zp, cr, 0, NULL, user_ns); if (error == 0) { error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error == 0) @@ -184,6 +190,9 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, vattr_t *vap; int error; fstrans_cookie_t cookie; +#ifndef HAVE_IOPS_MKNOD_USERNS + zuserns_t *user_ns = NULL; +#endif /* * We currently expect Linux to supply rdev=0 for all sockets @@ -194,12 +203,12 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, crhold(cr); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); - zpl_vap_init(vap, dir, mode, cr); + zpl_vap_init(vap, dir, mode, cr, user_ns); vap->va_rdev = rdev; cookie = spl_fstrans_mark(); error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0, - mode, &zp, cr, 0, NULL); + mode, &zp, cr, 0, NULL, user_ns); if (error == 0) { error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error == 0) @@ -236,6 +245,9 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) vattr_t *vap; int error; fstrans_cookie_t cookie; +#ifndef HAVE_TMPFILE_USERNS + zuserns_t *userns = NULL; +#endif crhold(cr); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); @@ -245,10 +257,10 @@ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) */ if (!IS_POSIXACL(dir)) mode &= ~current_umask(); - zpl_vap_init(vap, dir, mode, cr); + zpl_vap_init(vap, dir, mode, cr, userns); cookie = spl_fstrans_mark(); - error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL); + error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL, userns); if (error == 0) { /* d_tmpfile will do drop_nlink, so we should set it first */ set_nlink(ip, 1); @@ -311,13 +323,17 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) znode_t *zp; int error; fstrans_cookie_t cookie; +#ifndef HAVE_IOPS_MKDIR_USERNS + zuserns_t *user_ns = NULL; +#endif crhold(cr); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); - zpl_vap_init(vap, dir, mode | S_IFDIR, cr); + zpl_vap_init(vap, dir, mode | S_IFDIR, cr, user_ns); cookie = spl_fstrans_mark(); - error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL); + error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL, + user_ns); if (error == 0) { error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error == 0) @@ -439,7 +455,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia) int error; fstrans_cookie_t cookie; +#ifdef HAVE_SETATTR_PREPARE_USERNS + error = zpl_setattr_prepare(user_ns, dentry, ia); +#else error = zpl_setattr_prepare(kcred->user_ns, dentry, ia); +#endif if (error) return (error); @@ -458,7 +478,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia) ip->i_atime = zpl_inode_timestamp_truncate(ia->ia_atime, ip); cookie = spl_fstrans_mark(); - error = -zfs_setattr(ITOZ(ip), vap, 0, cr); +#ifdef HAVE_SETATTR_PREPARE_USERNS + error = -zfs_setattr(ITOZ(ip), vap, 0, cr, user_ns); +#else + error = -zfs_setattr(ITOZ(ip), vap, 0, cr, NULL); +#endif if (!error && (ia->ia_valid & ATTR_MODE)) error = zpl_chmod_acl(ip); @@ -483,6 +507,9 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry, cred_t *cr = CRED(); int error; fstrans_cookie_t cookie; +#ifndef HAVE_IOPS_RENAME_USERNS + zuserns_t *user_ns = NULL; +#endif /* We don't have renameat2(2) support */ if (flags) @@ -491,7 +518,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry, crhold(cr); cookie = spl_fstrans_mark(); error = -zfs_rename(ITOZ(sdip), dname(sdentry), ITOZ(tdip), - dname(tdentry), cr, 0); + dname(tdentry), cr, 0, user_ns); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0); @@ -521,14 +548,17 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name) znode_t *zp; int error; fstrans_cookie_t cookie; +#ifndef HAVE_IOPS_SYMLINK_USERNS + zuserns_t *user_ns = NULL; +#endif crhold(cr); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); - zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr); + zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr, user_ns); cookie = spl_fstrans_mark(); error = -zfs_symlink(ITOZ(dir), dname(dentry), vap, - (char *)name, &zp, cr, 0); + (char *)name, &zp, cr, 0, user_ns); if (error == 0) { error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name); if (error) { diff --git a/module/os/linux/zfs/zpl_super.c b/module/os/linux/zfs/zpl_super.c index e3945a2a05fe..63ba731dd804 100644 --- a/module/os/linux/zfs/zpl_super.c +++ b/module/os/linux/zfs/zpl_super.c @@ -374,7 +374,11 @@ const struct super_operations zpl_super_operations = { struct file_system_type zpl_fs_type = { .owner = THIS_MODULE, .name = ZFS_DRIVER, +#if defined(HAVE_IDMAP_MNT_API) + .fs_flags = FS_USERNS_MOUNT | FS_ALLOW_IDMAP, +#else .fs_flags = FS_USERNS_MOUNT, +#endif .mount = zpl_mount, .kill_sb = zpl_kill_sb, }; diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c index a010667adfa8..97b6e048c8a8 100644 --- a/module/os/linux/zfs/zpl_xattr.c +++ b/module/os/linux/zfs/zpl_xattr.c @@ -499,7 +499,7 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value, vap->va_gid = crgetgid(cr); error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp, - cr, 0, NULL); + cr, 0, NULL, NULL); if (error) goto out; } diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c index e438e3b37496..1026e2e60a9c 100644 --- a/module/os/linux/zfs/zvol_os.c +++ b/module/os/linux/zfs/zvol_os.c @@ -127,7 +127,7 @@ struct zvol_state_os { boolean_t use_blk_mq; }; -taskq_t *zvol_taskq; +static taskq_t *zvol_taskq; static struct ida zvol_ida; typedef struct zv_request_stack { diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c index 0e91304ecd4b..c03933d126c6 100644 --- a/module/zcommon/zfs_prop.c +++ b/module/zcommon/zfs_prop.c @@ -25,6 +25,7 @@ * Copyright 2016, Joyent, Inc. * Copyright (c) 2019, Klara Inc. * Copyright (c) 2019, Allan Jude + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ /* Portions Copyright 2010 Robert Milkowski */ @@ -369,6 +370,8 @@ zfs_prop_init(void) static const zprop_index_t redundant_metadata_table[] = { { "all", ZFS_REDUNDANT_METADATA_ALL }, { "most", ZFS_REDUNDANT_METADATA_MOST }, + { "some", ZFS_REDUNDANT_METADATA_SOME }, + { "none", ZFS_REDUNDANT_METADATA_NONE }, { NULL } }; @@ -388,7 +391,7 @@ zfs_prop_init(void) zprop_register_index(ZFS_PROP_REDUNDANT_METADATA, "redundant_metadata", ZFS_REDUNDANT_METADATA_ALL, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, - "all | most", "REDUND_MD", + "all | most | some | none", "REDUND_MD", redundant_metadata_table, sfeatures); zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, diff --git a/module/zfs/abd.c b/module/zfs/abd.c index 11a1e5112544..d4921d0ba7db 100644 --- a/module/zfs/abd.c +++ b/module/zfs/abd.c @@ -667,15 +667,15 @@ abd_return_buf(abd_t *abd, void *buf, size_t n) { abd_verify(abd); ASSERT3U(abd->abd_size, >=, n); +#ifdef ZFS_DEBUG + (void) zfs_refcount_remove_many(&abd->abd_children, n, buf); +#endif if (abd_is_linear(abd)) { ASSERT3P(buf, ==, abd_to_buf(abd)); } else { ASSERT0(abd_cmp_buf(abd, buf, n)); zio_buf_free(buf, n); } -#ifdef ZFS_DEBUG - (void) zfs_refcount_remove_many(&abd->abd_children, n, buf); -#endif } void diff --git a/module/zfs/arc.c b/module/zfs/arc.c index bc8d1041dfc9..d6ad8f835457 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -419,12 +419,12 @@ boolean_t arc_warm; /* * These tunables are for performance analysis. */ -unsigned long zfs_arc_max = 0; -unsigned long zfs_arc_min = 0; -unsigned long zfs_arc_meta_limit = 0; -unsigned long zfs_arc_meta_min = 0; -static unsigned long zfs_arc_dnode_limit = 0; -static unsigned long zfs_arc_dnode_reduce_percent = 10; +uint64_t zfs_arc_max = 0; +uint64_t zfs_arc_min = 0; +uint64_t zfs_arc_meta_limit = 0; +uint64_t zfs_arc_meta_min = 0; +static uint64_t zfs_arc_dnode_limit = 0; +static uint_t zfs_arc_dnode_reduce_percent = 10; static uint_t zfs_arc_grow_retry = 0; static uint_t zfs_arc_shrink_shift = 0; static uint_t zfs_arc_p_min_shift = 0; @@ -449,17 +449,17 @@ int zfs_compressed_arc_enabled = B_TRUE; * ARC will evict meta buffers that exceed arc_meta_limit. This * tunable make arc_meta_limit adjustable for different workloads. */ -static unsigned long zfs_arc_meta_limit_percent = 75; +static uint64_t zfs_arc_meta_limit_percent = 75; /* * Percentage that can be consumed by dnodes of ARC meta buffers. */ -static unsigned long zfs_arc_dnode_limit_percent = 10; +static uint_t zfs_arc_dnode_limit_percent = 10; /* * These tunables are Linux-specific */ -static unsigned long zfs_arc_sys_free = 0; +static uint64_t zfs_arc_sys_free = 0; static uint_t zfs_arc_min_prefetch_ms = 0; static uint_t zfs_arc_min_prescient_prefetch_ms = 0; static int zfs_arc_p_dampener_disable = 1; @@ -781,12 +781,12 @@ uint64_t zfs_crc64_table[256]; #define L2ARC_FEED_TYPES 4 /* L2ARC Performance Tunables */ -unsigned long l2arc_write_max = L2ARC_WRITE_SIZE; /* def max write size */ -unsigned long l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra warmup write */ -unsigned long l2arc_headroom = L2ARC_HEADROOM; /* # of dev writes */ -unsigned long l2arc_headroom_boost = L2ARC_HEADROOM_BOOST; -unsigned long l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */ -unsigned long l2arc_feed_min_ms = L2ARC_FEED_MIN_MS; /* min interval msecs */ +uint64_t l2arc_write_max = L2ARC_WRITE_SIZE; /* def max write size */ +uint64_t l2arc_write_boost = L2ARC_WRITE_SIZE; /* extra warmup write */ +uint64_t l2arc_headroom = L2ARC_HEADROOM; /* # of dev writes */ +uint64_t l2arc_headroom_boost = L2ARC_HEADROOM_BOOST; +uint64_t l2arc_feed_secs = L2ARC_FEED_SECS; /* interval seconds */ +uint64_t l2arc_feed_min_ms = L2ARC_FEED_MIN_MS; /* min interval msecs */ int l2arc_noprefetch = B_TRUE; /* don't cache prefetch bufs */ int l2arc_feed_again = B_TRUE; /* turbo warmup */ int l2arc_norw = B_FALSE; /* no reads during writes */ @@ -909,7 +909,7 @@ static int l2arc_mfuonly = 0; * will vary depending of how well the specific device handles * these commands. */ -static unsigned long l2arc_trim_ahead = 0; +static uint64_t l2arc_trim_ahead = 0; /* * Performance tuning of L2ARC persistence: @@ -925,7 +925,7 @@ static unsigned long l2arc_trim_ahead = 0; * not to waste space. */ static int l2arc_rebuild_enabled = B_TRUE; -static unsigned long l2arc_rebuild_blocks_min_l2size = 1024 * 1024 * 1024; +static uint64_t l2arc_rebuild_blocks_min_l2size = 1024 * 1024 * 1024; /* L2ARC persistence rebuild control routines. */ void l2arc_rebuild_vdev(vdev_t *vd, boolean_t reopen); @@ -3939,7 +3939,7 @@ arc_evict_hdr(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, uint64_t *real_evicted) * dropping from L1+L2 cached to L2-only, * realloc to remove the L1 header. */ - hdr = arc_hdr_realloc(hdr, hdr_full_cache, + (void) arc_hdr_realloc(hdr, hdr_full_cache, hdr_l2only_cache); *real_evicted += HDR_FULL_SIZE - HDR_L2ONLY_SIZE; } else { @@ -11078,20 +11078,20 @@ EXPORT_SYMBOL(arc_add_prune_callback); EXPORT_SYMBOL(arc_remove_prune_callback); ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min, param_set_arc_min, - param_get_ulong, ZMOD_RW, "Minimum ARC size in bytes"); + spl_param_get_u64, ZMOD_RW, "Minimum ARC size in bytes"); ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_max, - param_get_ulong, ZMOD_RW, "Maximum ARC size in bytes"); + spl_param_get_u64, ZMOD_RW, "Maximum ARC size in bytes"); -ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_long, - param_get_ulong, ZMOD_RW, "Metadata limit for ARC size in bytes"); +ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_u64, + spl_param_get_u64, ZMOD_RW, "Metadata limit for ARC size in bytes"); ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit_percent, - param_set_arc_long, param_get_ulong, ZMOD_RW, + param_set_arc_int, param_get_uint, ZMOD_RW, "Percent of ARC size for ARC meta limit"); -ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_min, param_set_arc_long, - param_get_ulong, ZMOD_RW, "Minimum ARC metadata size in bytes"); +ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_min, param_set_arc_u64, + spl_param_get_u64, ZMOD_RW, "Minimum ARC metadata size in bytes"); ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, meta_prune, INT, ZMOD_RW, "Meta objects to scan for prune"); @@ -11130,25 +11130,25 @@ ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min_prescient_prefetch_ms, param_set_arc_int, param_get_uint, ZMOD_RW, "Min life of prescient prefetched block in ms"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_max, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_max, U64, ZMOD_RW, "Max write bytes per interval"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_boost, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, write_boost, U64, ZMOD_RW, "Extra write bytes during device warmup"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom, U64, ZMOD_RW, "Number of max device writes to precache"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom_boost, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, headroom_boost, U64, ZMOD_RW, "Compressed l2arc_headroom multiplier"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, trim_ahead, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, trim_ahead, U64, ZMOD_RW, "TRIM ahead L2ARC write size multiplier"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_secs, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_secs, U64, ZMOD_RW, "Seconds between L2ARC writing"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_min_ms, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_min_ms, U64, ZMOD_RW, "Min feed interval in milliseconds"); ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, noprefetch, INT, ZMOD_RW, @@ -11166,7 +11166,7 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, meta_percent, UINT, ZMOD_RW, ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_enabled, INT, ZMOD_RW, "Rebuild the L2ARC when importing a pool"); -ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_blocks_min_l2size, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_blocks_min_l2size, U64, ZMOD_RW, "Min size in bytes to write rebuild log blocks in L2ARC"); ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, mfuonly, INT, ZMOD_RW, @@ -11178,17 +11178,17 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, exclude_special, INT, ZMOD_RW, ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, lotsfree_percent, param_set_arc_int, param_get_uint, ZMOD_RW, "System free memory I/O throttle in bytes"); -ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, sys_free, param_set_arc_long, - param_get_ulong, ZMOD_RW, "System free memory target size in bytes"); +ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, sys_free, param_set_arc_u64, + spl_param_get_u64, ZMOD_RW, "System free memory target size in bytes"); -ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, dnode_limit, param_set_arc_long, - param_get_ulong, ZMOD_RW, "Minimum bytes of dnodes in ARC"); +ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, dnode_limit, param_set_arc_u64, + spl_param_get_u64, ZMOD_RW, "Minimum bytes of dnodes in ARC"); ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, dnode_limit_percent, - param_set_arc_long, param_get_ulong, ZMOD_RW, + param_set_arc_int, param_get_uint, ZMOD_RW, "Percent of ARC meta buffers for dnodes"); -ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, dnode_reduce_percent, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, dnode_reduce_percent, UINT, ZMOD_RW, "Percentage of excess dnodes to try to unpin"); ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, eviction_pct, UINT, ZMOD_RW, diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 693defe0400f..06c3ba1d6b3b 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -227,8 +227,8 @@ typedef struct dbuf_cache { dbuf_cache_t dbuf_caches[DB_CACHE_MAX]; /* Size limits for the caches */ -static unsigned long dbuf_cache_max_bytes = ULONG_MAX; -static unsigned long dbuf_metadata_cache_max_bytes = ULONG_MAX; +static uint64_t dbuf_cache_max_bytes = UINT64_MAX; +static uint64_t dbuf_metadata_cache_max_bytes = UINT64_MAX; /* Set the default sizes of the caches to log2 fraction of arc size */ static uint_t dbuf_cache_shift = 5; @@ -1549,7 +1549,6 @@ dbuf_read_impl(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags, uint32_t aflags = ARC_FLAG_NOWAIT; int err, zio_flags; - err = zio_flags = 0; DB_DNODE_ENTER(db); dn = DB_DNODE(db); ASSERT(!zfs_refcount_is_zero(&db->db_holds)); @@ -5131,7 +5130,7 @@ EXPORT_SYMBOL(dmu_buf_set_user_ie); EXPORT_SYMBOL(dmu_buf_get_user); EXPORT_SYMBOL(dmu_buf_get_blkptr); -ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, max_bytes, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, max_bytes, U64, ZMOD_RW, "Maximum size in bytes of the dbuf cache."); ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, hiwater_pct, UINT, ZMOD_RW, @@ -5140,7 +5139,7 @@ ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, hiwater_pct, UINT, ZMOD_RW, ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, lowater_pct, UINT, ZMOD_RW, "Percentage below dbuf_cache_max_bytes when dbuf eviction stops."); -ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_max_bytes, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_max_bytes, U64, ZMOD_RW, "Maximum size in bytes of dbuf metadata cache."); ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, cache_shift, UINT, ZMOD_RW, diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index 6e8855d6f8e0..959875ed14b8 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -28,6 +28,7 @@ * Copyright (c) 2019 Datto Inc. * Copyright (c) 2019, Klara Inc. * Copyright (c) 2019, Allan Jude + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ #include @@ -70,7 +71,7 @@ static int zfs_nopwrite_enabled = 1; * will wait until the next TXG. * A value of zero will disable this throttle. */ -static unsigned long zfs_per_txg_dirty_frees_percent = 30; +static uint_t zfs_per_txg_dirty_frees_percent = 30; /* * Enable/disable forcing txg sync when dirty checking for holes with lseek(). @@ -1992,12 +1993,22 @@ dmu_write_policy(objset_t *os, dnode_t *dn, int level, int wp, zio_prop_t *zp) ZCHECKSUM_FLAG_EMBEDDED)) checksum = ZIO_CHECKSUM_FLETCHER_4; - if (os->os_redundant_metadata == ZFS_REDUNDANT_METADATA_ALL || - (os->os_redundant_metadata == - ZFS_REDUNDANT_METADATA_MOST && - (level >= zfs_redundant_metadata_most_ditto_level || - DMU_OT_IS_METADATA(type) || (wp & WP_SPILL)))) + switch (os->os_redundant_metadata) { + case ZFS_REDUNDANT_METADATA_ALL: copies++; + break; + case ZFS_REDUNDANT_METADATA_MOST: + if (level >= zfs_redundant_metadata_most_ditto_level || + DMU_OT_IS_METADATA(type) || (wp & WP_SPILL)) + copies++; + break; + case ZFS_REDUNDANT_METADATA_SOME: + if (DMU_OT_IS_CRITICAL(type)) + copies++; + break; + case ZFS_REDUNDANT_METADATA_NONE: + break; + } } else if (wp & WP_NOFILL) { ASSERT(level == 0); @@ -2395,7 +2406,7 @@ EXPORT_SYMBOL(dmu_ot); ZFS_MODULE_PARAM(zfs, zfs_, nopwrite_enabled, INT, ZMOD_RW, "Enable NOP writes"); -ZFS_MODULE_PARAM(zfs, zfs_, per_txg_dirty_frees_percent, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, per_txg_dirty_frees_percent, UINT, ZMOD_RW, "Percentage of dirtied blocks from frees in one TXG"); ZFS_MODULE_PARAM(zfs, zfs_, dmu_offset_next_sync, INT, ZMOD_RW, diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 7b5f6b389f55..c502edb7b6a4 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -32,6 +32,7 @@ * Copyright (c) 2018, loli10K . All rights reserved. * Copyright (c) 2019, Klara Inc. * Copyright (c) 2019, Allan Jude + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ /* Portions Copyright 2010 Robert Milkowski */ @@ -287,7 +288,9 @@ redundant_metadata_changed_cb(void *arg, uint64_t newval) * Inheritance and range checking should have been done by now. */ ASSERT(newval == ZFS_REDUNDANT_METADATA_ALL || - newval == ZFS_REDUNDANT_METADATA_MOST); + newval == ZFS_REDUNDANT_METADATA_MOST || + newval == ZFS_REDUNDANT_METADATA_SOME || + newval == ZFS_REDUNDANT_METADATA_NONE); os->os_redundant_metadata = newval; } diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index 1a93545152fb..a4fa33450550 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -1584,9 +1584,8 @@ send_merge_thread(void *arg) } range_free(front_ranges[i]); } - if (range == NULL) - range = kmem_zalloc(sizeof (*range), KM_SLEEP); - range->eos_marker = B_TRUE; + ASSERT3P(range, !=, NULL); + ASSERT3S(range->eos_marker, ==, B_TRUE); bqueue_enqueue_flush(&smt_arg->q, range, 1); spl_fstrans_unmark(cookie); thread_exit(); @@ -2533,8 +2532,7 @@ dmu_send_impl(struct dmu_send_params *dspp) } if (featureflags & DMU_BACKUP_FEATURE_RAW) { - uint64_t ivset_guid = (ancestor_zb != NULL) ? - ancestor_zb->zbm_ivset_guid : 0; + uint64_t ivset_guid = ancestor_zb->zbm_ivset_guid; nvlist_t *keynvl = NULL; ASSERT(os->os_encrypted); @@ -2738,6 +2736,10 @@ dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap, dspp.numfromredactsnaps = NUM_SNAPS_NOT_REDACTED; err = dmu_send_impl(&dspp); } + if (dspp.fromredactsnaps) + kmem_free(dspp.fromredactsnaps, + dspp.numfromredactsnaps * sizeof (uint64_t)); + dsl_dataset_rele(dspp.to_ds, FTAG); return (err); } @@ -2946,6 +2948,10 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, /* dmu_send_impl will call dsl_pool_rele for us. */ err = dmu_send_impl(&dspp); } else { + if (dspp.fromredactsnaps) + kmem_free(dspp.fromredactsnaps, + dspp.numfromredactsnaps * + sizeof (uint64_t)); dsl_pool_rele(dspp.dp, FTAG); } } else { diff --git a/module/zfs/dmu_zfetch.c b/module/zfs/dmu_zfetch.c index 101d2ee7b7a2..1d63d7de65a1 100644 --- a/module/zfs/dmu_zfetch.c +++ b/module/zfs/dmu_zfetch.c @@ -58,7 +58,7 @@ unsigned int zfetch_max_distance = 64 * 1024 * 1024; /* max bytes to prefetch indirects for per stream (default 64MB) */ unsigned int zfetch_max_idistance = 64 * 1024 * 1024; /* max number of bytes in an array_read in which we allow prefetching (1MB) */ -unsigned long zfetch_array_rd_sz = 1024 * 1024; +uint64_t zfetch_array_rd_sz = 1024 * 1024; typedef struct zfetch_stats { kstat_named_t zfetchstat_hits; @@ -565,5 +565,5 @@ ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_distance, UINT, ZMOD_RW, ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, max_idistance, UINT, ZMOD_RW, "Max bytes to prefetch indirects for per stream"); -ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, array_rd_sz, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_prefetch, zfetch_, array_rd_sz, U64, ZMOD_RW, "Number of bytes in a array_read"); diff --git a/module/zfs/dsl_bookmark.c b/module/zfs/dsl_bookmark.c index add14baefc0e..adaa7720cbff 100644 --- a/module/zfs/dsl_bookmark.c +++ b/module/zfs/dsl_bookmark.c @@ -229,7 +229,6 @@ dsl_bookmark_create_check_impl(dsl_pool_t *dp, switch (error) { case ESRCH: /* happy path: new bmark doesn't exist, proceed after switch */ - error = 0; break; case 0: error = SET_ERROR(EEXIST); diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 7a066b786cd0..c7577fc584af 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -3421,7 +3421,8 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) conflicting_snaps = B_TRUE; } else if (err == ESRCH) { err = 0; - } else if (err != 0) { + } + if (err != 0) { goto out; } } diff --git a/module/zfs/dsl_deadlist.c b/module/zfs/dsl_deadlist.c index 031be59e31cc..2b33446e66af 100644 --- a/module/zfs/dsl_deadlist.c +++ b/module/zfs/dsl_deadlist.c @@ -92,7 +92,7 @@ * will be loaded into memory and shouldn't take up an inordinate amount of * space. We settled on ~500000 entries, corresponding to roughly 128M. */ -unsigned long zfs_livelist_max_entries = 500000; +uint64_t zfs_livelist_max_entries = 500000; /* * We can approximate how much of a performance gain a livelist will give us @@ -1040,7 +1040,7 @@ dsl_process_sub_livelist(bpobj_t *bpobj, bplist_t *to_free, zthr_t *t, return (err); } -ZFS_MODULE_PARAM(zfs_livelist, zfs_livelist_, max_entries, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_livelist, zfs_livelist_, max_entries, U64, ZMOD_RW, "Size to start the next sub-livelist in a livelist"); ZFS_MODULE_PARAM(zfs_livelist, zfs_livelist_, min_percent_shared, INT, ZMOD_RW, diff --git a/module/zfs/dsl_pool.c b/module/zfs/dsl_pool.c index d07ec312dca6..9757cfae9b0f 100644 --- a/module/zfs/dsl_pool.c +++ b/module/zfs/dsl_pool.c @@ -100,8 +100,8 @@ * capped at zfs_dirty_data_max_max. It can also be overridden with a module * parameter. */ -unsigned long zfs_dirty_data_max = 0; -unsigned long zfs_dirty_data_max_max = 0; +uint64_t zfs_dirty_data_max = 0; +uint64_t zfs_dirty_data_max_max = 0; uint_t zfs_dirty_data_max_percent = 10; uint_t zfs_dirty_data_max_max_percent = 25; @@ -110,7 +110,7 @@ uint_t zfs_dirty_data_max_max_percent = 25; * when approaching the limit until log data is cleared out after txg sync. * It only counts TX_WRITE log with WR_COPIED or WR_NEED_COPY. */ -unsigned long zfs_wrlog_data_max = 0; +uint64_t zfs_wrlog_data_max = 0; /* * If there's at least this much dirty data (as a percentage of @@ -139,7 +139,7 @@ uint_t zfs_delay_min_dirty_percent = 60; * Note: zfs_delay_scale * zfs_dirty_data_max must be < 2^64, due to the * multiply in dmu_tx_delay(). */ -unsigned long zfs_delay_scale = 1000 * 1000 * 1000 / 2000; +uint64_t zfs_delay_scale = 1000 * 1000 * 1000 / 2000; /* * This determines the number of threads used by the dp_sync_taskq. @@ -332,7 +332,6 @@ dsl_pool_open(dsl_pool_t *dp) /* * We might not have created the remap bpobj yet. */ - err = 0; } else { goto out; } @@ -1529,20 +1528,20 @@ ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max_max_percent, UINT, ZMOD_RD, ZFS_MODULE_PARAM(zfs, zfs_, delay_min_dirty_percent, UINT, ZMOD_RW, "Transaction delay threshold"); -ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max, U64, ZMOD_RW, "Determines the dirty space limit"); -ZFS_MODULE_PARAM(zfs, zfs_, wrlog_data_max, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, wrlog_data_max, U64, ZMOD_RW, "The size limit of write-transaction zil log data"); /* zfs_dirty_data_max_max only applied at module load in arc_init(). */ -ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max_max, ULONG, ZMOD_RD, +ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_max_max, U64, ZMOD_RD, "zfs_dirty_data_max upper bound in bytes"); ZFS_MODULE_PARAM(zfs, zfs_, dirty_data_sync_percent, UINT, ZMOD_RW, "Dirty data txg sync threshold as a percentage of zfs_dirty_data_max"); -ZFS_MODULE_PARAM(zfs, zfs_, delay_scale, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, delay_scale, U64, ZMOD_RW, "How quickly delay approaches infinity"); ZFS_MODULE_PARAM(zfs, zfs_, sync_taskq_batch_pct, INT, ZMOD_RW, diff --git a/module/zfs/dsl_prop.c b/module/zfs/dsl_prop.c index 610e887b3fba..ad927b622fcf 100644 --- a/module/zfs/dsl_prop.c +++ b/module/zfs/dsl_prop.c @@ -23,6 +23,7 @@ * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 Martin Matuska. All rights reserved. * Copyright 2019 Joyent, Inc. + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ #include @@ -41,6 +42,7 @@ #define ZPROP_INHERIT_SUFFIX "$inherit" #define ZPROP_RECVD_SUFFIX "$recvd" +#define ZPROP_IUV_SUFFIX "$iuv" static int dodefault(zfs_prop_t prop, int intsz, int numints, void *buf) @@ -69,6 +71,16 @@ dodefault(zfs_prop_t prop, int intsz, int numints, void *buf) return (0); } +static int +dsl_prop_known_index(zfs_prop_t prop, uint64_t value) +{ + const char *str = NULL; + if (zfs_prop_get_type(prop) == PROP_TYPE_INDEX) + return (!zfs_prop_index_to_string(prop, value, &str)); + + return (-1); +} + int dsl_prop_get_dd(dsl_dir_t *dd, const char *propname, int intsz, int numints, void *buf, char *setpoint, boolean_t snapshot) @@ -81,6 +93,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname, boolean_t inheriting = B_FALSE; char *inheritstr; char *recvdstr; + char *iuvstr; ASSERT(dsl_pool_config_held(dd->dd_pool)); @@ -91,6 +104,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname, inheritable = (prop == ZPROP_USERPROP || zfs_prop_inheritable(prop)); inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX); recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX); + iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX); /* * Note: dd may become NULL, therefore we shouldn't dereference it @@ -105,6 +119,18 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname, inheriting = B_TRUE; } + /* Check for a iuv value. */ + err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj, + iuvstr, intsz, numints, buf); + if (dsl_prop_known_index(zfs_name_to_prop(propname), + *(uint64_t *)buf) != 1) + err = ENOENT; + if (err != ENOENT) { + if (setpoint != NULL && err == 0) + dsl_dir_name(dd, setpoint); + break; + } + /* Check for a local value. */ err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj, propname, intsz, numints, buf); @@ -155,6 +181,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname, kmem_strfree(inheritstr); kmem_strfree(recvdstr); + kmem_strfree(iuvstr); return (err); } @@ -647,6 +674,45 @@ dsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj, dsl_dir_rele(dd, FTAG); } + +/* + * For newer values in zfs index type properties, we add a new key + * propname$iuv (iuv = Ignore Unknown Values) to the properties zap object + * to store the new property value and store the default value in the + * existing prop key. So that the propname$iuv key is ignored by the older zfs + * versions and the default property value from the existing prop key is + * used. + */ +static void +dsl_prop_set_iuv(objset_t *mos, uint64_t zapobj, const char *propname, + int intsz, int numints, const void *value, dmu_tx_t *tx) +{ + char *iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX); + boolean_t iuv = B_FALSE; + zfs_prop_t prop = zfs_name_to_prop(propname); + + switch (prop) { + case ZFS_PROP_REDUNDANT_METADATA: + if (*(uint64_t *)value == ZFS_REDUNDANT_METADATA_SOME || + *(uint64_t *)value == ZFS_REDUNDANT_METADATA_NONE) + iuv = B_TRUE; + break; + default: + break; + } + + if (iuv) { + VERIFY0(zap_update(mos, zapobj, iuvstr, intsz, numints, + value, tx)); + uint64_t val = zfs_prop_default_numeric(prop); + VERIFY0(zap_update(mos, zapobj, propname, intsz, numints, + &val, tx)); + } else { + zap_remove(mos, zapobj, iuvstr, tx); + } + kmem_strfree(iuvstr); +} + void dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, zprop_source_t source, int intsz, int numints, const void *value, @@ -659,6 +725,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, const char *valstr = NULL; char *inheritstr; char *recvdstr; + char *iuvstr; char *tbuf = NULL; int err; uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa); @@ -692,6 +759,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX); recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX); + iuvstr = kmem_asprintf("%s%s", propname, ZPROP_IUV_SUFFIX); switch ((int)source) { case ZPROP_SRC_NONE: @@ -709,11 +777,14 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, /* * remove propname$inherit * set propname -> value + * set propname$iuv -> new property value */ err = zap_remove(mos, zapobj, inheritstr, tx); ASSERT(err == 0 || err == ENOENT); VERIFY0(zap_update(mos, zapobj, propname, intsz, numints, value, tx)); + (void) dsl_prop_set_iuv(mos, zapobj, propname, intsz, + numints, value, tx); break; case ZPROP_SRC_INHERITED: /* @@ -723,6 +794,8 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, */ err = zap_remove(mos, zapobj, propname, tx); ASSERT(err == 0 || err == ENOENT); + err = zap_remove(mos, zapobj, iuvstr, tx); + ASSERT(err == 0 || err == ENOENT); if (version >= SPA_VERSION_RECVD_PROPS && dsl_prop_get_int_ds(ds, ZPROP_HAS_RECVD, &dummy) == 0) { dummy = 0; @@ -763,6 +836,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname, kmem_strfree(inheritstr); kmem_strfree(recvdstr); + kmem_strfree(iuvstr); /* * If we are left with an empty snap zap we can destroy it. @@ -1012,6 +1086,14 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj, propname = za.za_name; source = setpoint; + + /* Skip if iuv entries are preset. */ + valstr = kmem_asprintf("%s%s", propname, + ZPROP_IUV_SUFFIX); + err = zap_contains(mos, propobj, valstr); + kmem_strfree(valstr); + if (err == 0) + continue; } else if (strcmp(suffix, ZPROP_INHERIT_SUFFIX) == 0) { /* Skip explicitly inherited entries. */ continue; @@ -1044,6 +1126,16 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj, source = ((flags & DSL_PROP_GET_INHERITING) ? setpoint : ZPROP_SOURCE_VAL_RECVD); + } else if (strcmp(suffix, ZPROP_IUV_SUFFIX) == 0) { + (void) strlcpy(buf, za.za_name, + MIN(sizeof (buf), suffix - za.za_name + 1)); + propname = buf; + source = setpoint; + prop = zfs_name_to_prop(propname); + + if (dsl_prop_known_index(prop, + za.za_first_integer) != 1) + continue; } else { /* * For backward compatibility, skip suffixes we don't diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c index 04993343bc88..9bd850a4ff9f 100644 --- a/module/zfs/dsl_scan.c +++ b/module/zfs/dsl_scan.c @@ -147,13 +147,13 @@ static int zfs_scan_strict_mem_lim = B_FALSE; * overload the drives with I/O, since that is protected by * zfs_vdev_scrub_max_active. */ -static unsigned long zfs_scan_vdev_limit = 4 << 20; +static uint64_t zfs_scan_vdev_limit = 4 << 20; static uint_t zfs_scan_issue_strategy = 0; /* don't queue & sort zios, go direct */ static int zfs_scan_legacy = B_FALSE; -static unsigned long zfs_scan_max_ext_gap = 2 << 20; /* in bytes */ +static uint64_t zfs_scan_max_ext_gap = 2 << 20; /* in bytes */ /* * fill_weight is non-tunable at runtime, so we copy it at module init from @@ -192,9 +192,9 @@ static int zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */ static int zfs_no_scrub_prefetch = B_FALSE; /* set to disable scrub prefetch */ static const enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE; /* max number of blocks to free in a single TXG */ -static unsigned long zfs_async_block_max_blocks = ULONG_MAX; +static uint64_t zfs_async_block_max_blocks = UINT64_MAX; /* max number of dedup blocks to free in a single TXG */ -static unsigned long zfs_max_async_dedup_frees = 100000; +static uint64_t zfs_max_async_dedup_frees = 100000; /* set to disable resilver deferring */ static int zfs_resilver_disable_defer = B_FALSE; @@ -4454,7 +4454,7 @@ dsl_scan_assess_vdev(dsl_pool_t *dp, vdev_t *vd) spa_async_request(dp->dp_spa, SPA_ASYNC_RESILVER); } -ZFS_MODULE_PARAM(zfs, zfs_, scan_vdev_limit, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, scan_vdev_limit, U64, ZMOD_RW, "Max bytes in flight per leaf vdev for scrubs and resilvers"); ZFS_MODULE_PARAM(zfs, zfs_, scrub_min_time_ms, UINT, ZMOD_RW, @@ -4478,10 +4478,10 @@ ZFS_MODULE_PARAM(zfs, zfs_, no_scrub_io, INT, ZMOD_RW, ZFS_MODULE_PARAM(zfs, zfs_, no_scrub_prefetch, INT, ZMOD_RW, "Set to disable scrub prefetching"); -ZFS_MODULE_PARAM(zfs, zfs_, async_block_max_blocks, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, async_block_max_blocks, U64, ZMOD_RW, "Max number of blocks freed in one txg"); -ZFS_MODULE_PARAM(zfs, zfs_, max_async_dedup_frees, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, max_async_dedup_frees, U64, ZMOD_RW, "Max number of dedup blocks freed in one txg"); ZFS_MODULE_PARAM(zfs, zfs_, free_bpobj_enabled, INT, ZMOD_RW, @@ -4502,7 +4502,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, scan_legacy, INT, ZMOD_RW, ZFS_MODULE_PARAM(zfs, zfs_, scan_checkpoint_intval, UINT, ZMOD_RW, "Scan progress on-disk checkpointing interval"); -ZFS_MODULE_PARAM(zfs, zfs_, scan_max_ext_gap, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, scan_max_ext_gap, U64, ZMOD_RW, "Max gap in bytes between sequential scrub / resilver I/Os"); ZFS_MODULE_PARAM(zfs, zfs_, scan_mem_lim_soft_fact, UINT, ZMOD_RW, diff --git a/module/zfs/fm.c b/module/zfs/fm.c index 32b5cf8facd1..3f05d759770b 100644 --- a/module/zfs/fm.c +++ b/module/zfs/fm.c @@ -955,6 +955,7 @@ fm_fmri_hc_create(nvlist_t *fmri, int version, const nvlist_t *auth, } atomic_inc_64( &erpt_kstat_data.fmri_set_failed.value.ui64); + va_end(ap); return; } } diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index b087073ba3d7..2d7180b76196 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -52,12 +52,12 @@ * operation, we will try to write this amount of data to each disk before * moving on to the next top-level vdev. */ -static unsigned long metaslab_aliquot = 1024 * 1024; +static uint64_t metaslab_aliquot = 1024 * 1024; /* * For testing, make some blocks above a certain size be gang blocks. */ -unsigned long metaslab_force_ganging = SPA_MAXBLOCKSIZE + 1; +uint64_t metaslab_force_ganging = SPA_MAXBLOCKSIZE + 1; /* * In pools where the log space map feature is not enabled we touch @@ -287,7 +287,7 @@ static const int max_disabled_ms = 3; * Time (in seconds) to respect ms_max_size when the metaslab is not loaded. * To avoid 64-bit overflow, don't set above UINT32_MAX. */ -static unsigned long zfs_metaslab_max_size_cache_sec = 1 * 60 * 60; /* 1 hour */ +static uint64_t zfs_metaslab_max_size_cache_sec = 1 * 60 * 60; /* 1 hour */ /* * Maximum percentage of memory to use on storing loaded metaslabs. If loading @@ -5192,8 +5192,7 @@ metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize, if (vd != NULL && vd->vdev_mg != NULL) { mg = vdev_get_mg(vd, mc); - if (flags & METASLAB_HINTBP_AVOID && - mg->mg_next != NULL) + if (flags & METASLAB_HINTBP_AVOID) mg = mg->mg_next; } else { mg = mca->mca_rotor; @@ -6280,7 +6279,7 @@ metaslab_unflushed_txg(metaslab_t *ms) return (ms->ms_unflushed_txg); } -ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, aliquot, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, aliquot, U64, ZMOD_RW, "Allocation granularity (a.k.a. stripe size)"); ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, debug_load, INT, ZMOD_RW, @@ -6328,7 +6327,7 @@ ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, segment_weight_enabled, INT, ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, switch_threshold, INT, ZMOD_RW, "Segment-based metaslab selection maximum buckets before switching"); -ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, force_ganging, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, force_ganging, U64, ZMOD_RW, "Blocks larger than this size are forced to be gang blocks"); ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, df_max_search, UINT, ZMOD_RW, @@ -6337,7 +6336,7 @@ ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, df_max_search, UINT, ZMOD_RW, ZFS_MODULE_PARAM(zfs_metaslab, metaslab_, df_use_largest_segment, INT, ZMOD_RW, "When looking in size tree, use largest segment instead of exact fit"); -ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, max_size_cache_sec, ULONG, +ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, max_size_cache_sec, U64, ZMOD_RW, "How long to trust the cached max chunk size of a metaslab"); ZFS_MODULE_PARAM(zfs_metaslab, zfs_metaslab_, mem_limit, UINT, ZMOD_RW, diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index b6d71aa8a458..ef0e01df390f 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -156,7 +156,7 @@ * vary with the I/O load and this observed value is the ub_mmp_delay which is * stored in the uberblock. The minimum allowed value is 100 ms. */ -ulong_t zfs_multihost_interval = MMP_DEFAULT_INTERVAL; +uint64_t zfs_multihost_interval = MMP_DEFAULT_INTERVAL; /* * Used to control the duration of the activity test on import. Smaller values @@ -550,11 +550,11 @@ mmp_thread(void *arg) uint32_t mmp_fail_intervals = MMP_FAIL_INTVS_OK( zfs_multihost_fail_intervals); hrtime_t mmp_fail_ns = mmp_fail_intervals * mmp_interval; - boolean_t last_spa_suspended = suspended; - boolean_t last_spa_multihost = multihost; - uint64_t last_mmp_interval = mmp_interval; - uint32_t last_mmp_fail_intervals = mmp_fail_intervals; - hrtime_t last_mmp_fail_ns = mmp_fail_ns; + boolean_t last_spa_suspended; + boolean_t last_spa_multihost; + uint64_t last_mmp_interval; + uint32_t last_mmp_fail_intervals; + hrtime_t last_mmp_fail_ns; callb_cpr_t cpr; int skip_wait = 0; @@ -736,7 +736,7 @@ mmp_signal_all_threads(void) /* BEGIN CSTYLED */ ZFS_MODULE_PARAM_CALL(zfs_multihost, zfs_multihost_, interval, - param_set_multihost_interval, param_get_ulong, ZMOD_RW, + param_set_multihost_interval, spl_param_get_u64, ZMOD_RW, "Milliseconds between mmp writes to each leaf"); /* END CSTYLED */ diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 65695b233776..f365aa05e697 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -221,7 +221,7 @@ static int spa_load_print_vdev_tree = B_FALSE; * there are also risks of performing an inadvertent rewind as we might be * missing all the vdevs with the latest uberblocks. */ -unsigned long zfs_max_missing_tvds = 0; +uint64_t zfs_max_missing_tvds = 0; /* * The parameters below are similar to zfs_max_missing_tvds but are only @@ -5333,7 +5333,7 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag, * If we've recovered the pool, pass back any information we * gathered while doing the load. */ - if (state == SPA_LOAD_RECOVER) { + if (state == SPA_LOAD_RECOVER && config != NULL) { fnvlist_add_nvlist(*config, ZPOOL_CONFIG_LOAD_INFO, spa->spa_load_info); } @@ -6891,8 +6891,8 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing, pvd = oldvd->vdev_parent; - if ((error = spa_config_parse(spa, &newrootvd, nvroot, NULL, 0, - VDEV_ALLOC_ATTACH)) != 0) + if (spa_config_parse(spa, &newrootvd, nvroot, NULL, 0, + VDEV_ALLOC_ATTACH) != 0) return (spa_vdev_exit(spa, NULL, txg, EINVAL)); if (newrootvd->vdev_children != 1) @@ -7248,7 +7248,7 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done) * it may be that the unwritability of the disk is the reason * it's being detached! */ - error = vdev_label_init(vd, 0, VDEV_LABEL_REMOVE); + (void) vdev_label_init(vd, 0, VDEV_LABEL_REMOVE); /* * Remove vd from its parent and compact the parent's children. @@ -8955,36 +8955,36 @@ spa_sync_props(void *arg, dmu_tx_t *tx) spa_history_log_internal(spa, "set", tx, "%s=%lld", nvpair_name(elem), (longlong_t)intval); - } else { - ASSERT(0); /* not allowed */ - } - switch (prop) { - case ZPOOL_PROP_DELEGATION: - spa->spa_delegation = intval; - break; - case ZPOOL_PROP_BOOTFS: - spa->spa_bootfs = intval; - break; - case ZPOOL_PROP_FAILUREMODE: - spa->spa_failmode = intval; - break; - case ZPOOL_PROP_AUTOTRIM: - spa->spa_autotrim = intval; - spa_async_request(spa, - SPA_ASYNC_AUTOTRIM_RESTART); - break; - case ZPOOL_PROP_AUTOEXPAND: - spa->spa_autoexpand = intval; - if (tx->tx_txg != TXG_INITIAL) + switch (prop) { + case ZPOOL_PROP_DELEGATION: + spa->spa_delegation = intval; + break; + case ZPOOL_PROP_BOOTFS: + spa->spa_bootfs = intval; + break; + case ZPOOL_PROP_FAILUREMODE: + spa->spa_failmode = intval; + break; + case ZPOOL_PROP_AUTOTRIM: + spa->spa_autotrim = intval; spa_async_request(spa, - SPA_ASYNC_AUTOEXPAND); - break; - case ZPOOL_PROP_MULTIHOST: - spa->spa_multihost = intval; - break; - default: - break; + SPA_ASYNC_AUTOTRIM_RESTART); + break; + case ZPOOL_PROP_AUTOEXPAND: + spa->spa_autoexpand = intval; + if (tx->tx_txg != TXG_INITIAL) + spa_async_request(spa, + SPA_ASYNC_AUTOEXPAND); + break; + case ZPOOL_PROP_MULTIHOST: + spa->spa_multihost = intval; + break; + default: + break; + } + } else { + ASSERT(0); /* not allowed */ } } @@ -10217,7 +10217,7 @@ ZFS_MODULE_PARAM(zfs_zio, zio_, taskq_batch_tpq, UINT, ZMOD_RD, "Number of threads per IO worker taskqueue"); /* BEGIN CSTYLED */ -ZFS_MODULE_PARAM(zfs, zfs_, max_missing_tvds, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, max_missing_tvds, U64, ZMOD_RW, "Allow importing pool with up to this number of missing top-level " "vdevs (in read-only mode)"); /* END CSTYLED */ diff --git a/module/zfs/spa_checkpoint.c b/module/zfs/spa_checkpoint.c index 556de9e698fd..96e492357d5f 100644 --- a/module/zfs/spa_checkpoint.c +++ b/module/zfs/spa_checkpoint.c @@ -159,7 +159,7 @@ * amount of checkpointed data that has been freed within them while * the pool had a checkpoint. */ -static unsigned long zfs_spa_discard_memory_limit = 16 * 1024 * 1024; +static uint64_t zfs_spa_discard_memory_limit = 16 * 1024 * 1024; int spa_checkpoint_get_stats(spa_t *spa, pool_checkpoint_stat_t *pcs) @@ -633,7 +633,7 @@ EXPORT_SYMBOL(spa_checkpoint_discard_thread); EXPORT_SYMBOL(spa_checkpoint_discard_thread_check); /* BEGIN CSTYLED */ -ZFS_MODULE_PARAM(zfs_spa, zfs_spa_, discard_memory_limit, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_spa, zfs_spa_, discard_memory_limit, U64, ZMOD_RW, "Limit for memory used in prefetching the checkpoint space map done " "on each vdev while discarding the checkpoint"); /* END CSTYLED */ diff --git a/module/zfs/spa_log_spacemap.c b/module/zfs/spa_log_spacemap.c index 95b9f7b916a9..8d857d7718b6 100644 --- a/module/zfs/spa_log_spacemap.c +++ b/module/zfs/spa_log_spacemap.c @@ -188,13 +188,13 @@ static const unsigned long zfs_log_sm_blksz = 1ULL << 17; * (thus the _ppm suffix; reads as "parts per million"). As an example, * the default of 1000 allows 0.1% of memory to be used. */ -static unsigned long zfs_unflushed_max_mem_ppm = 1000; +static uint64_t zfs_unflushed_max_mem_ppm = 1000; /* * Specific hard-limit in memory that ZFS allows to be used for * unflushed changes. */ -static unsigned long zfs_unflushed_max_mem_amt = 1ULL << 30; +static uint64_t zfs_unflushed_max_mem_amt = 1ULL << 30; /* * The following tunable determines the number of blocks that can be used for @@ -243,33 +243,33 @@ static unsigned long zfs_unflushed_max_mem_amt = 1ULL << 30; * provide upper and lower bounds for the log block limit. * [see zfs_unflushed_log_block_{min,max}] */ -static unsigned long zfs_unflushed_log_block_pct = 400; +static uint_t zfs_unflushed_log_block_pct = 400; /* * If the number of metaslabs is small and our incoming rate is high, we could * get into a situation that we are flushing all our metaslabs every TXG. Thus * we always allow at least this many log blocks. */ -static unsigned long zfs_unflushed_log_block_min = 1000; +static uint64_t zfs_unflushed_log_block_min = 1000; /* * If the log becomes too big, the import time of the pool can take a hit in * terms of performance. Thus we have a hard limit in the size of the log in * terms of blocks. */ -static unsigned long zfs_unflushed_log_block_max = (1ULL << 17); +static uint64_t zfs_unflushed_log_block_max = (1ULL << 17); /* * Also we have a hard limit in the size of the log in terms of dirty TXGs. */ -static unsigned long zfs_unflushed_log_txg_max = 1000; +static uint64_t zfs_unflushed_log_txg_max = 1000; /* * Max # of rows allowed for the log_summary. The tradeoff here is accuracy and * stability of the flushing algorithm (longer summary) vs its runtime overhead * (smaller summary is faster to traverse). */ -static unsigned long zfs_max_logsm_summary_length = 10; +static uint64_t zfs_max_logsm_summary_length = 10; /* * Tunable that sets the lower bound on the metaslabs to flush every TXG. @@ -282,7 +282,7 @@ static unsigned long zfs_max_logsm_summary_length = 10; * The point of this tunable is to be used in extreme cases where we really * want to flush more metaslabs than our adaptable heuristic plans to flush. */ -static unsigned long zfs_min_metaslabs_to_flush = 1; +static uint64_t zfs_min_metaslabs_to_flush = 1; /* * Tunable that specifies how far in the past do we want to look when trying to @@ -293,7 +293,7 @@ static unsigned long zfs_min_metaslabs_to_flush = 1; * average over all the blocks that we walk * [see spa_estimate_incoming_log_blocks]. */ -static unsigned long zfs_max_log_walking = 5; +static uint64_t zfs_max_log_walking = 5; /* * This tunable exists solely for testing purposes. It ensures that the log @@ -1378,34 +1378,34 @@ spa_ld_log_spacemaps(spa_t *spa) } /* BEGIN CSTYLED */ -ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_amt, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_amt, U64, ZMOD_RW, "Specific hard-limit in memory that ZFS allows to be used for " "unflushed changes"); -ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_ppm, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, unflushed_max_mem_ppm, U64, ZMOD_RW, "Percentage of the overall system memory that ZFS allows to be " "used for unflushed changes (value is calculated over 1000000 for " "finer granularity)"); -ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_max, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_max, U64, ZMOD_RW, "Hard limit (upper-bound) in the size of the space map log " "in terms of blocks."); -ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_min, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_min, U64, ZMOD_RW, "Lower-bound limit for the maximum amount of blocks allowed in " "log spacemap (see zfs_unflushed_log_block_max)"); -ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_txg_max, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_txg_max, U64, ZMOD_RW, "Hard limit (upper-bound) in the size of the space map log " "in terms of dirty TXGs."); -ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_pct, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, unflushed_log_block_pct, UINT, ZMOD_RW, "Tunable used to determine the number of blocks that can be used for " "the spacemap log, expressed as a percentage of the total number of " "metaslabs in the pool (e.g. 400 means the number of log blocks is " "capped at 4 times the number of metaslabs)"); -ZFS_MODULE_PARAM(zfs, zfs_, max_log_walking, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, max_log_walking, U64, ZMOD_RW, "The number of past TXGs that the flushing algorithm of the log " "spacemap feature uses to estimate incoming log blocks"); @@ -1414,8 +1414,8 @@ ZFS_MODULE_PARAM(zfs, zfs_, keep_log_spacemaps_at_export, INT, ZMOD_RW, "during pool export/destroy"); /* END CSTYLED */ -ZFS_MODULE_PARAM(zfs, zfs_, max_logsm_summary_length, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, max_logsm_summary_length, U64, ZMOD_RW, "Maximum number of rows allowed in the summary of the spacemap log"); -ZFS_MODULE_PARAM(zfs, zfs_, min_metaslabs_to_flush, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, min_metaslabs_to_flush, U64, ZMOD_RW, "Minimum number of metaslabs to flush per dirty TXG"); diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index 78017c02263a..89bf45c2d658 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -305,20 +305,20 @@ int zfs_free_leak_on_eio = B_FALSE; * has not completed in zfs_deadman_synctime_ms is considered "hung" resulting * in one of three behaviors controlled by zfs_deadman_failmode. */ -unsigned long zfs_deadman_synctime_ms = 600000UL; /* 10 min. */ +uint64_t zfs_deadman_synctime_ms = 600000UL; /* 10 min. */ /* * This value controls the maximum amount of time zio_wait() will block for an * outstanding IO. By default this is 300 seconds at which point the "hung" * behavior will be applied as described for zfs_deadman_synctime_ms. */ -unsigned long zfs_deadman_ziotime_ms = 300000UL; /* 5 min. */ +uint64_t zfs_deadman_ziotime_ms = 300000UL; /* 5 min. */ /* * Check time in milliseconds. This defines the frequency at which we check * for hung I/O. */ -unsigned long zfs_deadman_checktime_ms = 60000UL; /* 1 min. */ +uint64_t zfs_deadman_checktime_ms = 60000UL; /* 1 min. */ /* * By default the deadman is enabled. @@ -2993,7 +2993,7 @@ ZFS_MODULE_PARAM(zfs, zfs_, recover, INT, ZMOD_RW, ZFS_MODULE_PARAM(zfs, zfs_, free_leak_on_eio, INT, ZMOD_RW, "Set to ignore IO errors during free and permanently leak the space"); -ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, checktime_ms, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, checktime_ms, U64, ZMOD_RW, "Dead I/O check interval in milliseconds"); ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, enabled, INT, ZMOD_RW, @@ -3014,11 +3014,11 @@ ZFS_MODULE_PARAM_CALL(zfs_deadman, zfs_deadman_, failmode, "Failmode for deadman timer"); ZFS_MODULE_PARAM_CALL(zfs_deadman, zfs_deadman_, synctime_ms, - param_set_deadman_synctime, param_get_ulong, ZMOD_RW, + param_set_deadman_synctime, spl_param_get_u64, ZMOD_RW, "Pool sync expiration time in milliseconds"); ZFS_MODULE_PARAM_CALL(zfs_deadman, zfs_deadman_, ziotime_ms, - param_set_deadman_ziotime, param_get_ulong, ZMOD_RW, + param_set_deadman_ziotime, spl_param_get_u64, ZMOD_RW, "IO expiration time in milliseconds"); ZFS_MODULE_PARAM(zfs, zfs_, special_class_metadata_reserve_pct, UINT, ZMOD_RW, diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 22eedbcdb401..24dc6b639b60 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -145,8 +145,8 @@ int zfs_nocacheflush = 0; * be forced by vdev logical ashift or by user via ashift property, but won't * be set automatically as a performance optimization. */ -uint64_t zfs_vdev_max_auto_ashift = 14; -uint64_t zfs_vdev_min_auto_ashift = ASHIFT_MIN; +uint_t zfs_vdev_max_auto_ashift = 14; +uint_t zfs_vdev_min_auto_ashift = ASHIFT_MIN; void vdev_dbgmsg(vdev_t *vd, const char *fmt, ...) @@ -6173,7 +6173,6 @@ vdev_prop_get(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl) strval = NULL; zprop_source_t src = ZPROP_SRC_DEFAULT; propname = za.za_name; - prop = vdev_name_to_prop(propname); switch (za.za_integer_length) { case 8: @@ -6251,11 +6250,11 @@ ZFS_MODULE_PARAM(zfs, zfs_, embedded_slog_min_ms, UINT, ZMOD_RW, /* BEGIN CSTYLED */ ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, min_auto_ashift, - param_set_min_auto_ashift, param_get_ulong, ZMOD_RW, + param_set_min_auto_ashift, param_get_uint, ZMOD_RW, "Minimum ashift used when creating new top-level vdevs"); ZFS_MODULE_PARAM_CALL(zfs_vdev, zfs_vdev_, max_auto_ashift, - param_set_max_auto_ashift, param_get_ulong, ZMOD_RW, + param_set_max_auto_ashift, param_get_uint, ZMOD_RW, "Maximum ashift used when optimizing for logical -> physical sector " "size on new top-level vdevs"); /* END CSTYLED */ diff --git a/module/zfs/vdev_indirect.c b/module/zfs/vdev_indirect.c index b0bd71c58e69..814a1f0efe4c 100644 --- a/module/zfs/vdev_indirect.c +++ b/module/zfs/vdev_indirect.c @@ -189,14 +189,14 @@ static uint_t zfs_condense_indirect_obsolete_pct = 25; * consumed by the obsolete space map; the default of 1GB is small enough * that we typically don't mind "wasting" it. */ -static unsigned long zfs_condense_max_obsolete_bytes = 1024 * 1024 * 1024; +static uint64_t zfs_condense_max_obsolete_bytes = 1024 * 1024 * 1024; /* * Don't bother condensing if the mapping uses less than this amount of * memory. The default of 128KB is considered a "trivial" amount of * memory and not worth reducing. */ -static unsigned long zfs_condense_min_mapping_bytes = 128 * 1024; +static uint64_t zfs_condense_min_mapping_bytes = 128 * 1024; /* * This is used by the test suite so that it can ensure that certain @@ -1892,11 +1892,11 @@ ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, indirect_obsolete_pct, UINT, "Minimum obsolete percent of bytes in the mapping " "to attempt condensing"); -ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, min_mapping_bytes, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, min_mapping_bytes, U64, ZMOD_RW, "Don't bother condensing if the mapping uses less than this amount of " "memory"); -ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, max_obsolete_bytes, ULONG, +ZFS_MODULE_PARAM(zfs_condense, zfs_condense_, max_obsolete_bytes, U64, ZMOD_RW, "Minimum size obsolete spacemap to attempt condensing"); diff --git a/module/zfs/vdev_initialize.c b/module/zfs/vdev_initialize.c index 965fb7ef0593..75beb0cc3d12 100644 --- a/module/zfs/vdev_initialize.c +++ b/module/zfs/vdev_initialize.c @@ -36,17 +36,13 @@ /* * Value that is written to disk during initialization. */ -#ifdef _ILP32 -static unsigned long zfs_initialize_value = 0xdeadbeefUL; -#else -static unsigned long zfs_initialize_value = 0xdeadbeefdeadbeeeULL; -#endif +static uint64_t zfs_initialize_value = 0xdeadbeefdeadbeeeULL; /* maximum number of I/Os outstanding per leaf vdev */ static const int zfs_initialize_limit = 1; /* size of initializing writes; default 1MiB, see zfs_remove_max_segment */ -static unsigned long zfs_initialize_chunk_size = 1024 * 1024; +static uint64_t zfs_initialize_chunk_size = 1024 * 1024; static boolean_t vdev_initialize_should_stop(vdev_t *vd) @@ -261,15 +257,9 @@ vdev_initialize_block_fill(void *buf, size_t len, void *unused) (void) unused; ASSERT0(len % sizeof (uint64_t)); -#ifdef _ILP32 - for (uint64_t i = 0; i < len; i += sizeof (uint32_t)) { - *(uint32_t *)((char *)(buf) + i) = zfs_initialize_value; - } -#else for (uint64_t i = 0; i < len; i += sizeof (uint64_t)) { *(uint64_t *)((char *)(buf) + i) = zfs_initialize_value; } -#endif return (0); } @@ -765,8 +755,8 @@ EXPORT_SYMBOL(vdev_initialize_stop_all); EXPORT_SYMBOL(vdev_initialize_stop_wait); EXPORT_SYMBOL(vdev_initialize_restart); -ZFS_MODULE_PARAM(zfs, zfs_, initialize_value, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, initialize_value, U64, ZMOD_RW, "Value written during zpool initialize"); -ZFS_MODULE_PARAM(zfs, zfs_, initialize_chunk_size, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, initialize_chunk_size, U64, ZMOD_RW, "Size in bytes of writes by zpool initialize"); diff --git a/module/zfs/vdev_queue.c b/module/zfs/vdev_queue.c index c035f2d7b931..72eacc665914 100644 --- a/module/zfs/vdev_queue.c +++ b/module/zfs/vdev_queue.c @@ -746,6 +746,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio) * after our span is mandatory. */ dio = AVL_NEXT(t, last); + ASSERT3P(dio, !=, NULL); dio->io_flags &= ~ZIO_FLAG_OPTIONAL; } else { /* do not include the optional i/o */ diff --git a/module/zfs/vdev_rebuild.c b/module/zfs/vdev_rebuild.c index 1ce578e228d8..1f56275c853b 100644 --- a/module/zfs/vdev_rebuild.c +++ b/module/zfs/vdev_rebuild.c @@ -22,6 +22,7 @@ * * Copyright (c) 2018, Intel Corporation. * Copyright (c) 2020 by Lawrence Livermore National Security, LLC. + * Copyright (c) 2022 Hewlett Packard Enterprise Development LP. */ #include @@ -103,7 +104,7 @@ * Size of rebuild reads; defaults to 1MiB per data disk and is capped at * SPA_MAXBLOCKSIZE. */ -static unsigned long zfs_rebuild_max_segment = 1024 * 1024; +static uint64_t zfs_rebuild_max_segment = 1024 * 1024; /* * Maximum number of parallelly executed bytes per leaf vdev caused by a @@ -121,7 +122,7 @@ static unsigned long zfs_rebuild_max_segment = 1024 * 1024; * With a value of 32MB the sequential resilver write rate was measured at * 800MB/s sustained while rebuilding to a distributed spare. */ -static unsigned long zfs_rebuild_vdev_limit = 32 << 20; +static uint64_t zfs_rebuild_vdev_limit = 32 << 20; /* * Automatically start a pool scrub when the last active sequential resilver @@ -134,6 +135,7 @@ static int zfs_rebuild_scrub_enabled = 1; * For vdev_rebuild_initiate_sync() and vdev_rebuild_reset_sync(). */ static __attribute__((noreturn)) void vdev_rebuild_thread(void *arg); +static void vdev_rebuild_reset_sync(void *arg, dmu_tx_t *tx); /* * Clear the per-vdev rebuild bytes value for a vdev tree. @@ -307,6 +309,17 @@ vdev_rebuild_complete_sync(void *arg, dmu_tx_t *tx) vdev_rebuild_phys_t *vrp = &vr->vr_rebuild_phys; mutex_enter(&vd->vdev_rebuild_lock); + + /* + * Handle a second device failure if it occurs after all rebuild I/O + * has completed but before this sync task has been executed. + */ + if (vd->vdev_rebuild_reset_wanted) { + mutex_exit(&vd->vdev_rebuild_lock); + vdev_rebuild_reset_sync(arg, tx); + return; + } + vrp->vrp_rebuild_state = VDEV_REBUILD_COMPLETE; vrp->vrp_end_time = gethrestime_sec(); @@ -760,7 +773,6 @@ vdev_rebuild_thread(void *arg) ASSERT(vd->vdev_rebuilding); ASSERT(spa_feature_is_active(spa, SPA_FEATURE_DEVICE_REBUILD)); ASSERT3B(vd->vdev_rebuild_cancel_wanted, ==, B_FALSE); - ASSERT3B(vd->vdev_rebuild_reset_wanted, ==, B_FALSE); vdev_rebuild_t *vr = &vd->vdev_rebuild_config; vdev_rebuild_phys_t *vrp = &vr->vr_rebuild_phys; @@ -1138,10 +1150,10 @@ vdev_rebuild_get_stats(vdev_t *tvd, vdev_rebuild_stat_t *vrs) return (error); } -ZFS_MODULE_PARAM(zfs, zfs_, rebuild_max_segment, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, rebuild_max_segment, U64, ZMOD_RW, "Max segment size in bytes of rebuild reads"); -ZFS_MODULE_PARAM(zfs, zfs_, rebuild_vdev_limit, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, rebuild_vdev_limit, U64, ZMOD_RW, "Max bytes in flight per leaf vdev for sequential resilvers"); ZFS_MODULE_PARAM(zfs, zfs_, rebuild_scrub_enabled, INT, ZMOD_RW, diff --git a/module/zfs/zap_micro.c b/module/zfs/zap_micro.c index 58a5c9f600b7..4bf8a322e91b 100644 --- a/module/zfs/zap_micro.c +++ b/module/zfs/zap_micro.c @@ -990,8 +990,10 @@ zap_lookup_impl(zap_t *zap, const char *name, } else { *(uint64_t *)buf = MZE_PHYS(zap, mze)->mze_value; - (void) strlcpy(realname, - MZE_PHYS(zap, mze)->mze_name, rn_len); + if (realname != NULL) + (void) strlcpy(realname, + MZE_PHYS(zap, mze)->mze_name, + rn_len); if (ncp) { *ncp = mzap_normalization_conflict(zap, zn, mze); diff --git a/module/zfs/zcp.c b/module/zfs/zcp.c index fe90242ca40d..2b79f0a2a04a 100644 --- a/module/zfs/zcp.c +++ b/module/zfs/zcp.c @@ -109,8 +109,8 @@ #define ZCP_NVLIST_MAX_DEPTH 20 static const uint64_t zfs_lua_check_instrlimit_interval = 100; -unsigned long zfs_lua_max_instrlimit = ZCP_MAX_INSTRLIMIT; -unsigned long zfs_lua_max_memlimit = ZCP_MAX_MEMLIMIT; +uint64_t zfs_lua_max_instrlimit = ZCP_MAX_INSTRLIMIT; +uint64_t zfs_lua_max_memlimit = ZCP_MAX_MEMLIMIT; /* * Forward declarations for mutually recursive functions @@ -1443,8 +1443,8 @@ zcp_parse_args(lua_State *state, const char *fname, const zcp_arg_t *pargs, } } -ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_instrlimit, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_instrlimit, U64, ZMOD_RW, "Max instruction limit that can be specified for a channel program"); -ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_memlimit, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_lua, zfs_lua_, max_memlimit, U64, ZMOD_RW, "Max memory limit that can be specified for a channel program"); diff --git a/module/zfs/zcp_get.c b/module/zfs/zcp_get.c index cd17374eb422..f28266b8095f 100644 --- a/module/zfs/zcp_get.c +++ b/module/zfs/zcp_get.c @@ -467,7 +467,8 @@ get_zap_prop(lua_State *state, dsl_dataset_t *ds, zfs_prop_t zfs_prop) } else { error = dsl_prop_get_ds(ds, prop_name, sizeof (numval), 1, &numval, setpoint); - + if (error != 0) + goto out; #ifdef _KERNEL /* Fill in temporary value for prop, if applicable */ (void) zfs_get_temporary_prop(ds, zfs_prop, &numval, setpoint); @@ -489,6 +490,7 @@ get_zap_prop(lua_State *state, dsl_dataset_t *ds, zfs_prop_t zfs_prop) (void) lua_pushnumber(state, numval); } } +out: kmem_free(strval, ZAP_MAXVALUELEN); if (error == 0) get_prop_src(state, setpoint, zfs_prop); diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 64c21ac202b0..63d46b9963c7 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -228,14 +228,14 @@ static zfsdev_state_t *zfsdev_state_list; * for zc->zc_nvlist_src_size, since we will need to allocate that much memory. * Defaults to 0=auto which is handled by platform code. */ -unsigned long zfs_max_nvlist_src_size = 0; +uint64_t zfs_max_nvlist_src_size = 0; /* * When logging the output nvlist of an ioctl in the on-disk history, limit * the logged size to this many bytes. This must be less than DMU_MAX_ACCESS. * This applies primarily to zfs_ioc_channel_program(). */ -static unsigned long zfs_history_output_max = 1024 * 1024; +static uint64_t zfs_history_output_max = 1024 * 1024; uint_t zfs_fsyncer_key; uint_t zfs_allow_log_key; @@ -7886,8 +7886,8 @@ zfs_kmod_fini(void) tsd_destroy(&zfs_allow_log_key); } -ZFS_MODULE_PARAM(zfs, zfs_, max_nvlist_src_size, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, max_nvlist_src_size, U64, ZMOD_RW, "Maximum size in bytes allowed for src nvlist passed with ZFS ioctls"); -ZFS_MODULE_PARAM(zfs, zfs_, history_output_max, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, history_output_max, U64, ZMOD_RW, "Maximum size in bytes of ZFS ioctl output that will be logged"); diff --git a/module/zfs/zfs_log.c b/module/zfs/zfs_log.c index 0eea46cee49a..d03f6005c088 100644 --- a/module/zfs/zfs_log.c +++ b/module/zfs/zfs_log.c @@ -525,7 +525,7 @@ zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, znode_t *sdzp, * called as soon as the write is on stable storage (be it via a DMU sync or a * ZIL commit). */ -static long zfs_immediate_write_sz = 32768; +static int64_t zfs_immediate_write_sz = 32768; void zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, @@ -817,5 +817,5 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, zil_itx_assign(zilog, itx, tx); } -ZFS_MODULE_PARAM(zfs, zfs_, immediate_write_sz, LONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs, zfs_, immediate_write_sz, S64, ZMOD_RW, "Largest data block to write to zil"); diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c index 379e1d1a7b57..45c2fa3720cf 100644 --- a/module/zfs/zfs_replay.c +++ b/module/zfs/zfs_replay.c @@ -387,7 +387,7 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) } error = zfs_create(dzp, name, &xva.xva_vattr, - 0, 0, &zp, kcred, vflg, &vsec); + 0, 0, &zp, kcred, vflg, &vsec, NULL); break; case TX_MKDIR_ACL: aclstart = (caddr_t)(lracl + 1); @@ -417,7 +417,7 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap) lr->lr_uid, lr->lr_gid); } error = zfs_mkdir(dzp, name, &xva.xva_vattr, - &zp, kcred, vflg, &vsec); + &zp, kcred, vflg, &vsec, NULL); break; default: error = SET_ERROR(ENOTSUP); @@ -528,7 +528,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) name = (char *)start; error = zfs_create(dzp, name, &xva.xva_vattr, - 0, 0, &zp, kcred, vflg, NULL); + 0, 0, &zp, kcred, vflg, NULL, NULL); break; case TX_MKDIR_ATTR: lrattr = (lr_attr_t *)(caddr_t)(lr + 1); @@ -546,7 +546,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) name = (char *)(lr + 1); error = zfs_mkdir(dzp, name, &xva.xva_vattr, - &zp, kcred, vflg, NULL); + &zp, kcred, vflg, NULL, NULL); break; case TX_MKXATTR: error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &zp, kcred); @@ -555,7 +555,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap) name = (char *)(lr + 1); link = name + strlen(name) + 1; error = zfs_symlink(dzp, name, &xva.xva_vattr, - link, &zp, kcred, vflg); + link, &zp, kcred, vflg, NULL); break; default: error = SET_ERROR(ENOTSUP); @@ -667,7 +667,7 @@ zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap) if (lr->lr_common.lrc_txtype & TX_CI) vflg |= FIGNORECASE; - error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg); + error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg, NULL); zrele(tdzp); zrele(sdzp); @@ -860,7 +860,7 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap) zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start, lr->lr_uid, lr->lr_gid); - error = zfs_setattr(zp, vap, 0, kcred); + error = zfs_setattr(zp, vap, 0, kcred, NULL); zfs_fuid_info_free(zfsvfs->z_fuid_replay); zfsvfs->z_fuid_replay = NULL; diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 57f03f116273..c63076f90c18 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -168,15 +168,15 @@ zfs_access(znode_t *zp, int mode, int flag, cred_t *cr) return (error); if (flag & V_ACE_MASK) - error = zfs_zaccess(zp, mode, flag, B_FALSE, cr); + error = zfs_zaccess(zp, mode, flag, B_FALSE, cr, NULL); else - error = zfs_zaccess_rwx(zp, mode, flag, cr); + error = zfs_zaccess_rwx(zp, mode, flag, cr, NULL); zfs_exit(zfsvfs, FTAG); return (error); } -static unsigned long zfs_vnops_read_chunk_size = 1024 * 1024; /* Tunable */ +static uint64_t zfs_vnops_read_chunk_size = 1024 * 1024; /* Tunable */ /* * Read bytes from specified file into supplied buffer. @@ -991,5 +991,5 @@ EXPORT_SYMBOL(zfs_write); EXPORT_SYMBOL(zfs_getsecattr); EXPORT_SYMBOL(zfs_setsecattr); -ZFS_MODULE_PARAM(zfs_vnops, zfs_vnops_, read_chunk_size, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_vnops, zfs_vnops_, read_chunk_size, U64, ZMOD_RW, "Bytes to read per chunk"); diff --git a/module/zfs/zil.c b/module/zfs/zil.c index 9951ba391545..8efd7c6d5e4d 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -134,7 +134,7 @@ static int zil_nocacheflush = 0; * Any writes above that will be executed with lower (asynchronous) priority * to limit potential SLOG device abuse by single active ZIL writer. */ -static unsigned long zil_slog_bulk = 768 * 1024; +static uint64_t zil_slog_bulk = 768 * 1024; static kmem_cache_t *zil_lwb_cache; static kmem_cache_t *zil_zcw_cache; @@ -3967,7 +3967,7 @@ ZFS_MODULE_PARAM(zfs_zil, zil_, replay_disable, INT, ZMOD_RW, ZFS_MODULE_PARAM(zfs_zil, zil_, nocacheflush, INT, ZMOD_RW, "Disable ZIL cache flushes"); -ZFS_MODULE_PARAM(zfs_zil, zil_, slog_bulk, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_zil, zil_, slog_bulk, U64, ZMOD_RW, "Limit in bytes slog sync writes per commit"); ZFS_MODULE_PARAM(zfs_zil, zil_, maxblocksize, UINT, ZMOD_RW, diff --git a/module/zfs/zio.c b/module/zfs/zio.c index cd74dc75c9fa..ee9957045121 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -3396,7 +3396,7 @@ zio_ddt_write(zio_t *zio) return (zio); } -ddt_entry_t *freedde; /* for debugging */ +static ddt_entry_t *freedde; /* for debugging */ static zio_t * zio_ddt_free(zio_t *zio) diff --git a/module/zfs/zio_compress.c b/module/zfs/zio_compress.c index 4c9cbc962093..0fb91ac81522 100644 --- a/module/zfs/zio_compress.c +++ b/module/zfs/zio_compress.c @@ -44,7 +44,7 @@ * If nonzero, every 1/X decompression attempts will fail, simulating * an undetected memory error. */ -unsigned long zio_decompress_fail_fraction = 0; +static unsigned long zio_decompress_fail_fraction = 0; /* * Compression vectors. diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 73e085ec0f67..81bcb37f1152 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -1029,8 +1029,7 @@ zvol_add_clones(const char *dsname, list_t *minors_list) out: if (dd != NULL) dsl_dir_rele(dd, FTAG); - if (dp != NULL) - dsl_pool_rele(dp, FTAG); + dsl_pool_rele(dp, FTAG); } /* diff --git a/scripts/cstyle.pl b/scripts/cstyle.pl index ca7f027051cc..d47fd3362408 100755 --- a/scripts/cstyle.pl +++ b/scripts/cstyle.pl @@ -498,9 +498,6 @@ ($$) if (/\S\*\/[^)]|\S\*\/$/ && !/$lint_re/) { err("missing blank before close comment"); } - if (/\/\/\S/) { # C++ comments - err("missing blank after start comment"); - } # check for unterminated single line comments, but allow them when # they are used to comment out the argument list of a function # declaration. @@ -534,7 +531,15 @@ ($$) # multiple comments on the same line. # s/\/\*.*?\*\///g; - s/\/\/.*$//; # C++ comments + s/\/\/(?:\s.*)?$//; # Valid C++ comments + + # After stripping correctly spaced comments, check for (and strip) comments + # without a blank. By checking this after clearing out C++ comments that + # correctly have a blank, we guarantee URIs in a C++ comment will not cause + # an error. + if (s!//.*$!!) { # C++ comments + err("missing blank after start comment"); + } # delete any trailing whitespace; we have already checked for that. s/\s*$//; diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index 09dfb5eb1e1d..21e0f882dc40 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -194,3 +194,7 @@ tags = ['functional', 'userquota'] tests = ['zvol_misc_fua'] tags = ['functional', 'zvol', 'zvol_misc'] +[tests/functional/idmap_mount:Linux] +tests = ['idmap_mount_001', 'idmap_mount_002', 'idmap_mount_003', + 'idmap_mount_004'] +tags = ['functional', 'idmap_mount'] diff --git a/tests/test-runner/bin/zts-report.py.in b/tests/test-runner/bin/zts-report.py.in index ba4340bba85b..b463e7f0c63a 100755 --- a/tests/test-runner/bin/zts-report.py.in +++ b/tests/test-runner/bin/zts-report.py.in @@ -157,6 +157,10 @@ devices_not_available_reason = "Tests require additional disks. None found" # ci_reason = 'CI runner doesn\'t have all requirements' +# +# Idmapped mount is only supported in kernel version >= 5.12 +# +idmap_reason = 'Idmapped mount needs kernel 5.12+' # # These tests are known to fail, thus we use this list to prevent these @@ -496,6 +500,10 @@ elif sys.platform.startswith('linux'): 'zcache_slog_sharing/zcache_slog_sharing_multiple_pools_pos': ['SKIP', min_disk_required_reason], 'arc/dbufstats_001_pos': ['FAIL', 'QA-33190'], + 'idmap_mount/idmap_mount_001': ['SKIP', idmap_reason], + 'idmap_mount/idmap_mount_002': ['SKIP', idmap_reason], + 'idmap_mount/idmap_mount_003': ['SKIP', idmap_reason], + 'idmap_mount/idmap_mount_004': ['SKIP', idmap_reason], }) if 'ZTS_OBJECT_STORE' in os.environ and \ diff --git a/tests/zfs-tests/cmd/.gitignore b/tests/zfs-tests/cmd/.gitignore index 5162134942c8..88a251fa7547 100644 --- a/tests/zfs-tests/cmd/.gitignore +++ b/tests/zfs-tests/cmd/.gitignore @@ -49,3 +49,4 @@ /edonr_test /skein_test /sha2_test +/idmap_util diff --git a/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am index 4be0c9bf09dd..88945694f38e 100644 --- a/tests/zfs-tests/cmd/Makefile.am +++ b/tests/zfs-tests/cmd/Makefile.am @@ -126,7 +126,9 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/getversion scripts_zfs_tests_bin_PROGRAMS += %D%/user_ns_exec scripts_zfs_tests_bin_PROGRAMS += %D%/xattrtest scripts_zfs_tests_bin_PROGRAMS += %D%/zed_fd_spill-zedlet +scripts_zfs_tests_bin_PROGRAMS += %D%/idmap_util +%C%_idmap_util_LDADD = lib/libspl.la dist_noinst_DATA += %D%/linux_dos_attributes/dos_attributes.h scripts_zfs_tests_bin_PROGRAMS += %D%/read_dos_attributes %D%/write_dos_attributes diff --git a/tests/zfs-tests/cmd/btree_test.c b/tests/zfs-tests/cmd/btree_test.c index ab8967b22b22..9a34bf559be0 100644 --- a/tests/zfs-tests/cmd/btree_test.c +++ b/tests/zfs-tests/cmd/btree_test.c @@ -23,11 +23,11 @@ #define BUFSIZE 256 -int seed = 0; -int stress_timeout = 180; -int contents_frequency = 100; -int tree_limit = 64 * 1024; -boolean_t stress_only = B_FALSE; +static int seed = 0; +static int stress_timeout = 180; +static int contents_frequency = 100; +static int tree_limit = 64 * 1024; +static boolean_t stress_only = B_FALSE; static void usage(int exit_value) @@ -220,7 +220,6 @@ insert_find_remove(zfs_btree_t *bt, char *why) static int drain_tree(zfs_btree_t *bt, char *why) { - uint64_t *p; avl_tree_t avl; int i = 0; int_node_t *node; @@ -232,11 +231,8 @@ drain_tree(zfs_btree_t *bt, char *why) /* Fill both trees with the same data */ for (i = 0; i < 64 * 1024; i++) { - void *ret; - u_longlong_t randval = random(); - if ((p = (uint64_t *)zfs_btree_find(bt, &randval, &bt_idx)) != - NULL) { + if (zfs_btree_find(bt, &randval, &bt_idx) != NULL) { continue; } zfs_btree_add_idx(bt, &randval, &bt_idx); @@ -248,7 +244,7 @@ drain_tree(zfs_btree_t *bt, char *why) } node->data = randval; - if ((ret = avl_find(&avl, node, &avl_idx)) != NULL) { + if (avl_find(&avl, node, &avl_idx) != NULL) { (void) snprintf(why, BUFSIZE, "Found in avl: %llu\n", randval); return (1); @@ -372,9 +368,7 @@ stress_tree(zfs_btree_t *bt, char *why) if (stress_only) { zfs_btree_index_t *idx = NULL; - uint64_t *rv; - - while ((rv = zfs_btree_destroy_nodes(bt, &idx)) != NULL) + while (zfs_btree_destroy_nodes(bt, &idx) != NULL) ; zfs_btree_verify(bt); } @@ -389,15 +383,15 @@ stress_tree(zfs_btree_t *bt, char *why) static int insert_duplicate(zfs_btree_t *bt) { - uint64_t *p, i = 23456; + uint64_t i = 23456; zfs_btree_index_t bt_idx = {0}; - if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) { + if (zfs_btree_find(bt, &i, &bt_idx) != NULL) { fprintf(stderr, "Found value in empty tree.\n"); return (0); } zfs_btree_add_idx(bt, &i, &bt_idx); - if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) == NULL) { + if (zfs_btree_find(bt, &i, &bt_idx) == NULL) { fprintf(stderr, "Did not find expected value.\n"); return (0); } @@ -415,10 +409,10 @@ insert_duplicate(zfs_btree_t *bt) static int remove_missing(zfs_btree_t *bt) { - uint64_t *p, i = 23456; + uint64_t i = 23456; zfs_btree_index_t bt_idx = {0}; - if ((p = (uint64_t *)zfs_btree_find(bt, &i, &bt_idx)) != NULL) { + if (zfs_btree_find(bt, &i, &bt_idx) != NULL) { fprintf(stderr, "Found value in empty tree.\n"); return (0); } @@ -499,10 +493,6 @@ main(int argc, char *argv[]) break; } } - argc -= optind; - argv += optind; - optind = 1; - if (seed == 0) { (void) gettimeofday(&tp, NULL); @@ -536,7 +526,6 @@ main(int argc, char *argv[]) btree_test_t *test = &test_table[0]; while (test->name) { int retval; - uint64_t *rv; char why[BUFSIZE] = {0}; zfs_btree_index_t *idx = NULL; @@ -554,7 +543,7 @@ main(int argc, char *argv[]) } /* Remove all the elements and re-verify the tree */ - while ((rv = zfs_btree_destroy_nodes(&bt, &idx)) != NULL) + while (zfs_btree_destroy_nodes(&bt, &idx) != NULL) ; zfs_btree_verify(&bt); diff --git a/tests/zfs-tests/cmd/checksum/edonr_test.c b/tests/zfs-tests/cmd/checksum/edonr_test.c index 3a0a48533c53..d010fbfcd4d6 100644 --- a/tests/zfs-tests/cmd/checksum/edonr_test.c +++ b/tests/zfs-tests/cmd/checksum/edonr_test.c @@ -40,16 +40,16 @@ * Test messages from: * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf */ -const char *test_msg0 = "abc"; -const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn" - "lmnomnopnopq"; -const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi" - "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; +static const char *test_msg0 = "abc"; +static const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklm" + "nlmnomnopnopq"; +static const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfgh" + "ijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; /* * Test digests computed by hand. There's no formal standard or spec for edonr. */ -const uint8_t edonr_224_test_digests[][28] = { +static const uint8_t edonr_224_test_digests[][28] = { { /* for test_msg0 */ 0x56, 0x63, 0xc4, 0x93, 0x95, 0x20, 0xfa, 0xf6, @@ -67,7 +67,7 @@ const uint8_t edonr_224_test_digests[][28] = { /* no test vector for test_msg2 */ }; -const uint8_t edonr_256_test_digests[][32] = { +static const uint8_t edonr_256_test_digests[][32] = { { /* for test_msg0 */ 0x54, 0xd7, 0x8b, 0x13, 0xc7, 0x4e, 0xda, 0x5a, @@ -85,7 +85,7 @@ const uint8_t edonr_256_test_digests[][32] = { /* no test vectorfor test_msg2 */ }; -const uint8_t edonr_384_test_digests[][48] = { +static const uint8_t edonr_384_test_digests[][48] = { { /* for test_msg0 */ 0x0e, 0x7c, 0xd7, 0x85, 0x78, 0x77, 0xe0, 0x89, @@ -110,7 +110,7 @@ const uint8_t edonr_384_test_digests[][48] = { } }; -const uint8_t edonr_512_test_digests[][64] = { +static const uint8_t edonr_512_test_digests[][64] = { { /* for test_msg0 */ 0x1b, 0x14, 0xdb, 0x15, 0x5f, 0x1d, 0x40, 0x65, diff --git a/tests/zfs-tests/cmd/checksum/sha2_test.c b/tests/zfs-tests/cmd/checksum/sha2_test.c index bb355311091e..d99e8757a24c 100644 --- a/tests/zfs-tests/cmd/checksum/sha2_test.c +++ b/tests/zfs-tests/cmd/checksum/sha2_test.c @@ -44,17 +44,17 @@ * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf */ -const char *test_msg0 = "abc"; -const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn" - "lmnomnopnopq"; -const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi" - "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; +static const char *test_msg0 = "abc"; +static const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklm" + "nlmnomnopnopq"; +static const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfgh" + "ijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; /* * Test digests from: * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf */ -const uint8_t sha256_test_digests[][32] = { +static const uint8_t sha256_test_digests[][32] = { { /* for test_msg0 */ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, @@ -72,7 +72,7 @@ const uint8_t sha256_test_digests[][32] = { /* no test vector for test_msg2 */ }; -const uint8_t sha384_test_digests[][48] = { +static const uint8_t sha384_test_digests[][48] = { { /* for test_msg0 */ 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, @@ -97,7 +97,7 @@ const uint8_t sha384_test_digests[][48] = { } }; -const uint8_t sha512_test_digests[][64] = { +static const uint8_t sha512_test_digests[][64] = { { /* for test_msg0 */ 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, @@ -126,7 +126,7 @@ const uint8_t sha512_test_digests[][64] = { } }; -const uint8_t sha512_224_test_digests[][28] = { +static const uint8_t sha512_224_test_digests[][28] = { { /* for test_msg0 */ 0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54, @@ -147,7 +147,7 @@ const uint8_t sha512_224_test_digests[][28] = { } }; -const uint8_t sha512_256_test_digests[][32] = { +static const uint8_t sha512_256_test_digests[][32] = { { /* for test_msg0 */ 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, diff --git a/tests/zfs-tests/cmd/checksum/skein_test.c b/tests/zfs-tests/cmd/checksum/skein_test.c index 13611c860c42..20eb36d3e883 100644 --- a/tests/zfs-tests/cmd/checksum/skein_test.c +++ b/tests/zfs-tests/cmd/checksum/skein_test.c @@ -44,18 +44,18 @@ /* * Test messages from the Skein spec, Appendix C. */ -const uint8_t test_msg0[] = { +static const uint8_t test_msg0[] = { 0xFF }; -const uint8_t test_msg1[] = { +static const uint8_t test_msg1[] = { 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0 }; -const uint8_t test_msg2[] = { +static const uint8_t test_msg2[] = { 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, @@ -66,7 +66,7 @@ const uint8_t test_msg2[] = { 0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0 }; -const uint8_t test_msg3[] = { +static const uint8_t test_msg3[] = { 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, @@ -85,7 +85,7 @@ const uint8_t test_msg3[] = { 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80 }; -const uint8_t test_msg4[] = { +static const uint8_t test_msg4[] = { 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, @@ -123,7 +123,7 @@ const uint8_t test_msg4[] = { /* * Test digests from the Skein spec, Appendix C. */ -const uint8_t skein_256_test_digests[][32] = { +static const uint8_t skein_256_test_digests[][32] = { { /* for test_msg0 */ 0x0B, 0x98, 0xDC, 0xD1, 0x98, 0xEA, 0x0E, 0x50, @@ -148,7 +148,7 @@ const uint8_t skein_256_test_digests[][32] = { /* no test digests for test_msg3 and test_msg4 */ }; -const uint8_t skein_512_test_digests[][64] = { +static const uint8_t skein_512_test_digests[][64] = { { /* for test_msg0 */ 0x71, 0xB7, 0xBC, 0xE6, 0xFE, 0x64, 0x52, 0x22, @@ -189,7 +189,7 @@ const uint8_t skein_512_test_digests[][64] = { /* no test digests for test_msg4 */ }; -const uint8_t skein_1024_test_digests[][128] = { +static const uint8_t skein_1024_test_digests[][128] = { { /* for test_msg0 */ 0xE6, 0x2C, 0x05, 0x80, 0x2E, 0xA0, 0x15, 0x24, diff --git a/tests/zfs-tests/cmd/ctime.c b/tests/zfs-tests/cmd/ctime.c index f0f3d526eb3e..0f5d81aea613 100644 --- a/tests/zfs-tests/cmd/ctime.c +++ b/tests/zfs-tests/cmd/ctime.c @@ -327,7 +327,6 @@ main(void) if (access(tfile, F_OK) == 0) { (void) unlink(tfile); } - ret = 0; if ((fd = open(tfile, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE)) == -1) { (void) fprintf(stderr, "open(%s) failed: %d\n", tfile, errno); return (1); diff --git a/tests/zfs-tests/cmd/draid.c b/tests/zfs-tests/cmd/draid.c index 46d7b4dcc69d..3e5ff59f7399 100644 --- a/tests/zfs-tests/cmd/draid.c +++ b/tests/zfs-tests/cmd/draid.c @@ -1285,12 +1285,11 @@ draid_merge_impl(nvlist_t *allcfgs, const char *srcfilename, int *mergedp) if (nv_worst_ratio < allcfg_worst_ratio) { fnvlist_remove(allcfgs, key); - error = nvlist_add_nvlist(allcfgs, - key, cfg); + fnvlist_add_nvlist(allcfgs, key, cfg); merged++; } } else if (error == ENOENT) { - error = nvlist_add_nvlist(allcfgs, key, cfg); + fnvlist_add_nvlist(allcfgs, key, cfg); merged++; } else { return (error); diff --git a/tests/zfs-tests/cmd/idmap_util.c b/tests/zfs-tests/cmd/idmap_util.c new file mode 100644 index 000000000000..a9731f00dbc0 --- /dev/null +++ b/tests/zfs-tests/cmd/idmap_util.c @@ -0,0 +1,791 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef UINT_MAX +#define UINT_MAX 4294967295U +#endif + +#ifndef __NR_Linux +#if defined __alpha__ +#define __NR_Linux 110 +#elif defined _MIPS_SIM +#if _MIPS_SIM == _MIPS_SIM_ABI32 +#define __NR_Linux 4000 +#endif +#if _MIPS_SIM == _MIPS_SIM_NABI32 +#define __NR_Linux 6000 +#endif +#if _MIPS_SIM == _MIPS_SIM_ABI64 +#define __NR_Linux 5000 +#endif +#elif defined __ia64__ +#define __NR_Linux 1024 +#else +#define __NR_Linux 0 +#endif +#endif + +#ifndef __NR_mount_setattr +#define __NR_mount_setattr (442 + __NR_Linux) +#endif + +#ifndef __NR_open_tree +#define __NR_open_tree (428 + __NR_Linux) +#endif + +#ifndef __NR_move_mount +#define __NR_move_mount (429 + __NR_Linux) +#endif + +#ifndef MNT_DETACH +#define MNT_DETACH 2 +#endif + +#ifndef MOVE_MOUNT_F_EMPTY_PATH +#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 +#endif + +#ifndef MOUNT_ATTR_IDMAP +#define MOUNT_ATTR_IDMAP 0x00100000 +#endif + +#ifndef OPEN_TREE_CLONE +#define OPEN_TREE_CLONE 1 +#endif + +#ifndef OPEN_TREE_CLOEXEC +#define OPEN_TREE_CLOEXEC O_CLOEXEC +#endif + +#ifndef AT_RECURSIVE +#define AT_RECURSIVE 0x8000 +#endif + +#ifndef mount_attr +struct mount_attr { + __u64 attr_set; + __u64 attr_clr; + __u64 propagation; + __u64 userns_fd; +}; +#endif + +static inline int +sys_mount_setattr(int dfd, const char *path, unsigned int flags, + struct mount_attr *attr, size_t size) +{ + return (syscall(__NR_mount_setattr, dfd, path, flags, attr, size)); +} + +static inline int +sys_open_tree(int dfd, const char *filename, unsigned int flags) +{ + return (syscall(__NR_open_tree, dfd, filename, flags)); +} + +static inline int sys_move_mount(int from_dfd, const char *from_pathname, + int to_dfd, const char *to_pathname, unsigned int flags) +{ + return (syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, + to_pathname, flags)); +} + +typedef enum idmap_type_t { + TYPE_UID, + TYPE_GID, + TYPE_BOTH +} idmap_type_t; + +struct idmap_entry { + __u32 first; + __u32 lower_first; + __u32 count; + idmap_type_t type; + list_node_t node; +}; + +static void +log_msg(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + vfprintf(stderr, msg, ap); + fputc('\n', stderr); + va_end(ap); +} + +#define log_errno(msg, args...) \ + do { \ + log_msg("%s:%d:%s: [%m] " msg, __FILE__, __LINE__,\ + __FUNCTION__, ##args); \ + } while (0) + +/* + * Parse the idmapping in the following format + * and add to the list: + * + * u:nsid_first:hostid_first:count + * g:nsid_first:hostid_first:count + * b:nsid_first:hostid_first:count + * + * The delimiter can be : or space character. + * + * Return: + * 0 if success + * ENOMEM if out of memory + * EINVAL if wrong arg or input + */ +static int +parse_idmap_entry(list_t *head, char *input) +{ + char *token, *savedptr = NULL; + struct idmap_entry *entry; + unsigned long ul; + char *delimiter = (char *)": "; + char c; + + if (!input || !head) + return (EINVAL); + entry = malloc(sizeof (*entry)); + if (!entry) + return (ENOMEM); + + token = strtok_r(input, delimiter, &savedptr); + if (token) + c = token[0]; + if (!token || (c != 'b' && c != 'u' && c != 'g')) + goto errout; + entry->type = (c == 'b') ? TYPE_BOTH : + ((c == 'u') ? TYPE_UID : TYPE_GID); + + token = strtok_r(NULL, delimiter, &savedptr); + if (!token) + goto errout; + ul = strtoul(token, NULL, 10); + if (ul > UINT_MAX || errno != 0) + goto errout; + entry->first = (__u32)ul; + + token = strtok_r(NULL, delimiter, &savedptr); + if (!token) + goto errout; + ul = strtoul(token, NULL, 10); + if (ul > UINT_MAX || errno != 0) + goto errout; + entry->lower_first = (__u32)ul; + + token = strtok_r(NULL, delimiter, &savedptr); + if (!token) + goto errout; + ul = strtoul(token, NULL, 10); + if (ul > UINT_MAX || errno != 0) + goto errout; + entry->count = (__u32)ul; + + list_insert_tail(head, entry); + + return (0); + +errout: + free(entry); + return (EINVAL); +} + +/* + * Release all the entries in the list + */ +static void +free_idmap(list_t *head) +{ + struct idmap_entry *entry; + + while ((entry = list_remove_head(head)) != NULL) + free(entry); + /* list_destroy() to be done by the caller */ +} + +/* + * Write all bytes in the buffer to fd + */ +static ssize_t +write_buf(int fd, const char *buf, size_t buf_size) +{ + ssize_t written, total_written = 0; + size_t remaining = buf_size; + char *position = (char *)buf; + + for (;;) { + written = write(fd, position, remaining); + if (written < 0 && errno == EINTR) + continue; + if (written < 0) { + log_errno("write"); + return (written); + } + total_written += written; + if (total_written == buf_size) + break; + remaining -= written; + position += written; + } + + return (total_written); +} + +/* + * Read data from file into buffer + */ +static ssize_t +read_buf(int fd, char *buf, size_t buf_size) +{ + int ret; + for (;;) { + ret = read(fd, buf, buf_size); + if (ret < 0 && errno == EINTR) + continue; + break; + } + if (ret < 0) + log_errno("read"); + return (ret); +} + +/* + * Write idmap of the given type in the buffer to the + * process' uid_map or gid_map proc file. + * + * Return: + * 0 if success + * errno if there's any error + */ +static int +write_idmap(pid_t pid, char *buf, size_t buf_size, idmap_type_t type) +{ + char path[PATH_MAX]; + int fd = -EBADF; + int ret; + + (void) snprintf(path, sizeof (path), "/proc/%d/%cid_map", + pid, type == TYPE_UID ? 'u' : 'g'); + fd = open(path, O_WRONLY | O_CLOEXEC); + if (fd < 0) { + ret = errno; + log_errno("open(%s)", path); + goto out; + } + ret = write_buf(fd, buf, buf_size); + if (ret < 0) + ret = errno; + else + ret = 0; +out: + if (fd > 0) + close(fd); + return (ret); +} + +/* + * Write idmap info in the list to the process + * user namespace, i.e. its /proc//uid_map + * and /proc//gid_map file. + * + * Return: + * 0 if success + * errno if it fails + */ +static int +write_pid_idmaps(pid_t pid, list_t *head) +{ + char *buf_uids, *buf_gids; + char *curr_bufu, *curr_bufg; + /* max 4k to be allowed for each map */ + int size_buf_uids = 4096, size_buf_gids = 4096; + struct idmap_entry *entry; + int uid_filled, gid_filled; + int ret; + int has_uids = 0, has_gids = 0; + size_t buf_size; + + buf_uids = malloc(size_buf_uids); + if (!buf_uids) + return (ENOMEM); + buf_gids = malloc(size_buf_gids); + if (!buf_gids) { + free(buf_uids); + return (ENOMEM); + } + curr_bufu = buf_uids; + curr_bufg = buf_gids; + + for (entry = list_head(head); entry; entry = list_next(head, entry)) { + if (entry->type == TYPE_UID || entry->type == TYPE_BOTH) { + uid_filled = snprintf(curr_bufu, size_buf_uids, + "%u %u %u\n", entry->first, entry->lower_first, + entry->count); + if (uid_filled <= 0 || uid_filled >= size_buf_uids) { + ret = E2BIG; + goto out; + } + curr_bufu += uid_filled; + size_buf_uids -= uid_filled; + has_uids = 1; + } + if (entry->type == TYPE_GID || entry->type == TYPE_BOTH) { + gid_filled = snprintf(curr_bufg, size_buf_gids, + "%u %u %u\n", entry->first, entry->lower_first, + entry->count); + if (gid_filled <= 0 || gid_filled >= size_buf_gids) { + ret = E2BIG; + goto out; + } + curr_bufg += gid_filled; + size_buf_gids -= gid_filled; + has_gids = 1; + } + } + if (has_uids) { + buf_size = curr_bufu - buf_uids; + ret = write_idmap(pid, buf_uids, buf_size, TYPE_UID); + if (ret) + goto out; + } + if (has_gids) { + buf_size = curr_bufg - buf_gids; + ret = write_idmap(pid, buf_gids, buf_size, TYPE_GID); + } + +out: + free(buf_uids); + free(buf_gids); + return (ret); +} + +/* + * Wait for the child process to exit + * and reap it. + * + * Return: + * process exit code if available + */ +static int +wait_for_pid(pid_t pid) +{ + int status; + int ret; + + for (;;) { + ret = waitpid(pid, &status, 0); + if (ret < 0) { + if (errno == EINTR) + continue; + return (EXIT_FAILURE); + } + break; + } + if (!WIFEXITED(status)) + return (EXIT_FAILURE); + return (WEXITSTATUS(status)); +} + +/* + * Get the file descriptor of the process user namespace + * given its pid. + * + * Return: + * fd if success + * -1 if it fails + */ +static int +userns_fd_from_pid(pid_t pid) +{ + int fd; + char path[PATH_MAX]; + + (void) snprintf(path, sizeof (path), "/proc/%d/ns/user", pid); + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) + log_errno("open(%s)", path); + return (fd); +} + +/* + * Get the user namespace file descriptor given a list + * of idmap info. + * + * Return: + * fd if success + * -errno if it fails + */ +static int +userns_fd_from_idmap(list_t *head) +{ + pid_t pid; + int ret, fd; + int pipe_fd[2]; + char c; + int saved_errno = 0; + + /* pipe for bidirectional communication */ + ret = pipe(pipe_fd); + if (ret) { + log_errno("pipe"); + return (-errno); + } + + pid = fork(); + if (pid < 0) { + log_errno("fork"); + return (-errno); + } + + if (pid == 0) { + /* child process */ + close(pipe_fd[0]); + ret = unshare(CLONE_NEWUSER); + if (ret == 0) { + /* notify the parent of success */ + ret = write_buf(pipe_fd[1], "1", 1); + } else { + saved_errno = errno; + log_errno("unshare"); + ret = write_buf(pipe_fd[1], "0", 1); + } + if (ret < 0) + saved_errno = errno; + close(pipe_fd[1]); + exit(saved_errno); + } + /* parent process */ + close(pipe_fd[1]); + ret = read_buf(pipe_fd[0], &c, 1); + if (ret == 1 && c == '1') { + ret = write_pid_idmaps(pid, head); + if (!ret) { + fd = userns_fd_from_pid(pid); + if (fd < 0) + fd = -errno; + } else { + fd = -ret; + } + } else { + fd = -EBADF; + } + close(pipe_fd[0]); + (void) wait_for_pid(pid); + return (fd); +} + +/* + * Check if the operating system supports idmapped mount on the + * given path or not. + * + * Return: + * true if supported + * false if not supported + */ +static bool +is_idmap_supported(char *path) +{ + list_t head; + int ret; + int tree_fd = -EBADF, path_fd = -EBADF; + struct mount_attr attr = { + .attr_set = MOUNT_ATTR_IDMAP, + .userns_fd = -EBADF, + }; + + /* strtok_r() won't be happy with a const string */ + char *input = strdup("b:0:1000000:1000000"); + + if (!input) { + errno = ENOMEM; + log_errno("strdup"); + return (false); + } + + list_create(&head, sizeof (struct idmap_entry), + offsetof(struct idmap_entry, node)); + ret = parse_idmap_entry(&head, input); + if (ret) { + errno = ret; + log_errno("parse_idmap_entry(%s)", input); + goto out; + } + ret = userns_fd_from_idmap(&head); + if (ret < 0) + goto out; + attr.userns_fd = ret; + ret = openat(-EBADF, path, O_DIRECTORY | O_CLOEXEC); + if (ret < 0) { + log_errno("openat(%s)", path); + goto out; + } + path_fd = ret; + ret = sys_open_tree(path_fd, "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT | + AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE); + if (ret < 0) { + log_errno("sys_open_tree"); + goto out; + } + tree_fd = ret; + ret = sys_mount_setattr(tree_fd, "", AT_EMPTY_PATH, &attr, + sizeof (attr)); + if (ret < 0) { + log_errno("sys_mount_setattr"); + } +out: + free_idmap(&head); + list_destroy(&head); + if (tree_fd > 0) + close(tree_fd); + if (path_fd > 0) + close(path_fd); + if (attr.userns_fd > 0) + close(attr.userns_fd); + free(input); + return (ret == 0); +} + +/* + * Check if the given path is a mount point or not. + * + * Return: + * true if it is + * false otherwise + */ +static bool +is_mountpoint(char *path) +{ + char *parent; + struct stat st_me, st_parent; + bool ret; + + parent = malloc(strlen(path)+4); + if (!parent) { + errno = ENOMEM; + log_errno("malloc"); + return (false); + } + strcat(strcpy(parent, path), "/.."); + if (lstat(path, &st_me) != 0 || + lstat(parent, &st_parent) != 0) + ret = false; + else + if (st_me.st_dev != st_parent.st_dev || + st_me.st_ino == st_parent.st_ino) + ret = true; + else + ret = false; + free(parent); + return (ret); +} + +/* + * Remount the source on the new target folder with the given + * list of idmap info. If target is NULL, the source will be + * unmounted and then remounted if it is a mountpoint, otherwise + * no unmount is done, the source is simply idmap remounted. + * + * Return: + * 0 if success + * -errno otherwise + */ +static int +do_idmap_mount(list_t *idmap, char *source, char *target, int flags) +{ + int ret; + int tree_fd = -EBADF, source_fd = -EBADF; + struct mount_attr attr = { + .attr_set = MOUNT_ATTR_IDMAP, + .userns_fd = -EBADF, + }; + + ret = userns_fd_from_idmap(idmap); + if (ret < 0) + goto out; + attr.userns_fd = ret; + ret = openat(-EBADF, source, O_DIRECTORY | O_CLOEXEC); + if (ret < 0) { + ret = -errno; + log_errno("openat(%s)", source); + goto out; + } + source_fd = ret; + ret = sys_open_tree(source_fd, "", AT_EMPTY_PATH | AT_NO_AUTOMOUNT | + AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE | flags); + if (ret < 0) { + ret = -errno; + log_errno("sys_open_tree"); + goto out; + } + tree_fd = ret; + ret = sys_mount_setattr(tree_fd, "", AT_EMPTY_PATH | flags, &attr, + sizeof (attr)); + if (ret < 0) { + ret = -errno; + log_errno("sys_mount_setattr"); + goto out; + } + if (source != NULL && target == NULL && is_mountpoint(source)) { + ret = umount2(source, MNT_DETACH); + if (ret < 0) { + ret = -errno; + log_errno("umount2(%s)", source); + goto out; + } + } + ret = sys_move_mount(tree_fd, "", -EBADF, target == NULL ? + source : target, MOVE_MOUNT_F_EMPTY_PATH); + if (ret < 0) { + ret = -errno; + log_errno("sys_move_mount(%s)", target == NULL ? + source : target); + } +out: + if (tree_fd > 0) + close(tree_fd); + if (source_fd > 0) + close(source_fd); + if (attr.userns_fd > 0) + close(attr.userns_fd); + return (ret); +} + +static void +print_usage(char *argv[]) +{ + fprintf(stderr, "Usage: %s [-r] [-c] [-m ] [-m ]" \ + " ... [] []\n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, " -r Recursively do idmapped mount.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -c Checks if idmapped mount is supported " \ + "on the by the operating system or not.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -m to specify the idmap info, " \ + "in the following format:\n"); + fprintf(stderr, " :::\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " can be either of 'b', 'u', and 'g'.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "The folder will be mounted at " \ + "with the provided idmap information.\nIf no is " \ + "specified, and is a mount point, " \ + "then will be unmounted and then remounted.\n"); +} + +int +main(int argc, char *argv[]) +{ + int opt; + list_t idmap_head; + int check_supported = 0; + int ret = EXIT_SUCCESS; + char *source = NULL, *target = NULL; + int flags = 0; + + list_create(&idmap_head, sizeof (struct idmap_entry), + offsetof(struct idmap_entry, node)); + + while ((opt = getopt(argc, argv, "rcm:")) != -1) { + switch (opt) { + case 'r': + flags |= AT_RECURSIVE; + break; + case 'c': + check_supported = 1; + break; + case 'm': + ret = parse_idmap_entry(&idmap_head, optarg); + if (ret) { + errno = ret; + log_errno("parse_idmap_entry(%s)", optarg); + ret = EXIT_FAILURE; + goto out; + } + break; + default: + print_usage(argv); + exit(EXIT_FAILURE); + } + } + + if (check_supported == 0 && list_is_empty(&idmap_head)) { + print_usage(argv); + ret = EXIT_FAILURE; + goto out; + } + + if (optind >= argc) { + fprintf(stderr, "Expected to have , .\n"); + print_usage(argv); + ret = EXIT_FAILURE; + goto out; + } + + source = argv[optind]; + if (optind < (argc - 1)) { + target = argv[optind + 1]; + } + + if (check_supported) { + free_idmap(&idmap_head); + list_destroy(&idmap_head); + if (is_idmap_supported(source)) { + printf("idmapped mount is supported on [%s].\n", + source); + return (EXIT_SUCCESS); + } else { + printf("idmapped mount is NOT supported.\n"); + return (EXIT_FAILURE); + } + } + + ret = do_idmap_mount(&idmap_head, source, target, flags); + if (ret) + ret = EXIT_FAILURE; +out: + free_idmap(&idmap_head); + list_destroy(&idmap_head); + + exit(ret); +} diff --git a/tests/zfs-tests/cmd/mkbusy.c b/tests/zfs-tests/cmd/mkbusy.c index cc4a6cfcb98c..78860381d880 100644 --- a/tests/zfs-tests/cmd/mkbusy.c +++ b/tests/zfs-tests/cmd/mkbusy.c @@ -148,14 +148,10 @@ main(int argc, char *argv[]) } if (!isdir) { - int fd; - - if ((fd = open(fpath, O_CREAT | O_RDWR, 0600)) < 0) + if (open(fpath, O_CREAT | O_RDWR, 0600) < 0) fail("open"); } else { - DIR *dp; - - if ((dp = opendir(fpath)) == NULL) + if (opendir(fpath) == NULL) fail("opendir"); } free(fpath); diff --git a/tests/zfs-tests/cmd/mmap_libaio.c b/tests/zfs-tests/cmd/mmap_libaio.c index 7d76c9b4eb2f..5ee1f600a737 100644 --- a/tests/zfs-tests/cmd/mmap_libaio.c +++ b/tests/zfs-tests/cmd/mmap_libaio.c @@ -33,7 +33,7 @@ #include #include -io_context_t io_ctx; +static io_context_t io_ctx; static void do_sync_io(struct iocb *iocb) diff --git a/tests/zfs-tests/cmd/user_ns_exec.c b/tests/zfs-tests/cmd/user_ns_exec.c index 86593622399e..d781301473a9 100644 --- a/tests/zfs-tests/cmd/user_ns_exec.c +++ b/tests/zfs-tests/cmd/user_ns_exec.c @@ -97,7 +97,6 @@ set_idmap(pid_t pid, const char *file) mapfd = open(path, O_WRONLY); if (mapfd < 0) { - result = errno; perror("open"); return (errno); } diff --git a/tests/zfs-tests/include/commands.cfg b/tests/zfs-tests/include/commands.cfg index 048febd8b31a..e07de73164d5 100644 --- a/tests/zfs-tests/include/commands.cfg +++ b/tests/zfs-tests/include/commands.cfg @@ -166,6 +166,8 @@ export SYSTEM_FILES_LINUX='attr useradd userdel usermod + setpriv + mountpoint flock logger' @@ -240,4 +242,5 @@ export ZFSTEST_FILES='badsend truncate_test ereports zfs_diff-socket - dosmode_readonly_write' + dosmode_readonly_write + idmap_util' diff --git a/tests/zfs-tests/include/properties.shlib b/tests/zfs-tests/include/properties.shlib index 14b3f4415b7d..3dfb295a40df 100644 --- a/tests/zfs-tests/include/properties.shlib +++ b/tests/zfs-tests/include/properties.shlib @@ -11,6 +11,7 @@ # # Copyright (c) 2012, 2016, Delphix. All rights reserved. +# Copyright (c) 2022 Hewlett Packard Enterprise Development LP. # . $STF_SUITE/include/libtest.shlib @@ -27,7 +28,7 @@ typeset -a canmount_prop_vals=('on' 'off' 'noauto') typeset -a copies_prop_vals=('1' '2' '3') typeset -a logbias_prop_vals=('latency' 'throughput') typeset -a primarycache_prop_vals=('all' 'none' 'metadata') -typeset -a redundant_metadata_prop_vals=('all' 'most') +typeset -a redundant_metadata_prop_vals=('all' 'most' 'some' 'none') typeset -a secondarycache_prop_vals=('all' 'none' 'metadata') typeset -a snapdir_prop_vals=('hidden' 'visible') typeset -a sync_prop_vals=('standard' 'always' 'disabled') diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am index ef65e68dbc7f..2708eb774d9f 100644 --- a/tests/zfs-tests/tests/Makefile.am +++ b/tests/zfs-tests/tests/Makefile.am @@ -383,7 +383,9 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \ functional/zvol/zvol_common.shlib \ functional/zvol/zvol_ENOSPC/zvol_ENOSPC.cfg \ functional/zvol/zvol_misc/zvol_misc_common.kshlib \ - functional/zvol/zvol_swap/zvol_swap.cfg + functional/zvol/zvol_swap/zvol_swap.cfg \ + functional/idmap_mount/idmap_mount.cfg \ + functional/idmap_mount/idmap_mount_common.kshlib nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/acl/off/cleanup.ksh \ @@ -2026,4 +2028,10 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/zvol/zvol_swap/zvol_swap_003_pos.ksh \ functional/zvol/zvol_swap/zvol_swap_004_pos.ksh \ functional/zvol/zvol_swap/zvol_swap_005_pos.ksh \ - functional/zvol/zvol_swap/zvol_swap_006_pos.ksh + functional/zvol/zvol_swap/zvol_swap_006_pos.ksh \ + functional/idmap_mount/cleanup.ksh \ + functional/idmap_mount/setup.ksh \ + functional/idmap_mount/idmap_mount_001.ksh \ + functional/idmap_mount/idmap_mount_002.ksh \ + functional/idmap_mount/idmap_mount_003.ksh \ + functional/idmap_mount/idmap_mount_004.ksh diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh index 0166e84baa18..7ecaf849e44b 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_add/add-o_ashift.ksh @@ -44,7 +44,7 @@ verify_runnable "global" function cleanup { - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift poolexists $TESTPOOL && destroy_pool $TESTPOOL rm -f $disk1 $disk2 } @@ -77,13 +77,13 @@ do # Make sure we can also set the ashift using the tunable. # log_must zpool create $TESTPOOL $disk1 - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $ashift log_must zpool add $TESTPOOL $disk2 exp=$(( (ashift <= max_auto_ashift) ? ashift : logical_ashift )) log_must verify_ashift $disk2 $exp # clean things for the next run - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift log_must zpool destroy $TESTPOOL log_must zpool labelclear $disk1 log_must zpool labelclear $disk2 diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh index 964cfaa525e0..228f62232aae 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_prop_ashift.ksh @@ -44,7 +44,7 @@ verify_runnable "global" function cleanup { - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift poolexists $TESTPOOL && destroy_pool $TESTPOOL log_must rm -f $disk1 $disk2 } @@ -63,7 +63,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT) # the ashift using the -o ashift property should still # be honored. # -log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16 +log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16 typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16") for ashift in ${ashifts[@]} diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh index a96bc16761f7..6ccec6abd66f 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_attach/attach-o_ashift.ksh @@ -42,7 +42,7 @@ verify_runnable "global" function cleanup { - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1 rm -f $disk1 $disk2 } @@ -61,7 +61,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT) # the ashift using the -o ashift property should still # be honored. # -log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16 +log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16 typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16") for ashift in ${ashifts[@]} diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh index 7610f2855c03..37ed0062e61c 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace-o_ashift.ksh @@ -42,7 +42,7 @@ verify_runnable "global" function cleanup { - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1 rm -f $disk1 $disk2 } @@ -61,7 +61,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT) # the ashift using the -o ashift property should still # be honored. # -log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16 +log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16 typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16") for ashift in ${ashifts[@]} diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh index 313b388b2ba4..ffdaf91a2841 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_replace/replace_prop_ashift.ksh @@ -44,7 +44,7 @@ verify_runnable "global" function cleanup { - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1 rm -f $disk1 $disk2 } @@ -63,7 +63,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT) # the ashift using the -o ashift property should still # be honored. # -log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16 +log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16 typeset ashifts=("9" "10" "11" "12" "13" "14" "15" "16") for ashift in ${ashifts[@]} diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh index 58119e37cc67..41fef8f7cdb4 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_set/zpool_set_ashift.ksh @@ -42,7 +42,7 @@ verify_runnable "global" function cleanup { - log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift + log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT $orig_ashift destroy_pool $TESTPOOL1 rm -f $disk } @@ -60,7 +60,7 @@ orig_ashift=$(get_tunable VDEV_FILE_PHYSICAL_ASHIFT) # the ashift using the -o ashift property should still # be honored. # -log_must set_tunable64 VDEV_FILE_PHYSICAL_ASHIFT 16 +log_must set_tunable32 VDEV_FILE_PHYSICAL_ASHIFT 16 disk=$TEST_BASE_DIR/disk log_must mkfile $SIZE $disk diff --git a/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh b/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh new file mode 100755 index 000000000000..4895aa23ee4a --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/cleanup.ksh @@ -0,0 +1,25 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/include/libtest.shlib + +default_cleanup diff --git a/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg new file mode 100644 index 000000000000..51998945d0d1 --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount.cfg @@ -0,0 +1,25 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +export UID1=1000000 +export GID1=1000000 +export UID2=2000000 +export GID2=2000000 diff --git a/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh new file mode 100755 index 000000000000..e7187935e532 --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_001.ksh @@ -0,0 +1,76 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib + +# +# +# DESCRIPTION: +# Test uid and gid of files in idmapped folder are mapped correctly +# +# +# STRATEGY: +# 1. Create files/folder owned by $UID1 and $GID1 under "idmap_test" +# 2. Idmap the folder to "idmap_dest" +# 3. Verify the owner of files/folder under "idmap_dest" +# + +verify_runnable "global" + +export WORKDIR=$TESTDIR/idmap_test +export IDMAPDIR=$TESTDIR/idmap_dest + +function cleanup +{ + log_must rm -rf $WORKDIR + if mountpoint $IDMAPDIR; then + log_must umount $IDMAPDIR + fi + log_must rm -rf $IDMAPDIR +} + +log_onexit cleanup + +if ! idmap_util -c $TESTDIR; then + log_unsupported "Idmap mount not supported." +fi + +log_must mkdir -p $WORKDIR +log_must mkdir -p $IDMAPDIR +log_must touch $WORKDIR/file1 +log_must mkdir $WORKDIR/subdir +log_must ln -s $WORKDIR/file1 $WORKDIR/file1_sym +log_must ln $WORKDIR/file1 $WORKDIR/subdir/file1_hard +log_must touch $WORKDIR/subdir/file2 +log_must chown -R $UID1:$GID1 $WORKDIR +log_must chown $UID2:$GID2 $WORKDIR/subdir/file2 + +log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR + +log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/file1)" +log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/file1_sym)" +log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/subdir)" +log_must test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/subdir/file1_hard)" +log_mustnot test "$UID2 $GID2" = "$(stat -c '%u %g' $IDMAPDIR/subdir/file2)" + +log_pass "Owner verification of entries under idmapped folder is successful." + diff --git a/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh new file mode 100755 index 000000000000..8cba90ea58b7 --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_002.ksh @@ -0,0 +1,97 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib + +# +# +# DESCRIPTION: +# Perform file operations in idmapped folder, check owner in its base. +# +# +# STRATEGY: +# 1. Create folder "idmap_test" +# 2. Idmap the folder to "idmap_dest" +# 3. Do basic file operations in "idmap_dest" folder, verify the owner in +# the base folder "idmap_test" +# + +verify_runnable "global" + +export WORKDIR=$TESTDIR/idmap_test +export IDMAPDIR=$TESTDIR/idmap_dest + +function cleanup +{ + log_must rm -rf $IDMAPDIR/* + if mountpoint $IDMAPDIR; then + log_must umount $IDMAPDIR + fi + log_must rm -rf $IDMAPDIR $WORKDIR +} + +log_onexit cleanup + +if ! idmap_util -c $TESTDIR; then + log_unsupported "Idmap mount not supported." +fi + +log_must mkdir -p $WORKDIR +log_must mkdir -p $IDMAPDIR + +log_must chown $UID1:$GID1 $WORKDIR +log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR + +SETPRIV="setpriv --reuid $UID2 --regid $GID2 --clear-groups" + +log_must $SETPRIV touch $IDMAPDIR/file1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)" + +log_must $SETPRIV mv $IDMAPDIR/file1 $IDMAPDIR/file1_renamed +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_renamed)" + +log_must $SETPRIV mv $IDMAPDIR/file1_renamed $IDMAPDIR/file1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)" + +log_must $SETPRIV mkdir $IDMAPDIR/subdir +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir)" + +log_must $SETPRIV ln -s $IDMAPDIR/file1 $IDMAPDIR/file1_sym +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_sym)" + +log_must $SETPRIV ln $IDMAPDIR/file1 $IDMAPDIR/subdir/file1_hard +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir/file1_hard)" + +log_must $SETPRIV touch $IDMAPDIR/subdir/file2 +log_must $SETPRIV chown $UID2:$GID2 $IDMAPDIR/subdir/file2 +log_mustnot $SETPRIV chown $UID1 $IDMAPDIR/subdir/file2 + +log_must $SETPRIV cp -r $IDMAPDIR/subdir $IDMAPDIR/subdir1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file2)" +log_must $SETPRIV rm -rf $IDMAPDIR/subdir1 + +log_must $SETPRIV cp -rp $IDMAPDIR/subdir $IDMAPDIR/subdir1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file1_hard)" +log_must $SETPRIV rm -rf $IDMAPDIR/subdir1 + +log_pass "Owner verification of entries under base folder is successful." + diff --git a/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh new file mode 100755 index 000000000000..1f1a2aec655e --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_003.ksh @@ -0,0 +1,121 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib + +# +# +# DESCRIPTION: +# Perform file operations in idmapped folder in user namespace, +# then check the owner in its base. +# +# +# STRATEGY: +# 1. Create folder "idmap_test" +# 2. Idmap the folder to "idmap_dest" +# 3. Perform file operations in the idmapped folder in the user +# namespace having the same idmap info as the idmapped mount +# 4. Verify the owner of entries under the base folder "idmap_test" +# + +verify_runnable "global" + +export WORKDIR=$TESTDIR/idmap_test +export IDMAPDIR=$TESTDIR/idmap_dest + +function cleanup +{ + kill -TERM ${unshared_pid} + log_must rm -rf $IDMAPDIR/* + if mountpoint $IDMAPDIR; then + log_must umount $IDMAPDIR + fi + log_must rm -rf $IDMAPDIR $WORKDIR +} + +log_onexit cleanup + +if ! idmap_util -c $TESTDIR; then + log_unsupported "Idmap mount not supported." +fi + +log_must mkdir -p $WORKDIR +log_must mkdir -p $IDMAPDIR + +log_must chown $UID1:$GID1 $WORKDIR +log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR + +# Create a user namespace with the same idmapping +unshare -Urm echo test +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to create user namespace" +fi +unshare -Um /usr/bin/sleep 2h & +unshared_pid=$! +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to create user namespace" +fi +# wait for userns to be ready +sleep 1 +echo "${UID1} ${UID2} 1" > /proc/$unshared_pid/uid_map +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to write to uid_map" +fi +echo "${GID1} ${GID2} 1" > /proc/$unshared_pid/gid_map +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to write to gid_map" +fi + +NSENTER="nsenter -t $unshared_pid --all -S ${UID1} -G ${GID1}" + +log_must $NSENTER touch $IDMAPDIR/file1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)" + +log_must $NSENTER mv $IDMAPDIR/file1 $IDMAPDIR/file1_renamed +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_renamed)" + +log_must $NSENTER mv $IDMAPDIR/file1_renamed $IDMAPDIR/file1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1)" + +log_must $NSENTER mkdir $IDMAPDIR/subdir +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir)" + +log_must $NSENTER ln -s $IDMAPDIR/file1 $IDMAPDIR/file1_sym +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/file1_sym)" + +log_must $NSENTER ln $IDMAPDIR/file1 $IDMAPDIR/subdir/file1_hard +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir/file1_hard)" + +log_must $NSENTER touch $IDMAPDIR/subdir/file2 +log_must $NSENTER chown $UID1:$GID1 $IDMAPDIR/subdir/file2 +log_mustnot $NSENTER chown $UID2 $IDMAPDIR/subdir/file2 + +log_must $NSENTER cp -r $IDMAPDIR/subdir $IDMAPDIR/subdir1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file2)" +log_must $NSENTER rm -rf $IDMAPDIR/subdir1 + +log_must $NSENTER cp -rp $IDMAPDIR/subdir $IDMAPDIR/subdir1 +log_must test "$UID1 $GID1" = "$(stat -c '%u %g' $WORKDIR/subdir1/file1_hard)" +log_must $NSENTER rm -rf $IDMAPDIR/subdir1 + +log_pass "Owner verification of entries under the base folder is successful." + diff --git a/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh new file mode 100755 index 000000000000..89f2f750d23c --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_004.ksh @@ -0,0 +1,106 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/tests/functional/idmap_mount/idmap_mount_common.kshlib + +# +# +# DESCRIPTION: +# Test setgid bit is set properly on the idmapped mount +# in a user namespace. +# +# STRATEGY: +# 1. Create folder "idmap_test", set gid bit on it +# 2. Idmap the folder to "idmap_dest" +# 3. Create file and folder in the idmapped folder in the user +# namespace having the same idmap info +# 4. Verify the gid bit of the file and folder is set +# + +verify_runnable "global" + +export WORKDIR=$TESTDIR/idmap_test +export IDMAPDIR=$TESTDIR/idmap_dest + +function cleanup +{ + kill -TERM ${unshared_pid} + log_must rm -rf $IDMAPDIR/* + if mountpoint $IDMAPDIR; then + log_must umount $IDMAPDIR + fi + log_must rm -rf $IDMAPDIR $WORKDIR +} + +log_onexit cleanup + +if ! idmap_util -c $TESTDIR; then + log_unsupported "Idmap mount not supported." +fi + +log_must mkdir -p $WORKDIR +log_must mkdir -p $IDMAPDIR + +log_must chown $UID1:$GID1 $WORKDIR +# set gid bit +log_must chmod 2755 $WORKDIR +log_must idmap_util -m "u:${UID1}:${UID2}:1" -m "g:${GID1}:${GID2}:1" $WORKDIR $IDMAPDIR +log_must test -g $IDMAPDIR + +# Create a user namespace with the same idmapping +unshare -Urm echo test +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to create user namespace" +fi +unshare -Um /usr/bin/sleep 2h & +unshared_pid=$! +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to create user namespace" +fi +# wait for userns to be ready +sleep 1 +echo "${UID1} ${UID2} 1" > /proc/$unshared_pid/uid_map +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to write to uid_map" +fi +echo "${GID1} ${GID2} 1" > /proc/$unshared_pid/gid_map +if [ "$?" -ne "0" ]; then + log_unsupported "Failed to write to gid_map" +fi + +NSENTER="nsenter -t $unshared_pid --all -S ${UID1} -G ${GID1}" + +# gid bit can be set on the file +log_must $NSENTER touch $IDMAPDIR/file1 +log_must $NSENTER chmod 2654 $IDMAPDIR/file1 +log_must test -g $WORKDIR/file1 +log_must test -g $IDMAPDIR/file1 +log_must test "$UID1 $GID1" = "$($NSENTER stat -c '%u %g' $IDMAPDIR/file1)" + +# gid bit is carried over to new folder +log_must $NSENTER mkdir $IDMAPDIR/subdir +log_must test -g $WORKDIR/subdir +log_must test -g $IDMAPDIR/subdir +log_must test "$UID1 $GID1" = "$($NSENTER stat -c '%u %g' $IDMAPDIR/subdir)" + +log_pass "Verification of setting gid bit in userns is successful." + diff --git a/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib new file mode 100644 index 000000000000..980845ca209c --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/idmap_mount_common.kshlib @@ -0,0 +1,23 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/idmap_mount/idmap_mount.cfg diff --git a/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh b/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh new file mode 100755 index 000000000000..90a14f12058f --- /dev/null +++ b/tests/zfs-tests/tests/functional/idmap_mount/setup.ksh @@ -0,0 +1,30 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or https://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +. $STF_SUITE/include/libtest.shlib + +# unable to do idmapped mount in a local zone +verify_runnable "global" + +DISK=${DISKS%% *} +default_setup $DISK + diff --git a/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh b/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh index 40bff77f2107..d70b42e07fc0 100755 --- a/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh +++ b/tests/zfs-tests/tests/functional/inheritance/inherit_001_pos.ksh @@ -26,6 +26,7 @@ # # Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# Copyright (c) 2022 Hewlett Packard Enterprise Development LP. # . $STF_SUITE/include/libtest.shlib @@ -376,7 +377,8 @@ set -A prop "checksum" "" \ "sharenfs" "" \ "recordsize" "recsize" \ "snapdir" "" \ - "readonly" "" + "readonly" "" \ + "redundant_metadata" "" # # Note except for the mountpoint default value (which is handled in @@ -387,12 +389,14 @@ set -A prop "checksum" "" \ set -A def_val "on" "on" "on" \ "off" "" \ "hidden" \ - "off" + "off" \ + "all" set -A local_val "off" "off" "off" \ "on" "" \ "visible" \ - "off" + "off" \ + "none" # # Add system specific values