zfs: merge openzfs/zfs@d62bafee9
Notable upstream pull request merges:
#13857 Enforce "-F" flag on resuming recv of full/newfs on existing dataset
#13928 Revert "Reduce dbuf_find() lock contention"
#13928 Dynamically size dbuf hash mutex array
#13930 zpool: Don't print "repairing" on force faulted drives
#13938 Bring per_txg_dirty_frees_percent back to 30
#13939 Fix panic in dsl_process_sub_livelist for EINTR
#13954 Fix bad free in skein code
#13967 Fix potential NULL pointer dereference in dsl_dataset_promote_check()
Obtained from: OpenZFS
OpenZFS commit: d62bafee9f
This commit is contained in:
commit
be181ee2a2
@ -117,10 +117,10 @@ zdb_ot_name(dmu_object_type_t type)
|
||||
extern int reference_tracking_enable;
|
||||
extern int zfs_recover;
|
||||
extern unsigned long zfs_arc_meta_min, zfs_arc_meta_limit;
|
||||
extern int zfs_vdev_async_read_max_active;
|
||||
extern uint_t zfs_vdev_async_read_max_active;
|
||||
extern boolean_t spa_load_verify_dryrun;
|
||||
extern boolean_t spa_mode_readable_spacemaps;
|
||||
extern int zfs_reconstruct_indirect_combinations_max;
|
||||
extern uint_t zfs_reconstruct_indirect_combinations_max;
|
||||
extern uint_t zfs_btree_verify_intensity;
|
||||
|
||||
static const char cmdname[] = "zdb";
|
||||
@ -985,7 +985,7 @@ zdb_nicenum(uint64_t num, char *buf, size_t buflen)
|
||||
if (dump_opt['P'])
|
||||
(void) snprintf(buf, buflen, "%llu", (longlong_t)num);
|
||||
else
|
||||
nicenum(num, buf, sizeof (buf));
|
||||
nicenum(num, buf, buflen);
|
||||
}
|
||||
|
||||
static const char histo_stars[] = "****************************************";
|
||||
@ -1137,6 +1137,8 @@ dump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
if (data == NULL)
|
||||
kmem_free(arr, oursize);
|
||||
(void) printf("\t\t[]\n");
|
||||
return;
|
||||
}
|
||||
@ -4418,9 +4420,14 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
|
||||
default:
|
||||
abd = abd_alloc_for_io(asize, B_TRUE);
|
||||
abd_copy_from_buf_off(abd, &this_lb, 0, asize);
|
||||
zio_decompress_data(L2BLK_GET_COMPRESS(
|
||||
if (zio_decompress_data(L2BLK_GET_COMPRESS(
|
||||
(&lbps[0])->lbp_prop), abd, &this_lb,
|
||||
asize, sizeof (this_lb), NULL);
|
||||
asize, sizeof (this_lb), NULL) != 0) {
|
||||
(void) printf("L2ARC block decompression "
|
||||
"failed\n");
|
||||
abd_free(abd);
|
||||
goto out;
|
||||
}
|
||||
abd_free(abd);
|
||||
break;
|
||||
}
|
||||
@ -4455,7 +4462,7 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
|
||||
lbps[0] = lbps[1];
|
||||
lbps[1] = this_lb.lb_prev_lbp;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!dump_opt['q']) {
|
||||
(void) printf("log_blk_count:\t %llu with valid cksum\n",
|
||||
(u_longlong_t)rebuild->dh_lb_count);
|
||||
@ -6203,10 +6210,10 @@ zdb_check_for_obsolete_leaks(vdev_t *vd, zdb_cb_t *zcb)
|
||||
*/
|
||||
for (uint64_t inner_offset = 0;
|
||||
inner_offset < DVA_GET_ASIZE(&vimep->vimep_dst);
|
||||
inner_offset += 1 << vd->vdev_ashift) {
|
||||
inner_offset += 1ULL << vd->vdev_ashift) {
|
||||
if (range_tree_contains(msp->ms_allocatable,
|
||||
offset + inner_offset, 1 << vd->vdev_ashift)) {
|
||||
obsolete_bytes += 1 << vd->vdev_ashift;
|
||||
offset + inner_offset, 1ULL << vd->vdev_ashift)) {
|
||||
obsolete_bytes += 1ULL << vd->vdev_ashift;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7057,8 +7064,11 @@ import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
|
||||
freecfg = B_TRUE;
|
||||
}
|
||||
|
||||
if (asprintf(&bogus_name, "%s%s", poolname, BOGUS_SUFFIX) == -1)
|
||||
if (asprintf(&bogus_name, "%s%s", poolname, BOGUS_SUFFIX) == -1) {
|
||||
if (target != poolname)
|
||||
free(poolname);
|
||||
return (NULL);
|
||||
}
|
||||
fnvlist_add_string(cfg, ZPOOL_CONFIG_POOL_NAME, bogus_name);
|
||||
|
||||
error = spa_import(bogus_name, cfg, NULL,
|
||||
@ -7073,6 +7083,7 @@ import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
|
||||
|
||||
if (new_path != NULL && path_start != NULL) {
|
||||
if (asprintf(new_path, "%s%s", bogus_name, path_start) == -1) {
|
||||
free(bogus_name);
|
||||
if (path_start != NULL)
|
||||
free(poolname);
|
||||
return (NULL);
|
||||
@ -7586,7 +7597,7 @@ dump_mos_leaks(spa_t *spa)
|
||||
} else {
|
||||
dmu_object_info_t doi;
|
||||
const char *name;
|
||||
dmu_object_info(mos, object, &doi);
|
||||
VERIFY0(dmu_object_info(mos, object, &doi));
|
||||
if (doi.doi_type & DMU_OT_NEWTYPE) {
|
||||
dmu_object_byteswap_t bswap =
|
||||
DMU_OT_BYTESWAP(doi.doi_type);
|
||||
@ -8193,8 +8204,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
||||
vd = zdb_vdev_lookup(spa->spa_root_vdev, vdev);
|
||||
if (vd == NULL) {
|
||||
(void) printf("***Invalid vdev: %s\n", vdev);
|
||||
free(dup);
|
||||
return;
|
||||
goto done;
|
||||
} else {
|
||||
if (vd->vdev_path)
|
||||
(void) fprintf(stderr, "Found vdev: %s\n",
|
||||
@ -8698,6 +8708,8 @@ main(int argc, char **argv)
|
||||
usage();
|
||||
dump_opt['v'] = verbose;
|
||||
error = dump_path(argv[0], argv[1], &object);
|
||||
if (error != 0)
|
||||
fatal("internal error: %s", strerror(error));
|
||||
}
|
||||
|
||||
if (dump_opt['X'] || dump_opt['F'])
|
||||
|
@ -80,6 +80,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||
char *path = NULL;
|
||||
uint_t c, children;
|
||||
nvlist_t **child;
|
||||
uint64_t vdev_guid;
|
||||
|
||||
/*
|
||||
* First iterate over any children.
|
||||
@ -100,7 +101,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++) {
|
||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
||||
return (B_TRUE);
|
||||
}
|
||||
}
|
||||
@ -109,7 +110,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++) {
|
||||
if (zfs_agent_iter_vdev(zhp, child[c], gsp)) {
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_SPARE;
|
||||
gsp->gs_vdev_type = DEVICE_TYPE_L2ARC;
|
||||
return (B_TRUE);
|
||||
}
|
||||
}
|
||||
@ -126,6 +127,21 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
|
||||
&gsp->gs_vdev_expandtime);
|
||||
return (B_TRUE);
|
||||
}
|
||||
/*
|
||||
* Otherwise, on a vdev guid match, grab the devid and expansion
|
||||
* time. The devid might be missing on removal since its not part
|
||||
* of blkid cache and L2ARC VDEV does not contain pool guid in its
|
||||
* blkid, so this is a special case for L2ARC VDEV.
|
||||
*/
|
||||
else if (gsp->gs_vdev_guid != 0 && gsp->gs_devid == NULL &&
|
||||
nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &vdev_guid) == 0 &&
|
||||
gsp->gs_vdev_guid == vdev_guid) {
|
||||
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
|
||||
&gsp->gs_devid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME,
|
||||
&gsp->gs_vdev_expandtime);
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
return (B_FALSE);
|
||||
}
|
||||
@ -148,7 +164,7 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
|
||||
/*
|
||||
* if a match was found then grab the pool guid
|
||||
*/
|
||||
if (gsp->gs_vdev_guid) {
|
||||
if (gsp->gs_vdev_guid && gsp->gs_devid) {
|
||||
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||
&gsp->gs_pool_guid);
|
||||
}
|
||||
@ -195,11 +211,13 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
||||
uint64_t pool_guid = 0, vdev_guid = 0;
|
||||
guid_search_t search = { 0 };
|
||||
device_type_t devtype = DEVICE_TYPE_PRIMARY;
|
||||
char *devid = NULL;
|
||||
|
||||
class = "resource.fs.zfs.removed";
|
||||
subclass = "";
|
||||
|
||||
(void) nvlist_add_string(payload, FM_CLASS, class);
|
||||
(void) nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid);
|
||||
(void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid);
|
||||
|
||||
@ -209,20 +227,24 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
||||
(void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2);
|
||||
|
||||
/*
|
||||
* If devid is missing but vdev_guid is available, find devid
|
||||
* and pool_guid from vdev_guid.
|
||||
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
|
||||
* ZFS_EV_POOL_GUID may be missing so find them.
|
||||
*/
|
||||
if (pool_guid == 0 || vdev_guid == 0) {
|
||||
if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER,
|
||||
&search.gs_devid) == 0) &&
|
||||
(zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search)
|
||||
== 1)) {
|
||||
if (pool_guid == 0)
|
||||
pool_guid = search.gs_pool_guid;
|
||||
if (vdev_guid == 0)
|
||||
vdev_guid = search.gs_vdev_guid;
|
||||
devtype = search.gs_vdev_type;
|
||||
}
|
||||
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
|
||||
if (devid == NULL)
|
||||
search.gs_vdev_guid = vdev_guid;
|
||||
else
|
||||
search.gs_devid = devid;
|
||||
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
|
||||
if (devid == NULL)
|
||||
devid = search.gs_devid;
|
||||
if (pool_guid == 0)
|
||||
pool_guid = search.gs_pool_guid;
|
||||
if (vdev_guid == 0)
|
||||
vdev_guid = search.gs_vdev_guid;
|
||||
devtype = search.gs_vdev_type;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -235,7 +257,9 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
|
||||
search.gs_vdev_expandtime + 10 > tv.tv_sec) {
|
||||
zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' "
|
||||
"for recently expanded device '%s'", EC_DEV_REMOVE,
|
||||
search.gs_devid);
|
||||
devid);
|
||||
fnvlist_free(payload);
|
||||
free(event);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -323,10 +323,14 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
||||
boolean_t is_disk;
|
||||
vdev_aux_t aux;
|
||||
uint64_t state = 0;
|
||||
int l2arc;
|
||||
vdev_stat_t *vs;
|
||||
unsigned int c;
|
||||
|
||||
fmd_hdl_debug(hdl, "zfs_retire_recv: '%s'", class);
|
||||
|
||||
nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE, &state);
|
||||
(void) nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE,
|
||||
&state);
|
||||
|
||||
/*
|
||||
* If this is a resource notifying us of device removal then simply
|
||||
@ -351,13 +355,32 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
|
||||
|
||||
devname = zpool_vdev_name(NULL, zhp, vdev, B_FALSE);
|
||||
|
||||
/* Can't replace l2arc with a spare: offline the device */
|
||||
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
|
||||
&devtype) == 0 && strcmp(devtype, VDEV_TYPE_L2CACHE) == 0) {
|
||||
fmd_hdl_debug(hdl, "zpool_vdev_offline '%s'", devname);
|
||||
zpool_vdev_offline(zhp, devname, B_TRUE);
|
||||
} else if (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE) {
|
||||
nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
|
||||
(uint64_t **)&vs, &c);
|
||||
|
||||
/*
|
||||
* If state removed is requested for already removed vdev,
|
||||
* its a loopback event from spa_async_remove(). Just
|
||||
* ignore it.
|
||||
*/
|
||||
if (vs->vs_state == VDEV_STATE_REMOVED &&
|
||||
state == VDEV_STATE_REMOVED)
|
||||
return;
|
||||
|
||||
l2arc = (nvlist_lookup_string(nvl,
|
||||
FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE, &devtype) == 0 &&
|
||||
strcmp(devtype, VDEV_TYPE_L2CACHE) == 0);
|
||||
|
||||
/* Remove the vdev since device is unplugged */
|
||||
if (l2arc || (strcmp(class, "resource.fs.zfs.removed") == 0)) {
|
||||
int status = zpool_vdev_remove_wanted(zhp, devname);
|
||||
fmd_hdl_debug(hdl, "zpool_vdev_remove_wanted '%s'"
|
||||
", ret:%d", devname, status);
|
||||
}
|
||||
|
||||
/* Replace the vdev with a spare if its not a l2arc */
|
||||
if (!l2arc && (!fmd_prop_get_int32(hdl, "spare_on_remove") ||
|
||||
replace_with_spare(hdl, zhp, vdev) == B_FALSE)) {
|
||||
/* Could not handle with spare */
|
||||
fmd_hdl_debug(hdl, "no spare for '%s'", devname);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ void zed_log_syslog_close(void);
|
||||
|
||||
void zed_log_msg(int priority, const char *fmt, ...);
|
||||
|
||||
__attribute__((format(printf, 1, 2), __noreturn__))
|
||||
void zed_log_die(const char *fmt, ...);
|
||||
|
||||
#endif /* !ZED_LOG_H */
|
||||
|
@ -2459,7 +2459,8 @@ upgrade_set_callback(zfs_handle_t *zhp, void *data)
|
||||
cb->cb_numupgraded++;
|
||||
else
|
||||
cb->cb_numfailed++;
|
||||
(void) strcpy(cb->cb_lastfs, zfs_get_name(zhp));
|
||||
(void) strlcpy(cb->cb_lastfs, zfs_get_name(zhp),
|
||||
sizeof (cb->cb_lastfs));
|
||||
} else if (version > cb->cb_version) {
|
||||
/* can't downgrade */
|
||||
(void) printf(gettext("%s: can not be downgraded; "
|
||||
@ -6357,8 +6358,8 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
|
||||
++errors;
|
||||
continue;
|
||||
}
|
||||
(void) strncpy(parent, path, delim - path);
|
||||
parent[delim - path] = '\0';
|
||||
(void) strlcpy(parent, path, MIN(sizeof (parent),
|
||||
delim - path + 1));
|
||||
|
||||
zhp = zfs_open(g_zfs, parent,
|
||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||
@ -7395,8 +7396,11 @@ unshare_unmount(int op, int argc, char **argv)
|
||||
((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL))
|
||||
nomem();
|
||||
|
||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL)
|
||||
if ((mnttab = fopen(MNTTAB, "re")) == NULL) {
|
||||
uu_avl_destroy(tree);
|
||||
uu_avl_pool_destroy(pool);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
while (getmntent(mnttab, &entry) == 0) {
|
||||
|
||||
|
@ -295,6 +295,8 @@ zhack_do_feature_enable(int argc, char **argv)
|
||||
feature.fi_flags |= ZFEATURE_FLAG_READONLY_COMPAT;
|
||||
break;
|
||||
case 'd':
|
||||
if (desc != NULL)
|
||||
free(desc);
|
||||
desc = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
|
@ -115,12 +115,12 @@ parse_pathname(const char *inpath, char *dataset, char *relpath,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
(void) strcpy(dataset, mp.mnt_special);
|
||||
(void) strlcpy(dataset, mp.mnt_special, MAXNAMELEN);
|
||||
|
||||
rel = fullpath + strlen(mp.mnt_mountp);
|
||||
if (rel[0] == '/')
|
||||
rel++;
|
||||
(void) strcpy(relpath, rel);
|
||||
(void) strlcpy(relpath, rel, MAXPATHLEN);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -258,7 +258,7 @@ translate_record(err_type_t type, const char *object, const char *range,
|
||||
}
|
||||
|
||||
dataset[0] = '\0';
|
||||
(void) strcpy(poolname, object);
|
||||
(void) strlcpy(poolname, object, MAXNAMELEN);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -298,7 +298,7 @@ translate_record(err_type_t type, const char *object, const char *range,
|
||||
/*
|
||||
* Copy the pool name
|
||||
*/
|
||||
(void) strcpy(poolname, dataset);
|
||||
(void) strlcpy(poolname, dataset, MAXNAMELEN);
|
||||
if ((slash = strchr(poolname, '/')) != NULL)
|
||||
*slash = '\0';
|
||||
|
||||
|
@ -1196,6 +1196,7 @@ zpool_do_remove(int argc, char **argv)
|
||||
return (1);
|
||||
|
||||
if (stop && noop) {
|
||||
zpool_close(zhp);
|
||||
(void) fprintf(stderr, gettext("stop request ignored\n"));
|
||||
return (0);
|
||||
}
|
||||
@ -2462,7 +2463,14 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||
(void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS,
|
||||
(uint64_t **)&ps, &c);
|
||||
|
||||
if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) {
|
||||
/*
|
||||
* If you force fault a drive that's resilvering, its scan stats can
|
||||
* get frozen in time, giving the false impression that it's
|
||||
* being resilvered. That's why we check the state to see if the vdev
|
||||
* is healthy before reporting "resilvering" or "repairing".
|
||||
*/
|
||||
if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0 &&
|
||||
vs->vs_state == VDEV_STATE_HEALTHY) {
|
||||
if (vs->vs_scan_processed != 0) {
|
||||
(void) printf(gettext(" (%s)"),
|
||||
(ps->pss_func == POOL_SCAN_RESILVER) ?
|
||||
@ -2474,7 +2482,7 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
|
||||
|
||||
/* The top-level vdevs have the rebuild stats */
|
||||
if (vrs != NULL && vrs->vrs_state == VDEV_REBUILD_ACTIVE &&
|
||||
children == 0) {
|
||||
children == 0 && vs->vs_state == VDEV_STATE_HEALTHY) {
|
||||
if (vs->vs_rebuild_processed != 0) {
|
||||
(void) printf(gettext(" (resilvering)"));
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ get_vdev_name(nvlist_t *nvroot, const char *parent_name)
|
||||
uint64_t vdev_id = 0;
|
||||
|
||||
char *vdev_type = (char *)"unknown";
|
||||
nvlist_lookup_string(nvroot, ZPOOL_CONFIG_TYPE, &vdev_type);
|
||||
(void) nvlist_lookup_string(nvroot, ZPOOL_CONFIG_TYPE, &vdev_type);
|
||||
|
||||
if (nvlist_lookup_uint64(
|
||||
nvroot, ZPOOL_CONFIG_ID, &vdev_id) != 0)
|
||||
@ -302,9 +302,9 @@ get_vdev_desc(nvlist_t *nvroot, const char *parent_name)
|
||||
char *vdev_type = (char *)"unknown";
|
||||
uint64_t vdev_id = UINT64_MAX;
|
||||
char *vdev_path = NULL;
|
||||
nvlist_lookup_string(nvroot, ZPOOL_CONFIG_TYPE, &vdev_type);
|
||||
nvlist_lookup_uint64(nvroot, ZPOOL_CONFIG_ID, &vdev_id);
|
||||
nvlist_lookup_string(nvroot, ZPOOL_CONFIG_PATH, &vdev_path);
|
||||
(void) nvlist_lookup_string(nvroot, ZPOOL_CONFIG_TYPE, &vdev_type);
|
||||
(void) nvlist_lookup_uint64(nvroot, ZPOOL_CONFIG_ID, &vdev_id);
|
||||
(void) nvlist_lookup_string(nvroot, ZPOOL_CONFIG_PATH, &vdev_path);
|
||||
|
||||
if (parent_name == NULL) {
|
||||
s = escape_string(vdev_type);
|
||||
@ -687,8 +687,10 @@ print_recursive_stats(stat_printer_f func, nvlist_t *nvroot,
|
||||
sizeof (vdev_name));
|
||||
|
||||
for (c = 0; c < children; c++) {
|
||||
print_recursive_stats(func, child[c], pool_name,
|
||||
err = print_recursive_stats(func, child[c], pool_name,
|
||||
vdev_name, descend);
|
||||
if (err)
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
|
@ -363,9 +363,6 @@ zstream_do_dump(int argc, char *argv[])
|
||||
BSWAP_64(drrb->drr_fromguid);
|
||||
}
|
||||
|
||||
featureflags =
|
||||
DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
|
||||
|
||||
(void) printf("BEGIN record\n");
|
||||
(void) printf("\thdrtype = %lld\n",
|
||||
DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo));
|
||||
@ -465,6 +462,9 @@ zstream_do_dump(int argc, char *argv[])
|
||||
BSWAP_64(drro->drr_maxblkid);
|
||||
}
|
||||
|
||||
featureflags =
|
||||
DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
|
||||
|
||||
if (featureflags & DMU_BACKUP_FEATURE_RAW &&
|
||||
drro->drr_bonuslen > drro->drr_raw_bonuslen) {
|
||||
(void) fprintf(stderr,
|
||||
|
@ -49,6 +49,7 @@ int
|
||||
zstream_do_token(int argc, char *argv[])
|
||||
{
|
||||
char *resume_token = NULL;
|
||||
libzfs_handle_t *hdl;
|
||||
|
||||
if (argc < 2) {
|
||||
(void) fprintf(stderr, "Need to pass the resume token\n");
|
||||
@ -57,7 +58,10 @@ zstream_do_token(int argc, char *argv[])
|
||||
|
||||
resume_token = argv[1];
|
||||
|
||||
libzfs_handle_t *hdl = libzfs_init();
|
||||
if ((hdl = libzfs_init()) == NULL) {
|
||||
(void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
nvlist_t *resume_nvl =
|
||||
zfs_send_resume_token_to_nvlist(hdl, resume_token);
|
||||
|
@ -253,10 +253,10 @@ 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 int metaslab_preload_limit;
|
||||
extern uint_t metaslab_preload_limit;
|
||||
extern int zfs_compressed_arc_enabled;
|
||||
extern int zfs_abd_scatter_enabled;
|
||||
extern int dmu_object_alloc_chunk_shift;
|
||||
extern uint_t dmu_object_alloc_chunk_shift;
|
||||
extern boolean_t zfs_force_some_double_word_sm_entries;
|
||||
extern unsigned long zio_decompress_fail_fraction;
|
||||
extern unsigned long zfs_reconstruct_indirect_damage_fraction;
|
||||
@ -1137,7 +1137,8 @@ process_options(int argc, char **argv)
|
||||
goto invalid;
|
||||
|
||||
int dirlen = strrchr(val, '/') - val;
|
||||
strncpy(zo->zo_alt_libpath, val, dirlen);
|
||||
strlcpy(zo->zo_alt_libpath, val,
|
||||
MIN(sizeof (zo->zo_alt_libpath), dirlen + 1));
|
||||
invalid_what = "library path", val = zo->zo_alt_libpath;
|
||||
if (strrchr(val, '/') == NULL && (errno = EINVAL))
|
||||
goto invalid;
|
||||
@ -1165,7 +1166,7 @@ ztest_kill(ztest_shared_t *zs)
|
||||
* See comment above spa_write_cachefile().
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE);
|
||||
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
|
||||
(void) raise(SIGKILL);
|
||||
@ -1543,7 +1544,7 @@ ztest_dmu_objset_own(const char *name, dmu_objset_type_t type,
|
||||
char *cp = NULL;
|
||||
char ddname[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
strcpy(ddname, name);
|
||||
strlcpy(ddname, name, sizeof (ddname));
|
||||
cp = strchr(ddname, '@');
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
@ -2214,7 +2215,7 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
||||
dmu_write(os, lr->lr_foid, offset, length, data, tx);
|
||||
} else {
|
||||
memcpy(abuf->b_data, data, length);
|
||||
dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx);
|
||||
VERIFY0(dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx));
|
||||
}
|
||||
|
||||
(void) ztest_log_write(zd, tx, lr);
|
||||
@ -3666,7 +3667,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
||||
oldguid = oldvd->vdev_guid;
|
||||
oldsize = vdev_get_min_asize(oldvd);
|
||||
oldvd_is_log = oldvd->vdev_top->vdev_islog;
|
||||
(void) strcpy(oldpath, oldvd->vdev_path);
|
||||
(void) strlcpy(oldpath, oldvd->vdev_path, MAXPATHLEN);
|
||||
pvd = oldvd->vdev_parent;
|
||||
pguid = pvd->vdev_guid;
|
||||
|
||||
@ -3702,7 +3703,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
|
||||
if (newvd->vdev_ops == &vdev_draid_spare_ops)
|
||||
newvd_is_dspare = B_TRUE;
|
||||
|
||||
(void) strcpy(newpath, newvd->vdev_path);
|
||||
(void) strlcpy(newpath, newvd->vdev_path, MAXPATHLEN);
|
||||
} else {
|
||||
(void) snprintf(newpath, MAXPATHLEN, ztest_dev_template,
|
||||
ztest_opts.zo_dir, ztest_opts.zo_pool,
|
||||
@ -4638,7 +4639,7 @@ ztest_dmu_object_next_chunk(ztest_ds_t *zd, uint64_t id)
|
||||
{
|
||||
(void) id;
|
||||
objset_t *os = zd->zd_os;
|
||||
int dnodes_per_chunk = 1 << dmu_object_alloc_chunk_shift;
|
||||
uint_t dnodes_per_chunk = 1 << dmu_object_alloc_chunk_shift;
|
||||
uint64_t object;
|
||||
|
||||
/*
|
||||
@ -6144,8 +6145,8 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
}
|
||||
vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)];
|
||||
guid0 = vd0->vdev_guid;
|
||||
(void) strcpy(path0, vd0->vdev_path);
|
||||
(void) strcpy(pathrand, vd0->vdev_path);
|
||||
(void) strlcpy(path0, vd0->vdev_path, MAXPATHLEN);
|
||||
(void) strlcpy(pathrand, vd0->vdev_path, MAXPATHLEN);
|
||||
|
||||
leaf = 0;
|
||||
leaves = 1;
|
||||
@ -6636,6 +6637,8 @@ ztest_global_vars_to_zdb_args(void)
|
||||
{
|
||||
char **args = calloc(2*ztest_opts.zo_gvars_count + 1, sizeof (char *));
|
||||
char **cur = args;
|
||||
if (args == NULL)
|
||||
return (NULL);
|
||||
for (size_t i = 0; i < ztest_opts.zo_gvars_count; i++) {
|
||||
*cur++ = (char *)"-o";
|
||||
*cur++ = ztest_opts.zo_gvars[i];
|
||||
@ -6905,6 +6908,10 @@ ztest_run_zdb(const char *pool)
|
||||
ztest_get_zdb_bin(bin, len);
|
||||
|
||||
char **set_gvars_args = ztest_global_vars_to_zdb_args();
|
||||
if (set_gvars_args == NULL) {
|
||||
fatal(B_FALSE, "Failed to allocate memory in "
|
||||
"ztest_global_vars_to_zdb_args(). Cannot run zdb.\n");
|
||||
}
|
||||
char *set_gvars_args_joined = join_strings(set_gvars_args, " ");
|
||||
free(set_gvars_args);
|
||||
|
||||
|
@ -52,6 +52,8 @@ AM_CPPFLAGS_NOCHECK += -D"asctime(...)=__attribute__((deprecated(\"Use strftime(
|
||||
AM_CPPFLAGS_NOCHECK += -D"asctime_r(...)=__attribute__((deprecated(\"Use strftime(3) instead!\"))) asctime_r(__VA_ARGS__)"
|
||||
AM_CPPFLAGS_NOCHECK += -D"gmtime(...)=__attribute__((deprecated(\"gmtime(3) isn't thread-safe. Use gmtime_r(3) instead!\"))) gmtime(__VA_ARGS__)"
|
||||
AM_CPPFLAGS_NOCHECK += -D"localtime(...)=__attribute__((deprecated(\"localtime(3) isn't thread-safe. Use localtime_r(3) instead!\"))) localtime(__VA_ARGS__)"
|
||||
AM_CPPFLAGS_NOCHECK += -D"strncpy(...)=__attribute__((deprecated(\"strncpy(3) is deprecated. Use strlcpy(3) instead!\"))) strncpy(__VA_ARGS__)"
|
||||
|
||||
AM_CPPFLAGS += $(AM_CPPFLAGS_NOCHECK)
|
||||
|
||||
if ASAN_ENABLED
|
||||
|
@ -103,6 +103,57 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE], [
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # bdev_kobj() is introduced from 5.12
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ], [
|
||||
ZFS_LINUX_TEST_SRC([bdev_kobj], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/kobject.h>
|
||||
], [
|
||||
struct block_device *bdev = NULL;
|
||||
struct kobject *disk_kobj;
|
||||
disk_kobj = bdev_kobj(bdev);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ], [
|
||||
AC_MSG_CHECKING([whether bdev_kobj() exists])
|
||||
ZFS_LINUX_TEST_RESULT([bdev_kobj], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BDEV_KOBJ, 1,
|
||||
[bdev_kobj() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # part_to_dev() was removed in 5.12
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV], [
|
||||
ZFS_LINUX_TEST_SRC([part_to_dev], [
|
||||
#include <linux/fs.h>
|
||||
#include <linux/blkdev.h>
|
||||
], [
|
||||
struct hd_struct *p = NULL;
|
||||
struct device *pdev;
|
||||
pdev = part_to_dev(p);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV], [
|
||||
AC_MSG_CHECKING([whether part_to_dev() exists])
|
||||
ZFS_LINUX_TEST_RESULT([part_to_dev], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PART_TO_DEV, 1,
|
||||
[part_to_dev() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 5.10 API, check_disk_change() is removed, in favor of
|
||||
dnl # bdev_check_media_change(), which doesn't force revalidation
|
||||
@ -405,6 +456,8 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_WHOLE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEVNAME
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_ISSUE_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_KOBJ
|
||||
ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
||||
@ -421,4 +474,6 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEVNAME
|
||||
ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
|
||||
ZFS_AC_KERNEL_BLKDEV_ISSUE_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_BLKDEV_BDEV_KOBJ
|
||||
ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV
|
||||
])
|
||||
|
@ -31,66 +31,6 @@
|
||||
|
||||
int condition0, condition1;
|
||||
|
||||
void
|
||||
abort()
|
||||
{
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
void
|
||||
exit(int status)
|
||||
{
|
||||
(void) status;
|
||||
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
void
|
||||
_exit(int status)
|
||||
{
|
||||
(void) status;
|
||||
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
void
|
||||
zed_log_die(const char *fmt, ...)
|
||||
{
|
||||
__coverity_format_string_sink__(fmt);
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
void
|
||||
panic(const char *fmt, ...)
|
||||
{
|
||||
__coverity_format_string_sink__(fmt);
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
void
|
||||
vpanic(const char *fmt, va_list adx)
|
||||
{
|
||||
(void) adx;
|
||||
|
||||
__coverity_format_string_sink__(fmt);
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
void
|
||||
uu_panic(const char *format, ...)
|
||||
{
|
||||
__coverity_format_string_sink__(format);
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
int
|
||||
libspl_assertf(const char *file, const char *func, int line,
|
||||
const char *format, ...)
|
||||
{
|
||||
__coverity_format_string_sink__(format);
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
int
|
||||
ddi_copyin(const void *from, void *to, size_t len, int flags)
|
||||
{
|
||||
@ -125,7 +65,7 @@ umem_alloc_aligned(size_t size, size_t align, int kmflags)
|
||||
{
|
||||
(void) align;
|
||||
|
||||
if (UMEM_NOFAIL & kmflags == UMEM_NOFAIL)
|
||||
if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL)
|
||||
return (__coverity_alloc__(size));
|
||||
else if (condition0)
|
||||
return (__coverity_alloc__(size));
|
||||
@ -136,7 +76,7 @@ umem_alloc_aligned(size_t size, size_t align, int kmflags)
|
||||
void *
|
||||
umem_alloc(size_t size, int kmflags)
|
||||
{
|
||||
if (UMEM_NOFAIL & kmflags == UMEM_NOFAIL)
|
||||
if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL)
|
||||
return (__coverity_alloc__(size));
|
||||
else if (condition0)
|
||||
return (__coverity_alloc__(size));
|
||||
@ -147,7 +87,7 @@ umem_alloc(size_t size, int kmflags)
|
||||
void *
|
||||
umem_zalloc(size_t size, int kmflags)
|
||||
{
|
||||
if (UMEM_NOFAIL & kmflags == UMEM_NOFAIL)
|
||||
if ((UMEM_NOFAIL & kmflags) == UMEM_NOFAIL)
|
||||
return (__coverity_alloc__(size));
|
||||
else if (condition0)
|
||||
return (__coverity_alloc__(size));
|
||||
@ -163,6 +103,32 @@ umem_free(void *buf, size_t size)
|
||||
__coverity_free__(buf);
|
||||
}
|
||||
|
||||
typedef struct {} umem_cache_t;
|
||||
|
||||
void *
|
||||
umem_cache_alloc(umem_cache_t *skc, int flags)
|
||||
{
|
||||
(void) skc;
|
||||
|
||||
if (condition1)
|
||||
__coverity_sleep__();
|
||||
|
||||
if ((UMEM_NOFAIL & flags) == UMEM_NOFAIL)
|
||||
return (__coverity_alloc_nosize__());
|
||||
else if (condition0)
|
||||
return (__coverity_alloc_nosize__());
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
umem_cache_free(umem_cache_t *skc, void *obj)
|
||||
{
|
||||
(void) skc;
|
||||
|
||||
__coverity_free__(obj);
|
||||
}
|
||||
|
||||
void *
|
||||
spl_kmem_alloc(size_t sz, int fl, const char *func, int line)
|
||||
{
|
||||
@ -243,13 +209,6 @@ free(void *buf)
|
||||
__coverity_free__(buf);
|
||||
}
|
||||
|
||||
int
|
||||
spl_panic(const char *file, const char *func, int line, const char *fmt, ...)
|
||||
{
|
||||
__coverity_format_string_sink__(fmt);
|
||||
__coverity_panic__();
|
||||
}
|
||||
|
||||
int
|
||||
sched_yield(void)
|
||||
{
|
||||
@ -398,25 +357,3 @@ __cond_resched(void)
|
||||
__coverity_sleep__();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An endian-independent filesystem must support doing byte swaps on data. We
|
||||
* attempt to suppress taint warnings, which are false positives for us.
|
||||
*/
|
||||
void
|
||||
byteswap_uint64_array(void *vbuf, size_t size)
|
||||
{
|
||||
__coverity_tainted_data_sanitize__(vbuf);
|
||||
}
|
||||
|
||||
void
|
||||
byteswap_uint32_array(void *vbuf, size_t size)
|
||||
{
|
||||
__coverity_tainted_data_sanitize__(vbuf);
|
||||
}
|
||||
|
||||
void
|
||||
byteswap_uint16_array(void *vbuf, size_t size)
|
||||
{
|
||||
__coverity_tainted_data_sanitize__(vbuf);
|
||||
}
|
||||
|
@ -480,7 +480,8 @@ zfs_key_config_load(pam_handle_t *pamh, zfs_key_config_t *config,
|
||||
} else if (strcmp(argv[c], "nounmount") == 0) {
|
||||
config->unmount_and_unload = 0;
|
||||
} else if (strcmp(argv[c], "prop_mountpoint") == 0) {
|
||||
config->homedir = strdup(entry->pw_dir);
|
||||
if (config->homedir == NULL)
|
||||
config->homedir = strdup(entry->pw_dir);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
@ -557,9 +558,8 @@ zfs_key_config_get_dataset(zfs_key_config_t *config)
|
||||
return (NULL);
|
||||
}
|
||||
ret[0] = 0;
|
||||
strcat(ret, config->homes_prefix);
|
||||
strcat(ret, "/");
|
||||
strcat(ret, config->username);
|
||||
(void) snprintf(ret, len + 1, "%s/%s", config->homes_prefix,
|
||||
config->username);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -810,7 +810,9 @@ pam_sm_close_session(pam_handle_t *pamh, int flags,
|
||||
return (PAM_SUCCESS);
|
||||
}
|
||||
zfs_key_config_t config;
|
||||
zfs_key_config_load(pamh, &config, argc, argv);
|
||||
if (zfs_key_config_load(pamh, &config, argc, argv) != 0) {
|
||||
return (PAM_SESSION_ERR);
|
||||
}
|
||||
if (config.uid < 1000) {
|
||||
zfs_key_config_free(&config);
|
||||
return (PAM_SUCCESS);
|
||||
|
@ -101,6 +101,7 @@ def enum(*sequential, **named):
|
||||
'ZFS_ERR_BADPROP',
|
||||
'ZFS_ERR_VDEV_NOTSUP',
|
||||
'ZFS_ERR_NOT_USER_NAMESPACE',
|
||||
'ZFS_ERR_RESUME_EXISTS',
|
||||
],
|
||||
{}
|
||||
)
|
||||
|
@ -44,7 +44,7 @@ INSTALLING INIT SCRIPT LINKS
|
||||
|
||||
update-rc.d zfs-import start 07 S . stop 07 0 1 6 .
|
||||
update-rc.d zfs-load-key start 02 2 3 4 5 . stop 06 0 1 6 .
|
||||
update-rc.d zfs-mount start 02 2 3 4 5 . stop 06 0 1 6 .
|
||||
update-rc.d zfs-mount start 02 S . stop 06 0 1 6 .
|
||||
update-rc.d zfs-zed start 07 2 3 4 5 . stop 08 0 1 6 .
|
||||
update-rc.d zfs-share start 27 2 3 4 5 . stop 05 0 1 6 .
|
||||
|
||||
|
@ -13,10 +13,11 @@
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: zfs-mount
|
||||
# Required-Start: $local_fs zfs-import
|
||||
# Required-Start: zfs-import
|
||||
# Required-Stop: $local_fs zfs-import
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Start: S
|
||||
# Default-Stop: 0 1 6
|
||||
# X-Start-Before: mountall
|
||||
# X-Stop-After: zfs-zed
|
||||
# Short-Description: Mount ZFS filesystems and volumes
|
||||
# Description: Run the `zfs mount -a` or `zfs umount -a` commands.
|
||||
|
@ -42,7 +42,8 @@ extern "C" {
|
||||
void uu_set_error(uint_t);
|
||||
|
||||
|
||||
void uu_panic(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
__attribute__((format(printf, 1, 2), __noreturn__))
|
||||
void uu_panic(const char *format, ...);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -152,6 +152,7 @@ typedef enum zfs_error {
|
||||
EZFS_VDEV_NOTSUP, /* ops not supported for this type of vdev */
|
||||
EZFS_NOT_USER_NAMESPACE, /* a file is not a user namespace */
|
||||
EZFS_CKSUM, /* insufficient replicas */
|
||||
EZFS_RESUME_EXISTS, /* Resume on existing dataset without force */
|
||||
EZFS_UNKNOWN
|
||||
} zfs_error_t;
|
||||
|
||||
@ -309,6 +310,7 @@ _LIBZFS_H int zpool_vdev_indirect_size(zpool_handle_t *, const char *,
|
||||
uint64_t *);
|
||||
_LIBZFS_H int zpool_vdev_split(zpool_handle_t *, char *, nvlist_t **,
|
||||
nvlist_t *, splitflags_t);
|
||||
_LIBZFS_H int zpool_vdev_remove_wanted(zpool_handle_t *, const char *);
|
||||
|
||||
_LIBZFS_H int zpool_vdev_fault(zpool_handle_t *, uint64_t, vdev_aux_t);
|
||||
_LIBZFS_H int zpool_vdev_degrade(zpool_handle_t *, uint64_t, vdev_aux_t);
|
||||
|
@ -56,8 +56,8 @@ typedef const struct pool_config_ops {
|
||||
/*
|
||||
* An instance of pool_config_ops_t is expected in the caller's binary.
|
||||
*/
|
||||
_LIBZUTIL_H const pool_config_ops_t libzfs_config_ops;
|
||||
_LIBZUTIL_H const pool_config_ops_t libzpool_config_ops;
|
||||
_LIBZUTIL_H pool_config_ops_t libzfs_config_ops;
|
||||
_LIBZUTIL_H pool_config_ops_t libzpool_config_ops;
|
||||
|
||||
typedef struct importargs {
|
||||
char **path; /* a list of paths to search */
|
||||
@ -71,9 +71,9 @@ typedef struct importargs {
|
||||
} importargs_t;
|
||||
|
||||
_LIBZUTIL_H nvlist_t *zpool_search_import(void *, importargs_t *,
|
||||
const pool_config_ops_t *);
|
||||
pool_config_ops_t *);
|
||||
_LIBZUTIL_H int zpool_find_config(void *, const char *, nvlist_t **,
|
||||
importargs_t *, const pool_config_ops_t *);
|
||||
importargs_t *, pool_config_ops_t *);
|
||||
|
||||
_LIBZUTIL_H const char * const * zpool_default_search_paths(size_t *count);
|
||||
_LIBZUTIL_H int zpool_read_label(int, nvlist_t **, int *);
|
||||
|
@ -44,6 +44,18 @@
|
||||
|
||||
#include <sys/endian.h>
|
||||
|
||||
#ifdef __COVERITY__
|
||||
/*
|
||||
* Coverity's taint warnings from byteswapping are false positives for us.
|
||||
* Suppress them by hiding byteswapping from Coverity.
|
||||
*/
|
||||
#define BSWAP_8(x) ((x) & 0xff)
|
||||
#define BSWAP_16(x) ((x) & 0xffff)
|
||||
#define BSWAP_32(x) ((x) & 0xffffffff)
|
||||
#define BSWAP_64(x) (x)
|
||||
|
||||
#else /* __COVERITY__ */
|
||||
|
||||
/*
|
||||
* Macros to reverse byte order
|
||||
*/
|
||||
@ -52,6 +64,8 @@
|
||||
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
|
||||
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
|
||||
|
||||
#endif /* __COVERITY__ */
|
||||
|
||||
#define BMASK_8(x) ((x) & 0xff)
|
||||
#define BMASK_16(x) ((x) & 0xffff)
|
||||
#define BMASK_32(x) ((x) & 0xffffffff)
|
||||
|
@ -71,7 +71,7 @@ extern void vuprintf(const char *, __va_list)
|
||||
__attribute__((format(printf, 1, 0)));
|
||||
|
||||
extern void panic(const char *, ...)
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
__attribute__((format(printf, 1, 2), __noreturn__));
|
||||
|
||||
#endif /* !_ASM */
|
||||
|
||||
|
@ -54,9 +54,16 @@
|
||||
/*
|
||||
* Common DEBUG functionality.
|
||||
*/
|
||||
int spl_panic(const char *file, const char *func, int line,
|
||||
const char *fmt, ...);
|
||||
void spl_dumpstack(void);
|
||||
extern void spl_panic(const char *file, const char *func, int line,
|
||||
const char *fmt, ...) __attribute__((__noreturn__));
|
||||
extern void spl_dumpstack(void);
|
||||
|
||||
static inline int
|
||||
spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
{
|
||||
spl_panic(file, func, line, "%s", buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef expect
|
||||
#define expect(expr, value) (__builtin_expect((expr), (value)))
|
||||
@ -69,8 +76,8 @@ void spl_dumpstack(void);
|
||||
|
||||
#define VERIFY(cond) \
|
||||
(void) (unlikely(!(cond)) && \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s", "VERIFY(" #cond ") failed\n"))
|
||||
spl_assert("VERIFY(" #cond ") failed\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
@ -158,13 +165,14 @@ void spl_dumpstack(void);
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT VERIFY
|
||||
#define IMPLY(A, B) \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") implies (" #B ")")))
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_assert("(" #A ") implies (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
#define EQUIV(A, B) \
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") is equivalent to (" #B ")")))
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_assert("(" #A ") is equivalent to (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
@ -52,8 +52,10 @@ MALLOC_DECLARE(M_SOLARIS);
|
||||
|
||||
typedef struct vmem vmem_t;
|
||||
|
||||
extern char *kmem_asprintf(const char *, ...);
|
||||
extern char *kmem_vasprintf(const char *fmt, va_list ap);
|
||||
extern char *kmem_asprintf(const char *, ...)
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
extern char *kmem_vasprintf(const char *fmt, va_list ap)
|
||||
__attribute__((format(printf, 1, 0)));
|
||||
|
||||
typedef struct kmem_cache {
|
||||
char kc_name[32];
|
||||
@ -70,6 +72,7 @@ typedef struct kmem_cache {
|
||||
extern uint64_t spl_kmem_cache_inuse(kmem_cache_t *cache);
|
||||
extern uint64_t spl_kmem_cache_entry_size(kmem_cache_t *cache);
|
||||
|
||||
__attribute__((alloc_size(1)))
|
||||
void *zfs_kmem_alloc(size_t size, int kmflags);
|
||||
void zfs_kmem_free(void *buf, size_t size);
|
||||
uint64_t kmem_size(void);
|
||||
|
@ -94,7 +94,7 @@ void seq_printf(struct seq_file *m, const char *fmt, ...);
|
||||
|
||||
|
||||
typedef struct kstat_module {
|
||||
char ksm_name[KSTAT_STRLEN+1]; /* module name */
|
||||
char ksm_name[KSTAT_STRLEN]; /* module name */
|
||||
struct list_head ksm_module_list; /* module linkage */
|
||||
struct list_head ksm_kstat_list; /* list of kstat entries */
|
||||
struct proc_dir_entry *ksm_proc; /* proc entry */
|
||||
@ -112,10 +112,10 @@ struct kstat_s {
|
||||
kid_t ks_kid; /* unique kstat ID */
|
||||
hrtime_t ks_crtime; /* creation time */
|
||||
hrtime_t ks_snaptime; /* last access time */
|
||||
char ks_module[KSTAT_STRLEN+1]; /* provider module name */
|
||||
char ks_module[KSTAT_STRLEN]; /* provider module name */
|
||||
int ks_instance; /* provider module instance */
|
||||
char ks_name[KSTAT_STRLEN+1]; /* kstat name */
|
||||
char ks_class[KSTAT_STRLEN+1]; /* kstat class */
|
||||
char ks_name[KSTAT_STRLEN]; /* kstat name */
|
||||
char ks_class[KSTAT_STRLEN]; /* kstat class */
|
||||
uchar_t ks_type; /* kstat data type */
|
||||
uchar_t ks_flags; /* kstat flags */
|
||||
void *ks_data; /* kstat type-specific data */
|
||||
@ -181,7 +181,7 @@ typedef struct kstat_io {
|
||||
} kstat_io_t;
|
||||
|
||||
typedef struct kstat_timer {
|
||||
char name[KSTAT_STRLEN+1]; /* event name */
|
||||
char name[KSTAT_STRLEN]; /* event name */
|
||||
u_longlong_t num_events; /* number of events */
|
||||
hrtime_t elapsed_time; /* cumulative elapsed time */
|
||||
hrtime_t min_time; /* shortest event duration */
|
||||
|
@ -88,4 +88,5 @@ zfs_isa207_available(void)
|
||||
{
|
||||
return ((cpu_features2 & PPC_FEATURE2_ARCH_2_07) != 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -71,6 +71,7 @@ kernel_spl_sys_HEADERS = \
|
||||
%D%/spl/sys/kmem_cache.h \
|
||||
%D%/spl/sys/kstat.h \
|
||||
%D%/spl/sys/list.h \
|
||||
%D%/spl/sys/misc.h \
|
||||
%D%/spl/sys/mod_os.h \
|
||||
%D%/spl/sys/mutex.h \
|
||||
%D%/spl/sys/param.h \
|
||||
|
@ -261,6 +261,32 @@ bio_set_bi_error(struct bio *bio, int error)
|
||||
#define BIO_END_IO(bio, error) bio_endio(bio, error);
|
||||
#endif /* HAVE_1ARG_BIO_END_IO_T */
|
||||
|
||||
/*
|
||||
* 5.15 MACRO,
|
||||
* GD_DEAD
|
||||
*
|
||||
* 2.6.36 - 5.14 MACRO,
|
||||
* GENHD_FL_UP
|
||||
*
|
||||
* Check the disk status and return B_TRUE if alive
|
||||
* otherwise B_FALSE
|
||||
*/
|
||||
static inline boolean_t
|
||||
zfs_check_disk_status(struct block_device *bdev)
|
||||
{
|
||||
#if defined(GENHD_FL_UP)
|
||||
return (!!(bdev->bd_disk->flags & GENHD_FL_UP));
|
||||
#elif defined(GD_DEAD)
|
||||
return (!test_bit(GD_DEAD, &bdev->bd_disk->state));
|
||||
#else
|
||||
/*
|
||||
* This is encountered if neither GENHD_FL_UP nor GD_DEAD is available in
|
||||
* the kernel - likely due to an MACRO change that needs to be chased down.
|
||||
*/
|
||||
#error "Unsupported kernel: no usable disk status check"
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 4.1 API,
|
||||
* 3.10.0 CentOS 7.x API,
|
||||
|
@ -36,11 +36,26 @@
|
||||
|
||||
#include <sys/isa_defs.h>
|
||||
|
||||
#ifdef __COVERITY__
|
||||
/*
|
||||
* Coverity's taint warnings from byteswapping are false positives for us.
|
||||
* Suppress them by hiding byteswapping from Coverity.
|
||||
*/
|
||||
|
||||
#define BSWAP_8(x) ((x) & 0xff)
|
||||
#define BSWAP_16(x) ((x) & 0xffff)
|
||||
#define BSWAP_32(x) ((x) & 0xffffffff)
|
||||
#define BSWAP_64(x) (x)
|
||||
|
||||
#else /* __COVERITY__ */
|
||||
|
||||
#define BSWAP_8(x) ((x) & 0xff)
|
||||
#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
|
||||
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
|
||||
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
|
||||
|
||||
#endif /* __COVERITY__ */
|
||||
|
||||
#define LE_16(x) cpu_to_le16(x)
|
||||
#define LE_32(x) cpu_to_le32(x)
|
||||
#define LE_64(x) cpu_to_le64(x)
|
||||
|
@ -41,7 +41,7 @@ extern void cmn_err(int, const char *, ...)
|
||||
extern void vcmn_err(int, const char *, va_list)
|
||||
__attribute__((format(printf, 2, 0)));
|
||||
extern void vpanic(const char *, va_list)
|
||||
__attribute__((format(printf, 1, 0)));
|
||||
__attribute__((format(printf, 1, 0), __noreturn__));
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
|
@ -54,17 +54,24 @@
|
||||
#define __maybe_unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
int spl_panic(const char *file, const char *func, int line,
|
||||
const char *fmt, ...);
|
||||
void spl_dumpstack(void);
|
||||
extern void spl_panic(const char *file, const char *func, int line,
|
||||
const char *fmt, ...) __attribute__((__noreturn__));
|
||||
extern void spl_dumpstack(void);
|
||||
|
||||
static inline int
|
||||
spl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
{
|
||||
spl_panic(file, func, line, "%s", buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define PANIC(fmt, a...) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||
|
||||
#define VERIFY(cond) \
|
||||
(void) (unlikely(!(cond)) && \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s", "VERIFY(" #cond ") failed\n"))
|
||||
spl_assert("VERIFY(" #cond ") failed\n", \
|
||||
__FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
@ -152,13 +159,13 @@ void spl_dumpstack(void);
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT VERIFY
|
||||
#define IMPLY(A, B) \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") implies (" #B ")")))
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_assert("(" #A ") implies (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
#define EQUIV(A, B) \
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") is equivalent to (" #B ")")))
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_assert("(" #A ") is equivalent to (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
@ -31,8 +31,10 @@
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
extern int kmem_debugging(void);
|
||||
extern char *kmem_vasprintf(const char *fmt, va_list ap);
|
||||
extern char *kmem_asprintf(const char *fmt, ...);
|
||||
extern char *kmem_vasprintf(const char *fmt, va_list ap)
|
||||
__attribute__((format(printf, 1, 0)));
|
||||
extern char *kmem_asprintf(const char *fmt, ...)
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
extern char *kmem_strdup(const char *str);
|
||||
extern void kmem_strfree(char *str);
|
||||
|
||||
@ -179,8 +181,10 @@ extern unsigned int spl_kmem_alloc_max;
|
||||
#define kmem_free(ptr, sz) spl_kmem_free((ptr), (sz))
|
||||
#define kmem_cache_reap_active spl_kmem_cache_reap_active
|
||||
|
||||
extern void *spl_kmem_alloc(size_t sz, int fl, const char *func, int line);
|
||||
extern void *spl_kmem_zalloc(size_t sz, int fl, const char *func, int line);
|
||||
extern void *spl_kmem_alloc(size_t sz, int fl, const char *func, int line)
|
||||
__attribute__((alloc_size(1)));
|
||||
extern void *spl_kmem_zalloc(size_t sz, int fl, const char *func, int line)
|
||||
__attribute__((alloc_size(1)));
|
||||
extern void spl_kmem_free(const void *ptr, size_t sz);
|
||||
|
||||
/*
|
||||
|
@ -85,7 +85,7 @@ typedef int kid_t; /* unique kstat id */
|
||||
typedef int kstat_update_t(struct kstat_s *, int); /* dynamic update cb */
|
||||
|
||||
typedef struct kstat_module {
|
||||
char ksm_name[KSTAT_STRLEN+1]; /* module name */
|
||||
char ksm_name[KSTAT_STRLEN]; /* module name */
|
||||
struct list_head ksm_module_list; /* module linkage */
|
||||
struct list_head ksm_kstat_list; /* list of kstat entries */
|
||||
struct proc_dir_entry *ksm_proc; /* proc entry */
|
||||
@ -98,8 +98,8 @@ typedef struct kstat_raw_ops {
|
||||
} kstat_raw_ops_t;
|
||||
|
||||
typedef struct kstat_proc_entry {
|
||||
char kpe_name[KSTAT_STRLEN+1]; /* kstat name */
|
||||
char kpe_module[KSTAT_STRLEN+1]; /* provider module name */
|
||||
char kpe_name[KSTAT_STRLEN]; /* kstat name */
|
||||
char kpe_module[KSTAT_STRLEN]; /* provider module name */
|
||||
kstat_module_t *kpe_owner; /* kstat module linkage */
|
||||
struct list_head kpe_list; /* kstat linkage */
|
||||
struct proc_dir_entry *kpe_proc; /* procfs entry */
|
||||
@ -111,7 +111,7 @@ struct kstat_s {
|
||||
hrtime_t ks_crtime; /* creation time */
|
||||
hrtime_t ks_snaptime; /* last access time */
|
||||
int ks_instance; /* provider module instance */
|
||||
char ks_class[KSTAT_STRLEN+1]; /* kstat class */
|
||||
char ks_class[KSTAT_STRLEN]; /* kstat class */
|
||||
uchar_t ks_type; /* kstat data type */
|
||||
uchar_t ks_flags; /* kstat flags */
|
||||
void *ks_data; /* kstat type-specific data */
|
||||
@ -177,7 +177,7 @@ typedef struct kstat_io {
|
||||
} kstat_io_t;
|
||||
|
||||
typedef struct kstat_timer {
|
||||
char name[KSTAT_STRLEN+1]; /* event name */
|
||||
char name[KSTAT_STRLEN]; /* event name */
|
||||
u_longlong_t num_events; /* number of events */
|
||||
hrtime_t elapsed_time; /* cumulative elapsed time */
|
||||
hrtime_t min_time; /* shortest event duration */
|
||||
|
29
sys/contrib/openzfs/include/os/linux/spl/sys/misc.h
Normal file
29
sys/contrib/openzfs/include/os/linux/spl/sys/misc.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 _OS_LINUX_SPL_MISC_H
|
||||
#define _OS_LINUX_SPL_MISC_H
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
extern void spl_signal_kobj_evt(struct block_device *bdev);
|
||||
|
||||
#endif
|
@ -84,7 +84,7 @@ typedef void arc_write_done_func_t(zio_t *zio, arc_buf_t *buf, void *priv);
|
||||
typedef void arc_prune_func_t(int64_t bytes, void *priv);
|
||||
|
||||
/* Shared module parameters */
|
||||
extern int zfs_arc_average_blocksize;
|
||||
extern uint_t zfs_arc_average_blocksize;
|
||||
extern int l2arc_exclude_special;
|
||||
|
||||
/* generic arc_done_func_t's which you can use */
|
||||
|
@ -976,15 +976,15 @@ extern arc_stats_t arc_stats;
|
||||
extern arc_sums_t arc_sums;
|
||||
extern hrtime_t arc_growtime;
|
||||
extern boolean_t arc_warm;
|
||||
extern int arc_grow_retry;
|
||||
extern int arc_no_grow_shift;
|
||||
extern int arc_shrink_shift;
|
||||
extern uint_t arc_grow_retry;
|
||||
extern uint_t arc_no_grow_shift;
|
||||
extern uint_t arc_shrink_shift;
|
||||
extern kmutex_t arc_prune_mtx;
|
||||
extern list_t arc_prune_list;
|
||||
extern arc_state_t ARC_mfu;
|
||||
extern arc_state_t ARC_mru;
|
||||
extern uint_t zfs_arc_pc_percent;
|
||||
extern int arc_lotsfree_percent;
|
||||
extern uint_t arc_lotsfree_percent;
|
||||
extern unsigned long zfs_arc_min;
|
||||
extern unsigned long zfs_arc_max;
|
||||
|
||||
@ -995,7 +995,7 @@ extern void arc_wait_for_eviction(uint64_t, boolean_t);
|
||||
|
||||
extern void arc_lowmem_init(void);
|
||||
extern void arc_lowmem_fini(void);
|
||||
extern void arc_prune_async(int64_t);
|
||||
extern void arc_prune_async(uint64_t);
|
||||
extern int arc_memory_throttle(spa_t *spa, uint64_t reserve, uint64_t txg);
|
||||
extern uint64_t arc_free_memory(void);
|
||||
extern int64_t arc_available_memory(void);
|
||||
|
@ -321,12 +321,14 @@ typedef struct dmu_buf_impl {
|
||||
uint8_t db_dirtycnt;
|
||||
} dmu_buf_impl_t;
|
||||
|
||||
#define DBUF_RWLOCKS 8192
|
||||
#define DBUF_HASH_RWLOCK(h, idx) (&(h)->hash_rwlocks[(idx) & (DBUF_RWLOCKS-1)])
|
||||
#define DBUF_HASH_MUTEX(h, idx) \
|
||||
(&(h)->hash_mutexes[(idx) & ((h)->hash_mutex_mask)])
|
||||
|
||||
typedef struct dbuf_hash_table {
|
||||
uint64_t hash_table_mask;
|
||||
uint64_t hash_mutex_mask;
|
||||
dmu_buf_impl_t **hash_table;
|
||||
krwlock_t hash_rwlocks[DBUF_RWLOCKS] ____cacheline_aligned;
|
||||
kmutex_t *hash_mutexes;
|
||||
} dbuf_hash_table_t;
|
||||
|
||||
typedef void (*dbuf_prefetch_fn)(void *, uint64_t, uint64_t, boolean_t);
|
||||
|
@ -865,7 +865,7 @@ int dmu_assign_arcbuf_by_dnode(dnode_t *dn, uint64_t offset,
|
||||
int dmu_assign_arcbuf_by_dbuf(dmu_buf_t *handle, uint64_t offset,
|
||||
struct arc_buf *buf, dmu_tx_t *tx);
|
||||
#define dmu_assign_arcbuf dmu_assign_arcbuf_by_dbuf
|
||||
extern int zfs_max_recordsize;
|
||||
extern uint_t zfs_max_recordsize;
|
||||
|
||||
/*
|
||||
* Asynchronously try to read in the data.
|
||||
@ -907,7 +907,7 @@ typedef const struct dmu_object_byteswap_info {
|
||||
} dmu_object_byteswap_info_t;
|
||||
|
||||
extern const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES];
|
||||
extern const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS];
|
||||
extern dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS];
|
||||
|
||||
/*
|
||||
* Get information on a DMU object.
|
||||
@ -1070,7 +1070,7 @@ int dmu_diff(const char *tosnap_name, const char *fromsnap_name,
|
||||
#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */
|
||||
extern uint64_t zfs_crc64_table[256];
|
||||
|
||||
extern int dmu_prefetch_max;
|
||||
extern uint_t dmu_prefetch_max;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ 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 int zfs_dirty_data_max_percent;
|
||||
extern int zfs_dirty_data_max_max_percent;
|
||||
extern int zfs_delay_min_dirty_percent;
|
||||
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;
|
||||
|
||||
/* These macros are for indexing into the zfs_all_blkstats_t. */
|
||||
|
@ -95,7 +95,7 @@ extern void fm_init(void);
|
||||
extern void fm_fini(void);
|
||||
extern void zfs_zevent_post_cb(nvlist_t *nvl, nvlist_t *detector);
|
||||
extern int zfs_zevent_post(nvlist_t *, nvlist_t *, zevent_cb_t *);
|
||||
extern void zfs_zevent_drain_all(int *);
|
||||
extern void zfs_zevent_drain_all(uint_t *);
|
||||
extern zfs_file_t *zfs_zevent_fd_hold(int, minor_t *, zfs_zevent_t **);
|
||||
extern void zfs_zevent_fd_rele(zfs_file_t *);
|
||||
extern int zfs_zevent_next(zfs_zevent_t *, nvlist_t **, uint64_t *, uint64_t *);
|
||||
|
@ -1536,6 +1536,7 @@ typedef enum {
|
||||
ZFS_ERR_BADPROP,
|
||||
ZFS_ERR_VDEV_NOTSUP,
|
||||
ZFS_ERR_NOT_USER_NAMESPACE,
|
||||
ZFS_ERR_RESUME_EXISTS,
|
||||
} zfs_errno_t;
|
||||
|
||||
/*
|
||||
|
@ -826,7 +826,7 @@ extern int spa_scrub_pause_resume(spa_t *spa, pool_scrub_cmd_t flag);
|
||||
extern void spa_sync(spa_t *spa, uint64_t txg); /* only for DMU use */
|
||||
extern void spa_sync_allpools(void);
|
||||
|
||||
extern int zfs_sync_pass_deferred_free;
|
||||
extern uint_t zfs_sync_pass_deferred_free;
|
||||
|
||||
/* spa namespace global mutex */
|
||||
extern kmutex_t spa_namespace_lock;
|
||||
@ -838,7 +838,7 @@ extern kmutex_t spa_namespace_lock;
|
||||
#define SPA_CONFIG_UPDATE_POOL 0
|
||||
#define SPA_CONFIG_UPDATE_VDEVS 1
|
||||
|
||||
extern void spa_write_cachefile(spa_t *, boolean_t, boolean_t);
|
||||
extern void spa_write_cachefile(spa_t *, boolean_t, boolean_t, boolean_t);
|
||||
extern void spa_config_load(void);
|
||||
extern nvlist_t *spa_all_configs(uint64_t *);
|
||||
extern void spa_config_set(spa_t *spa, nvlist_t *config);
|
||||
@ -1013,7 +1013,7 @@ extern boolean_t spa_indirect_vdevs_loaded(spa_t *spa);
|
||||
extern blkptr_t *spa_get_rootblkptr(spa_t *spa);
|
||||
extern void spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp);
|
||||
extern void spa_altroot(spa_t *, char *, size_t);
|
||||
extern int spa_sync_pass(spa_t *spa);
|
||||
extern uint32_t spa_sync_pass(spa_t *spa);
|
||||
extern char *spa_name(spa_t *spa);
|
||||
extern uint64_t spa_guid(spa_t *spa);
|
||||
extern uint64_t spa_load_guid(spa_t *spa);
|
||||
|
@ -215,7 +215,7 @@ struct spa {
|
||||
nvlist_t *spa_config_splitting; /* config for splitting */
|
||||
nvlist_t *spa_load_info; /* info and errors from load */
|
||||
uint64_t spa_config_txg; /* txg of last config change */
|
||||
int spa_sync_pass; /* iterate-to-convergence */
|
||||
uint32_t spa_sync_pass; /* iterate-to-convergence */
|
||||
pool_state_t spa_state; /* pool state */
|
||||
int spa_inject_ref; /* injection references */
|
||||
uint8_t spa_sync_on; /* sync threads are running */
|
||||
@ -446,7 +446,7 @@ struct spa {
|
||||
|
||||
extern char *spa_config_path;
|
||||
extern const char *zfs_deadman_failmode;
|
||||
extern int spa_slop_shift;
|
||||
extern uint_t spa_slop_shift;
|
||||
extern void spa_taskq_dispatch_ent(spa_t *spa, zio_type_t t, zio_taskq_type_t q,
|
||||
task_func_t *func, void *arg, uint_t flags, taskq_ent_t *ent);
|
||||
extern void spa_taskq_dispatch_sync(spa_t *, zio_type_t t, zio_taskq_type_t q,
|
||||
|
@ -138,7 +138,7 @@ extern void *txg_list_head(txg_list_t *tl, uint64_t txg);
|
||||
extern void *txg_list_next(txg_list_t *tl, void *p, uint64_t txg);
|
||||
|
||||
/* Global tuning */
|
||||
extern int zfs_txg_timeout;
|
||||
extern uint_t zfs_txg_timeout;
|
||||
|
||||
|
||||
#ifdef ZFS_DEBUG
|
||||
|
@ -148,6 +148,7 @@ extern int vdev_degrade(spa_t *spa, uint64_t guid, vdev_aux_t aux);
|
||||
extern int vdev_online(spa_t *spa, uint64_t guid, uint64_t flags,
|
||||
vdev_state_t *);
|
||||
extern int vdev_offline(spa_t *spa, uint64_t guid, uint64_t flags);
|
||||
extern int vdev_remove_wanted(spa_t *spa, uint64_t guid);
|
||||
extern void vdev_clear(spa_t *spa, vdev_t *vd);
|
||||
|
||||
extern boolean_t vdev_is_dead(vdev_t *vd);
|
||||
@ -190,6 +191,8 @@ typedef enum vdev_config_flag {
|
||||
VDEV_CONFIG_MISSING = 1 << 4
|
||||
} vdev_config_flag_t;
|
||||
|
||||
extern void vdev_post_kobj_evt(vdev_t *vd);
|
||||
extern void vdev_clear_kobj_evt(vdev_t *vd);
|
||||
extern void vdev_top_config_generate(spa_t *spa, nvlist_t *config);
|
||||
extern nvlist_t *vdev_config_generate(spa_t *spa, vdev_t *vd,
|
||||
boolean_t getstats, vdev_config_flag_t flags);
|
||||
|
@ -61,14 +61,15 @@ typedef struct vdev_cache vdev_cache_t;
|
||||
typedef struct vdev_cache_entry vdev_cache_entry_t;
|
||||
struct abd;
|
||||
|
||||
extern int zfs_vdev_queue_depth_pct;
|
||||
extern int zfs_vdev_def_queue_depth;
|
||||
extern uint32_t zfs_vdev_async_write_max_active;
|
||||
extern uint_t zfs_vdev_queue_depth_pct;
|
||||
extern uint_t zfs_vdev_def_queue_depth;
|
||||
extern uint_t zfs_vdev_async_write_max_active;
|
||||
|
||||
/*
|
||||
* Virtual device operations
|
||||
*/
|
||||
typedef int vdev_init_func_t(spa_t *spa, nvlist_t *nv, void **tsd);
|
||||
typedef void vdev_kobj_post_evt_func_t(vdev_t *vd);
|
||||
typedef void vdev_fini_func_t(vdev_t *vd);
|
||||
typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
|
||||
uint64_t *ashift, uint64_t *pshift);
|
||||
@ -123,6 +124,7 @@ typedef const struct vdev_ops {
|
||||
vdev_config_generate_func_t *vdev_op_config_generate;
|
||||
vdev_nparity_func_t *vdev_op_nparity;
|
||||
vdev_ndisks_func_t *vdev_op_ndisks;
|
||||
vdev_kobj_post_evt_func_t *vdev_op_kobj_evt_post;
|
||||
char vdev_op_type[16];
|
||||
boolean_t vdev_op_leaf;
|
||||
} vdev_ops_t;
|
||||
@ -436,6 +438,7 @@ struct vdev {
|
||||
boolean_t vdev_isl2cache; /* was a l2cache device */
|
||||
boolean_t vdev_copy_uberblocks; /* post expand copy uberblocks */
|
||||
boolean_t vdev_resilver_deferred; /* resilver deferred */
|
||||
boolean_t vdev_kobj_flag; /* kobj event record */
|
||||
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
|
||||
vdev_cache_t vdev_cache; /* physical block cache */
|
||||
spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
|
||||
|
@ -87,7 +87,7 @@ extern int spa_vdev_remove_cancel(spa_t *);
|
||||
extern void spa_vdev_removal_destroy(spa_vdev_removal_t *);
|
||||
extern uint64_t spa_remove_max_segment(spa_t *);
|
||||
|
||||
extern int vdev_removal_max_span;
|
||||
extern uint_t vdev_removal_max_span;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ extern "C" {
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/kmem_cache.h>
|
||||
#include <sys/vmem.h>
|
||||
#include <sys/misc.h>
|
||||
#include <sys/taskq.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/disp.h>
|
||||
@ -150,10 +151,14 @@ extern "C" {
|
||||
|
||||
extern void dprintf_setup(int *argc, char **argv);
|
||||
|
||||
extern void cmn_err(int, const char *, ...);
|
||||
extern void vcmn_err(int, const char *, va_list);
|
||||
extern __attribute__((noreturn)) void panic(const char *, ...);
|
||||
extern __attribute__((noreturn)) void vpanic(const char *, va_list);
|
||||
extern void cmn_err(int, const char *, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
extern void vcmn_err(int, const char *, va_list)
|
||||
__attribute__((format(printf, 2, 0)));
|
||||
extern void panic(const char *, ...)
|
||||
__attribute__((format(printf, 1, 2), noreturn));
|
||||
extern void vpanic(const char *, va_list)
|
||||
__attribute__((format(printf, 1, 0), noreturn));
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
|
@ -124,7 +124,13 @@ typedef enum drr_headertype {
|
||||
* default use of "zfs send" won't encounter the bug mentioned above.
|
||||
*/
|
||||
#define DMU_BACKUP_FEATURE_SWITCH_TO_LARGE_BLOCKS (1 << 27)
|
||||
#define DMU_BACKUP_FEATURE_BLAKE3 (1 << 28)
|
||||
/* flag #28 is reserved for a Nutanix feature */
|
||||
/*
|
||||
* flag #29 is the last unused bit. It is reserved to indicate a to-be-designed
|
||||
* extension to the stream format which will accomodate more feature flags.
|
||||
* If you need to add another feature flag, please reach out to the OpenZFS
|
||||
* community, e.g., on GitHub or Slack.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mask of all supported backup features
|
||||
@ -135,7 +141,7 @@ typedef enum drr_headertype {
|
||||
DMU_BACKUP_FEATURE_COMPRESSED | DMU_BACKUP_FEATURE_LARGE_DNODE | \
|
||||
DMU_BACKUP_FEATURE_RAW | DMU_BACKUP_FEATURE_HOLDS | \
|
||||
DMU_BACKUP_FEATURE_REDACTED | DMU_BACKUP_FEATURE_SWITCH_TO_LARGE_BLOCKS | \
|
||||
DMU_BACKUP_FEATURE_ZSTD | DMU_BACKUP_FEATURE_BLAKE3)
|
||||
DMU_BACKUP_FEATURE_ZSTD)
|
||||
|
||||
/* Are all features in the given flag word currently supported? */
|
||||
#define DMU_STREAM_SUPPORTED(x) (!((x) & ~DMU_BACKUP_FEATURE_MASK))
|
||||
|
@ -102,7 +102,7 @@ typedef struct zio_bad_cksum {
|
||||
uint8_t zbc_has_cksum; /* expected/actual valid */
|
||||
} zio_bad_cksum_t;
|
||||
|
||||
_SYS_ZIO_CHECKSUM_H const zio_checksum_info_t
|
||||
_SYS_ZIO_CHECKSUM_H zio_checksum_info_t
|
||||
zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS];
|
||||
|
||||
/*
|
||||
|
@ -152,7 +152,7 @@ typedef const struct zio_compress_info {
|
||||
zio_decompresslevel_func_t *ci_decompress_level;
|
||||
} zio_compress_info_t;
|
||||
|
||||
extern const zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS];
|
||||
extern zio_compress_info_t zio_compress_table[ZIO_COMPRESS_FUNCTIONS];
|
||||
|
||||
/*
|
||||
* lz4 compression init & free
|
||||
|
@ -95,8 +95,8 @@ nfs_init_tmpfile(const char *prefix, const char *mdir, struct tmpfile *tmpf)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
strcpy(tmpf->name, prefix);
|
||||
strcat(tmpf->name, ".XXXXXXXX");
|
||||
strlcpy(tmpf->name, prefix, sizeof (tmpf->name));
|
||||
strlcat(tmpf->name, ".XXXXXXXX", sizeof (tmpf->name) - strlen(prefix));
|
||||
|
||||
int fd = mkostemp(tmpf->name, O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
|
@ -45,8 +45,11 @@ libspl_assertf(const char *file, const char *func, int line,
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
|
||||
va_end(args);
|
||||
|
||||
#if !__has_feature(attribute_analyzer_noreturn) && !defined(__COVERITY__)
|
||||
if (libspl_assert_ok) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
|
@ -34,12 +34,24 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Workaround for non-Clang compilers */
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
/* We need to workaround libspl_set_assert_ok() that we have for zdb */
|
||||
#if __has_feature(attribute_analyzer_noreturn) || defined(__COVERITY__)
|
||||
#define NORETURN __attribute__((__noreturn__))
|
||||
#else
|
||||
#define NORETURN
|
||||
#endif
|
||||
|
||||
/* Set to non-zero to avoid abort()ing on an assertion failure */
|
||||
extern void libspl_set_assert_ok(boolean_t val);
|
||||
|
||||
/* printf version of libspl_assert */
|
||||
extern void libspl_assertf(const char *file, const char *func, int line,
|
||||
const char *format, ...);
|
||||
const char *format, ...) NORETURN __attribute__((format(printf, 4, 5)));
|
||||
|
||||
static inline int
|
||||
libspl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
|
@ -59,6 +59,18 @@ extern "C" {
|
||||
*/
|
||||
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
|
||||
|
||||
#ifdef __COVERITY__
|
||||
/*
|
||||
* Coverity's taint warnings from byteswapping are false positives for us.
|
||||
* Suppress them by hiding byteswapping from Coverity.
|
||||
*/
|
||||
#define BSWAP_8(x) ((x) & 0xff)
|
||||
#define BSWAP_16(x) ((x) & 0xffff)
|
||||
#define BSWAP_32(x) ((x) & 0xffffffff)
|
||||
#define BSWAP_64(x) (x)
|
||||
|
||||
#else /* __COVERITY__ */
|
||||
|
||||
/*
|
||||
* Macros to reverse byte order
|
||||
*/
|
||||
@ -67,6 +79,8 @@ extern "C" {
|
||||
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
|
||||
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
|
||||
|
||||
#endif /* __COVERITY__ */
|
||||
|
||||
#define BMASK_8(x) ((x) & 0xff)
|
||||
#define BMASK_16(x) ((x) & 0xffff)
|
||||
#define BMASK_32(x) ((x) & 0xffffffff)
|
||||
|
@ -90,6 +90,18 @@ extern in_port_t ntohs(in_port_t);
|
||||
|
||||
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
|
||||
|
||||
#ifdef __COVERITY__
|
||||
/*
|
||||
* Coverity's taint warnings from byteswapping are false positives for us.
|
||||
* Suppress them by hiding byteswapping from Coverity.
|
||||
*/
|
||||
#define BSWAP_8(x) ((x) & 0xff)
|
||||
#define BSWAP_16(x) ((x) & 0xffff)
|
||||
#define BSWAP_32(x) ((x) & 0xffffffff)
|
||||
#define BSWAP_64(x) (x)
|
||||
|
||||
#else /* __COVERITY__ */
|
||||
|
||||
/*
|
||||
* Macros to reverse byte order
|
||||
*/
|
||||
@ -98,6 +110,8 @@ extern in_port_t ntohs(in_port_t);
|
||||
#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
|
||||
#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
|
||||
|
||||
#endif /* __COVERITY__ */
|
||||
|
||||
#define BMASK_8(x) ((x) & 0xff)
|
||||
#define BMASK_16(x) ((x) & 0xffff)
|
||||
#define BMASK_32(x) ((x) & 0xffffffff)
|
||||
|
@ -83,6 +83,7 @@ const char *_umem_debug_init(void);
|
||||
const char *_umem_options_init(void);
|
||||
const char *_umem_logging_init(void);
|
||||
|
||||
__attribute__((alloc_size(1)))
|
||||
static inline void *
|
||||
umem_alloc(size_t size, int flags)
|
||||
{
|
||||
@ -95,6 +96,7 @@ umem_alloc(size_t size, int flags)
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
__attribute__((alloc_size(1)))
|
||||
static inline void *
|
||||
umem_alloc_aligned(size_t size, size_t align, int flags)
|
||||
{
|
||||
@ -116,6 +118,7 @@ umem_alloc_aligned(size_t size, size_t align, int flags)
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
__attribute__((alloc_size(1)))
|
||||
static inline void *
|
||||
umem_zalloc(size_t size, int flags)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ hasmntopt(struct mnttab *mnt, const char *opt)
|
||||
|
||||
if (mnt->mnt_mntopts == NULL)
|
||||
return (NULL);
|
||||
(void) strcpy(opts, mnt->mnt_mntopts);
|
||||
(void) strlcpy(opts, mnt->mnt_mntopts, MNT_LINE_MAX);
|
||||
f = mntopt(&opts);
|
||||
for (; *f; f = mntopt(&opts)) {
|
||||
if (strncmp(opt, f, strlen(opt)) == 0)
|
||||
|
@ -550,6 +550,7 @@
|
||||
<elf-symbol name='zpool_vdev_path_to_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_vdev_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_vdev_remove_cancel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_vdev_remove_wanted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_vdev_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
<elf-symbol name='zpool_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
|
||||
@ -3505,6 +3506,11 @@
|
||||
<parameter type-id='c19b74c3' name='istmp'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_vdev_remove_wanted' mangled-name='zpool_vdev_remove_wanted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_remove_wanted'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='80f4b756' name='path'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='zpool_vdev_fault' mangled-name='zpool_vdev_fault' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_fault'>
|
||||
<parameter type-id='4c81de99' name='zhp'/>
|
||||
<parameter type-id='9c313c2d' name='guid'/>
|
||||
|
@ -717,8 +717,8 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
|
||||
* to get the parent dataset name only.
|
||||
*/
|
||||
assert(bookp - path < sizeof (dsname));
|
||||
(void) strncpy(dsname, path, bookp - path);
|
||||
dsname[bookp - path] = '\0';
|
||||
(void) strlcpy(dsname, path,
|
||||
MIN(sizeof (dsname), bookp - path + 1));
|
||||
|
||||
/*
|
||||
* Create handle for the parent dataset.
|
||||
@ -2007,6 +2007,7 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
|
||||
goto error;
|
||||
|
||||
if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
|
||||
changelist_free(cl);
|
||||
return (zfs_standard_error(hdl, errno, errbuf));
|
||||
} else {
|
||||
|
||||
@ -3453,8 +3454,8 @@ check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
|
||||
/* check to see if the pool exists */
|
||||
if ((slash = strchr(parent, '/')) == NULL)
|
||||
slash = parent + strlen(parent);
|
||||
(void) strncpy(zc.zc_name, parent, slash - parent);
|
||||
zc.zc_name[slash - parent] = '\0';
|
||||
(void) strlcpy(zc.zc_name, parent,
|
||||
MIN(sizeof (zc.zc_name), slash - parent + 1));
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
|
||||
errno == ENOENT) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
@ -4163,6 +4164,8 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
|
||||
* same pool, as does lzc_snapshot (below).
|
||||
*/
|
||||
elem = nvlist_next_nvpair(snaps, NULL);
|
||||
if (elem == NULL)
|
||||
return (-1);
|
||||
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
|
||||
pool[strcspn(pool, "/@")] = '\0';
|
||||
zpool_hdl = zpool_open(hdl, pool);
|
||||
|
@ -572,8 +572,7 @@ get_snapshot_names(differ_info_t *di, const char *fromsnap,
|
||||
zfs_handle_t *zhp;
|
||||
|
||||
di->ds = zfs_alloc(di->zhp->zfs_hdl, tdslen + 1);
|
||||
(void) strncpy(di->ds, tosnap, tdslen);
|
||||
di->ds[tdslen] = '\0';
|
||||
(void) strlcpy(di->ds, tosnap, tdslen + 1);
|
||||
|
||||
zhp = zfs_open(hdl, di->ds, ZFS_TYPE_FILESYSTEM);
|
||||
while (zhp != NULL) {
|
||||
@ -609,8 +608,7 @@ get_snapshot_names(differ_info_t *di, const char *fromsnap,
|
||||
int dslen = fdslen ? fdslen : tdslen;
|
||||
|
||||
di->ds = zfs_alloc(hdl, dslen + 1);
|
||||
(void) strncpy(di->ds, fdslen ? fromsnap : tosnap, dslen);
|
||||
di->ds[dslen] = '\0';
|
||||
(void) strlcpy(di->ds, fdslen ? fromsnap : tosnap, dslen + 1);
|
||||
|
||||
di->fromsnap = zfs_asprintf(hdl, "%s%s", di->ds, atptrf);
|
||||
if (tsnlen) {
|
||||
|
@ -3073,6 +3073,43 @@ zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the specified vdev asynchronously from the configuration, so
|
||||
* that it may come ONLINE if reinserted. This is called from zed on
|
||||
* Udev remove event.
|
||||
* Note: We also have a similar function zpool_vdev_remove() that
|
||||
* removes the vdev from the pool.
|
||||
*/
|
||||
int
|
||||
zpool_vdev_remove_wanted(zpool_handle_t *zhp, const char *path)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char errbuf[ERRBUFLEN];
|
||||
nvlist_t *tgt;
|
||||
boolean_t avail_spare, l2cache;
|
||||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
||||
if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
|
||||
NULL)) == NULL)
|
||||
return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
|
||||
|
||||
zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
|
||||
|
||||
if (avail_spare)
|
||||
return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
|
||||
|
||||
zc.zc_cookie = VDEV_STATE_REMOVED;
|
||||
|
||||
if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
|
||||
return (0);
|
||||
|
||||
return (zpool_standard_error(hdl, errno, errbuf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the given vdev faulted.
|
||||
*/
|
||||
|
@ -1175,7 +1175,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
(void) strcpy(sdd->prevsnap, thissnap);
|
||||
(void) strlcpy(sdd->prevsnap, thissnap, sizeof (sdd->prevsnap));
|
||||
sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
|
||||
zfs_close(zhp);
|
||||
return (err);
|
||||
@ -1736,7 +1736,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
|
||||
(void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid);
|
||||
|
||||
if (flags->saved) {
|
||||
(void) strcpy(name, toname);
|
||||
(void) strlcpy(name, toname, sizeof (name));
|
||||
} else {
|
||||
error = guid_to_name(hdl, toname, toguid, B_FALSE, name);
|
||||
if (error != 0) {
|
||||
@ -2880,7 +2880,7 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
|
||||
goto out;
|
||||
|
||||
if (tryname) {
|
||||
(void) strcpy(newname, tryname);
|
||||
(void) strlcpy(newname, tryname, ZFS_MAX_DATASET_NAME_LEN);
|
||||
if (flags->verbose) {
|
||||
(void) printf("attempting rename %s to %s\n",
|
||||
name, newname);
|
||||
@ -4331,7 +4331,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
err = nvlist_lookup_string(rcvprops,
|
||||
zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
|
||||
if (err == 0) {
|
||||
strcpy(tmp_keylocation, keylocation);
|
||||
strlcpy(tmp_keylocation, keylocation, MAXNAMELEN);
|
||||
(void) nvlist_remove_all(rcvprops,
|
||||
zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
|
||||
}
|
||||
@ -4498,18 +4498,20 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||
"cannot receive new filesystem stream"));
|
||||
|
||||
(void) strcpy(name, destsnap);
|
||||
(void) strlcpy(name, destsnap, sizeof (name));
|
||||
cp = strrchr(name, '/');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
if (cp &&
|
||||
!zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
|
||||
char suffix[ZFS_MAX_DATASET_NAME_LEN];
|
||||
(void) strcpy(suffix, strrchr(destsnap, '/'));
|
||||
(void) strlcpy(suffix, strrchr(destsnap, '/'),
|
||||
sizeof (suffix));
|
||||
if (guid_to_name(hdl, name, parent_snapguid,
|
||||
B_FALSE, destsnap) == 0) {
|
||||
*strchr(destsnap, '@') = '\0';
|
||||
(void) strcat(destsnap, suffix);
|
||||
(void) strlcat(destsnap, suffix,
|
||||
sizeof (destsnap) - strlen(destsnap));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -4527,7 +4529,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
"cannot receive incremental stream"));
|
||||
}
|
||||
|
||||
(void) strcpy(name, destsnap);
|
||||
(void) strlcpy(name, destsnap, sizeof (name));
|
||||
*strchr(name, '@') = '\0';
|
||||
|
||||
/*
|
||||
@ -4539,16 +4541,18 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
|
||||
!zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
|
||||
char snap[ZFS_MAX_DATASET_NAME_LEN];
|
||||
(void) strcpy(snap, strchr(destsnap, '@'));
|
||||
(void) strlcpy(snap, strchr(destsnap, '@'),
|
||||
sizeof (snap));
|
||||
if (guid_to_name(hdl, name, drrb->drr_fromguid,
|
||||
B_FALSE, destsnap) == 0) {
|
||||
*strchr(destsnap, '@') = '\0';
|
||||
(void) strcat(destsnap, snap);
|
||||
(void) strlcat(destsnap, snap,
|
||||
sizeof (destsnap) - strlen(destsnap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void) strcpy(name, destsnap);
|
||||
(void) strlcpy(name, destsnap, sizeof (name));
|
||||
*strchr(name, '@') = '\0';
|
||||
|
||||
redacted = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
|
||||
@ -4638,6 +4642,33 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* When receiving full/newfs on existing dataset, then it
|
||||
* should be done with "-F" flag. Its enforced for initial
|
||||
* receive in previous checks in this function.
|
||||
* Similarly, on resuming full/newfs recv on existing dataset,
|
||||
* it should be done with "-F" flag.
|
||||
*
|
||||
* When dataset doesn't exist, then full/newfs recv is done on
|
||||
* newly created dataset and it's marked INCONSISTENT. But
|
||||
* When receiving on existing dataset, recv is first done on
|
||||
* %recv and its marked INCONSISTENT. Existing dataset is not
|
||||
* marked INCONSISTENT.
|
||||
* Resume of full/newfs receive with dataset not INCONSISTENT
|
||||
* indicates that its resuming newfs on existing dataset. So,
|
||||
* enforce "-F" flag in this case.
|
||||
*/
|
||||
if (stream_resumingnewfs &&
|
||||
!zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
|
||||
!flags->force) {
|
||||
zfs_close(zhp);
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"Resuming recv on existing destination '%s'\n"
|
||||
"must specify -F to overwrite it"), name);
|
||||
err = zfs_error(hdl, EZFS_RESUME_EXISTS, errbuf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (stream_wantsnewfs &&
|
||||
zhp->zfs_dmustats.dds_origin[0]) {
|
||||
zfs_close(zhp);
|
||||
@ -4903,7 +4934,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
if (err == 0 && snapprops_nvlist) {
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
|
||||
(void) strcpy(zc.zc_name, destsnap);
|
||||
(void) strlcpy(zc.zc_name, destsnap, sizeof (zc.zc_name));
|
||||
zc.zc_cookie = B_TRUE; /* received */
|
||||
zcmd_write_src_nvlist(hdl, &zc, snapprops_nvlist);
|
||||
(void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
|
||||
@ -5078,6 +5109,19 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||
"be updated."));
|
||||
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
|
||||
break;
|
||||
case ZFS_ERR_RESUME_EXISTS:
|
||||
cp = strchr(destsnap, '@');
|
||||
if (newfs) {
|
||||
/* it's the containing fs that exists */
|
||||
*cp = '\0';
|
||||
}
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"Resuming recv on existing dataset without force"));
|
||||
(void) zfs_error_fmt(hdl, EZFS_RESUME_EXISTS,
|
||||
dgettext(TEXT_DOMAIN, "cannot resume recv %s"),
|
||||
destsnap);
|
||||
*cp = '@';
|
||||
break;
|
||||
case EBUSY:
|
||||
if (hastoken) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
|
@ -304,6 +304,9 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
||||
case EZFS_NOT_USER_NAMESPACE:
|
||||
return (dgettext(TEXT_DOMAIN, "the provided file "
|
||||
"was not a user namespace file"));
|
||||
case EZFS_RESUME_EXISTS:
|
||||
return (dgettext(TEXT_DOMAIN, "Resuming recv on existing "
|
||||
"dataset without force"));
|
||||
case EZFS_UNKNOWN:
|
||||
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
||||
default:
|
||||
|
@ -145,8 +145,8 @@ libzfs_load_module(void)
|
||||
if (pfds[0].revents & POLLIN) {
|
||||
verify(read(ino, ev, evsz) >
|
||||
sizeof (struct inotify_event));
|
||||
if (strcmp(ev->name, &ZFS_DEV[sizeof (ZFS_DEVDIR)])
|
||||
== 0) {
|
||||
if (strncmp(ev->name, &ZFS_DEV[sizeof (ZFS_DEVDIR)],
|
||||
ev->len) == 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device)
|
||||
/* version is mandatory */
|
||||
fnvlist_add_uint64(nv, BOOTENV_VERSION, VB_NVLIST);
|
||||
|
||||
rv = 0;
|
||||
/*
|
||||
* If device name is empty, remove boot device configuration.
|
||||
*/
|
||||
@ -95,8 +96,8 @@ lzbe_set_boot_device(const char *pool, lzbe_flags_t flag, const char *device)
|
||||
rv = ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
rv = zpool_set_bootenv(zphdl, nv);
|
||||
if (rv == 0)
|
||||
rv = zpool_set_bootenv(zphdl, nv);
|
||||
if (rv != 0)
|
||||
fprintf(stderr, "%s\n", libzfs_error_description(hdl));
|
||||
|
||||
|
@ -276,7 +276,7 @@ taskq_create(const char *name, int nthreads, pri_t pri,
|
||||
cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
|
||||
cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL);
|
||||
(void) strncpy(tq->tq_name, name, TASKQ_NAMELEN);
|
||||
(void) strlcpy(tq->tq_name, name, sizeof (tq->tq_name));
|
||||
tq->tq_flags = flags | TASKQ_ACTIVE;
|
||||
tq->tq_active = nthreads;
|
||||
tq->tq_nthreads = nthreads;
|
||||
@ -319,7 +319,9 @@ taskq_destroy(taskq_t *tq)
|
||||
tq->tq_minalloc = 0;
|
||||
while (tq->tq_nalloc != 0) {
|
||||
ASSERT(tq->tq_freelist != NULL);
|
||||
task_free(tq, task_alloc(tq, KM_SLEEP));
|
||||
taskq_ent_t *tqent_nexttq = tq->tq_freelist->tqent_next;
|
||||
task_free(tq, tq->tq_freelist);
|
||||
tq->tq_freelist = tqent_nexttq;
|
||||
}
|
||||
|
||||
mutex_exit(&tq->tq_lock);
|
||||
|
@ -174,12 +174,13 @@ set_global_var_parse_kv(const char *arg, char **k_out, u_longlong_t *v_out)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
*k_out = k;
|
||||
*k_out = strdup(k);
|
||||
*v_out = val;
|
||||
free(d);
|
||||
return (0);
|
||||
|
||||
err_free:
|
||||
free(k);
|
||||
free(d);
|
||||
|
||||
return (err);
|
||||
}
|
||||
@ -349,7 +350,7 @@ pool_active(void *unused, const char *name, uint64_t guid,
|
||||
}
|
||||
#endif
|
||||
|
||||
const pool_config_ops_t libzpool_config_ops = {
|
||||
pool_config_ops_t libzpool_config_ops = {
|
||||
.pco_refresh_config = refresh_config,
|
||||
.pco_pool_active = pool_active,
|
||||
};
|
||||
|
@ -344,6 +344,8 @@ zfs_get_enclosure_sysfs_path(const char *dev_name)
|
||||
if (strstr(ep->d_name, "enclosure_device") == NULL)
|
||||
continue;
|
||||
|
||||
if (tmp2 != NULL)
|
||||
free(tmp2);
|
||||
if (asprintf(&tmp2, "%s/%s", tmp1, ep->d_name) == -1) {
|
||||
tmp2 = NULL;
|
||||
break;
|
||||
@ -372,14 +374,13 @@ zfs_get_enclosure_sysfs_path(const char *dev_name)
|
||||
if (tmp3 == NULL)
|
||||
break;
|
||||
|
||||
if (path != NULL)
|
||||
free(path);
|
||||
if (asprintf(&path, "/sys/class/%s", tmp3) == -1) {
|
||||
/* If asprintf() fails, 'path' is undefined */
|
||||
path = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (path == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -1777,8 +1777,7 @@ zpool_find_import(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
|
||||
|
||||
nvlist_t *
|
||||
zpool_search_import(void *hdl, importargs_t *import,
|
||||
const pool_config_ops_t *pco)
|
||||
zpool_search_import(void *hdl, importargs_t *import, pool_config_ops_t *pco)
|
||||
{
|
||||
libpc_handle_t handle = { 0 };
|
||||
nvlist_t *pools = NULL;
|
||||
@ -1821,7 +1820,7 @@ pool_match(nvlist_t *cfg, char *tgt)
|
||||
|
||||
int
|
||||
zpool_find_config(void *hdl, const char *target, nvlist_t **configp,
|
||||
importargs_t *args, const pool_config_ops_t *pco)
|
||||
importargs_t *args, pool_config_ops_t *pco)
|
||||
{
|
||||
nvlist_t *pools;
|
||||
nvlist_t *match = NULL;
|
||||
|
@ -43,7 +43,7 @@ typedef struct libpc_handle {
|
||||
boolean_t lpc_open_access_error;
|
||||
boolean_t lpc_desc_active;
|
||||
char lpc_desc[1024];
|
||||
const pool_config_ops_t *lpc_ops;
|
||||
pool_config_ops_t *lpc_ops;
|
||||
void *lpc_lib_handle;
|
||||
} libpc_handle_t;
|
||||
|
||||
|
@ -56,21 +56,27 @@ The percentage below
|
||||
.Sy dbuf_cache_max_bytes
|
||||
when the evict thread stops evicting dbufs.
|
||||
.
|
||||
.It Sy dbuf_cache_shift Ns = Ns Sy 5 Pq int
|
||||
.It Sy dbuf_cache_shift Ns = Ns Sy 5 Pq uint
|
||||
Set the size of the dbuf cache
|
||||
.Pq Sy dbuf_cache_max_bytes
|
||||
to a log2 fraction of the target ARC size.
|
||||
.
|
||||
.It Sy dbuf_metadata_cache_shift Ns = Ns Sy 6 Pq int
|
||||
.It Sy dbuf_metadata_cache_shift Ns = Ns Sy 6 Pq uint
|
||||
Set the size of the dbuf metadata cache
|
||||
.Pq Sy dbuf_metadata_cache_max_bytes
|
||||
to a log2 fraction of the target ARC size.
|
||||
.
|
||||
.It Sy dmu_object_alloc_chunk_shift Ns = Ns Sy 7 Po 128 Pc Pq int
|
||||
.It Sy dbuf_mutex_cache_shift Ns = Ns Sy 0 Pq uint
|
||||
Set the size of the mutex array for the dbuf cache.
|
||||
When set to
|
||||
.Sy 0
|
||||
the array is dynamically sized based on total system memory.
|
||||
.
|
||||
.It Sy dmu_object_alloc_chunk_shift Ns = Ns Sy 7 Po 128 Pc Pq uint
|
||||
dnode slots allocated in a single operation as a power of 2.
|
||||
The default value minimizes lock contention for the bulk operation performed.
|
||||
.
|
||||
.It Sy dmu_prefetch_max Ns = Ns Sy 134217728 Ns B Po 128 MiB Pc Pq int
|
||||
.It Sy dmu_prefetch_max Ns = Ns Sy 134217728 Ns B Po 128 MiB Pc Pq uint
|
||||
Limit the amount we can prefetch with one call to this amount in bytes.
|
||||
This helps to limit the amount of memory that can be used by prefetching.
|
||||
.
|
||||
@ -149,7 +155,7 @@ provided by the
|
||||
arcstats can be used to decide if toggling this option is appropriate
|
||||
for the current workload.
|
||||
.
|
||||
.It Sy l2arc_meta_percent Ns = Ns Sy 33 Ns % Pq int
|
||||
.It Sy l2arc_meta_percent Ns = Ns Sy 33 Ns % Pq uint
|
||||
Percent of ARC size allowed for L2ARC-only headers.
|
||||
Since L2ARC buffers are not evicted on memory pressure,
|
||||
too many headers on a system with an irrationally large L2ARC
|
||||
@ -261,7 +267,7 @@ Prevent metaslabs from being unloaded.
|
||||
.It Sy metaslab_fragmentation_factor_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
Enable use of the fragmentation metric in computing metaslab weights.
|
||||
.
|
||||
.It Sy metaslab_df_max_search Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq int
|
||||
.It Sy metaslab_df_max_search Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq uint
|
||||
Maximum distance to search forward from the last offset.
|
||||
Without this limit, fragmented pools can see
|
||||
.Em >100`000
|
||||
@ -303,7 +309,7 @@ After a number of seconds controlled by this tunable,
|
||||
we stop considering the cached max size and start
|
||||
considering only the histogram instead.
|
||||
.
|
||||
.It Sy zfs_metaslab_mem_limit Ns = Ns Sy 25 Ns % Pq int
|
||||
.It Sy zfs_metaslab_mem_limit Ns = Ns Sy 25 Ns % Pq uint
|
||||
When we are loading a new metaslab, we check the amount of memory being used
|
||||
to store metaslab range trees.
|
||||
If it is over a threshold, we attempt to unload the least recently used metaslab
|
||||
@ -335,16 +341,16 @@ If that fails we will do a "try hard" gang allocation.
|
||||
If that fails then we will have a multi-layer gang block.
|
||||
.El
|
||||
.
|
||||
.It Sy zfs_metaslab_find_max_tries Ns = Ns Sy 100 Pq int
|
||||
.It Sy zfs_metaslab_find_max_tries Ns = Ns Sy 100 Pq uint
|
||||
When not trying hard, we only consider this number of the best metaslabs.
|
||||
This improves performance, especially when there are many metaslabs per vdev
|
||||
and the allocation can't actually be satisfied
|
||||
(so we would otherwise iterate all metaslabs).
|
||||
.
|
||||
.It Sy zfs_vdev_default_ms_count Ns = Ns Sy 200 Pq int
|
||||
.It Sy zfs_vdev_default_ms_count Ns = Ns Sy 200 Pq uint
|
||||
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 int
|
||||
.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
|
||||
@ -357,7 +363,7 @@ 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
|
||||
Minimum ashift used when creating new top-level vdevs.
|
||||
.
|
||||
.It Sy zfs_vdev_min_ms_count Ns = Ns Sy 16 Pq int
|
||||
.It Sy zfs_vdev_min_ms_count Ns = Ns Sy 16 Pq uint
|
||||
Minimum number of metaslabs to create in a top-level vdev.
|
||||
.
|
||||
.It Sy vdev_validate_skip Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
@ -365,7 +371,7 @@ Skip label validation steps during pool import.
|
||||
Changing is not recommended unless you know what you're doing
|
||||
and are recovering a damaged label.
|
||||
.
|
||||
.It Sy zfs_vdev_ms_count_limit Ns = Ns Sy 131072 Po 128k Pc Pq int
|
||||
.It Sy zfs_vdev_ms_count_limit Ns = Ns Sy 131072 Po 128k Pc Pq uint
|
||||
Practical upper limit of total metaslabs per top-level vdev.
|
||||
.
|
||||
.It Sy metaslab_preload_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
@ -376,21 +382,21 @@ Give more weight to metaslabs with lower LBAs,
|
||||
assuming they have greater bandwidth,
|
||||
as is typically the case on a modern constant angular velocity disk drive.
|
||||
.
|
||||
.It Sy metaslab_unload_delay Ns = Ns Sy 32 Pq int
|
||||
.It Sy metaslab_unload_delay Ns = Ns Sy 32 Pq uint
|
||||
After a metaslab is used, we keep it loaded for this many TXGs, to attempt to
|
||||
reduce unnecessary reloading.
|
||||
Note that both this many TXGs and
|
||||
.Sy metaslab_unload_delay_ms
|
||||
milliseconds must pass before unloading will occur.
|
||||
.
|
||||
.It Sy metaslab_unload_delay_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq int
|
||||
.It Sy metaslab_unload_delay_ms Ns = Ns Sy 600000 Ns ms Po 10 min Pc Pq uint
|
||||
After a metaslab is used, we keep it loaded for this many milliseconds,
|
||||
to attempt to reduce unnecessary reloading.
|
||||
Note, that both this many milliseconds and
|
||||
.Sy metaslab_unload_delay
|
||||
TXGs must pass before unloading will occur.
|
||||
.
|
||||
.It Sy reference_history Ns = Ns Sy 3 Pq int
|
||||
.It Sy reference_history Ns = Ns Sy 3 Pq uint
|
||||
Maximum reference holders being tracked when reference_tracking_enable is active.
|
||||
.
|
||||
.It Sy reference_tracking_enable Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
@ -409,7 +415,7 @@ This is useful if you suspect your datasets are affected by a bug in
|
||||
.It Sy spa_config_path Ns = Ns Pa /etc/zfs/zpool.cache Pq charp
|
||||
SPA config file.
|
||||
.
|
||||
.It Sy spa_asize_inflation Ns = Ns Sy 24 Pq int
|
||||
.It Sy spa_asize_inflation Ns = Ns Sy 24 Pq uint
|
||||
Multiplication factor used to estimate actual disk consumption from the
|
||||
size of data being written.
|
||||
The default value is a worst case estimate,
|
||||
@ -442,7 +448,7 @@ blocks in the pool for verification.
|
||||
If this parameter is unset, the traversal is not performed.
|
||||
It can be toggled once the import has started to stop or start the traversal.
|
||||
.
|
||||
.It Sy spa_load_verify_shift Ns = Ns Sy 4 Po 1/16th Pc Pq int
|
||||
.It Sy spa_load_verify_shift Ns = Ns Sy 4 Po 1/16th Pc Pq uint
|
||||
Sets the maximum number of bytes to consume during pool import to the log2
|
||||
fraction of the target ARC size.
|
||||
.
|
||||
@ -464,7 +470,7 @@ new format when enabling the
|
||||
feature.
|
||||
The default is to convert all log entries.
|
||||
.
|
||||
.It Sy vdev_removal_max_span Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq int
|
||||
.It Sy vdev_removal_max_span Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq uint
|
||||
During top-level vdev removal, chunks of data are copied from the vdev
|
||||
which may include free space in order to trade bandwidth for IOPS.
|
||||
This parameter determines the maximum span of free space, in bytes,
|
||||
@ -559,7 +565,7 @@ 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 .
|
||||
.
|
||||
.It Sy zfs_arc_average_blocksize Ns = Ns Sy 8192 Ns B Po 8 KiB Pc Pq int
|
||||
.It Sy zfs_arc_average_blocksize Ns = Ns Sy 8192 Ns B Po 8 KiB Pc Pq uint
|
||||
The ARC's buffer hash table is sized based on the assumption of an average
|
||||
block size of this value.
|
||||
This works out to roughly 1 MiB of hash table per 1 GiB of physical memory
|
||||
@ -567,7 +573,7 @@ with 8-byte pointers.
|
||||
For configurations with a known larger average block size,
|
||||
this value can be increased to reduce the memory footprint.
|
||||
.
|
||||
.It Sy zfs_arc_eviction_pct Ns = Ns Sy 200 Ns % Pq int
|
||||
.It Sy zfs_arc_eviction_pct Ns = Ns Sy 200 Ns % Pq uint
|
||||
When
|
||||
.Fn arc_is_overflowing ,
|
||||
.Fn arc_get_data_impl
|
||||
@ -585,12 +591,12 @@ Since this is finite, it ensures that allocations can still happen,
|
||||
even during the potentially long time that
|
||||
.Sy arc_size No is more than Sy arc_c .
|
||||
.
|
||||
.It Sy zfs_arc_evict_batch_limit Ns = Ns Sy 10 Pq int
|
||||
.It Sy zfs_arc_evict_batch_limit Ns = Ns Sy 10 Pq uint
|
||||
Number ARC headers to evict per sub-list before proceeding to another sub-list.
|
||||
This batch-style operation prevents entire sub-lists from being evicted at once
|
||||
but comes at a cost of additional unlocking and locking.
|
||||
.
|
||||
.It Sy zfs_arc_grow_retry Ns = Ns Sy 0 Ns s Pq int
|
||||
.It Sy zfs_arc_grow_retry Ns = Ns Sy 0 Ns s Pq uint
|
||||
If set to a non zero value, it will replace the
|
||||
.Sy arc_grow_retry
|
||||
value with this value.
|
||||
@ -629,7 +635,7 @@ It cannot be set back to
|
||||
while running, and reducing it below the current ARC size will not cause
|
||||
the ARC to shrink without memory pressure to induce shrinking.
|
||||
.
|
||||
.It Sy zfs_arc_meta_adjust_restarts Ns = Ns Sy 4096 Pq ulong
|
||||
.It Sy zfs_arc_meta_adjust_restarts Ns = Ns Sy 4096 Pq uint
|
||||
The number of restart passes to make while scanning the ARC attempting
|
||||
the free buffers in order to stay below the
|
||||
.Sy fs_arc_meta_limit .
|
||||
@ -675,7 +681,7 @@ Setting this value to
|
||||
.Sy 0
|
||||
will disable pruning the inode and dentry caches.
|
||||
.
|
||||
.It Sy zfs_arc_meta_strategy Ns = Ns Sy 1 Ns | Ns 0 Pq int
|
||||
.It Sy zfs_arc_meta_strategy Ns = Ns Sy 1 Ns | Ns 0 Pq uint
|
||||
Define the strategy for ARC metadata buffer eviction (meta reclaim strategy):
|
||||
.Bl -tag -compact -offset 4n -width "0 (META_ONLY)"
|
||||
.It Sy 0 Pq META_ONLY
|
||||
@ -693,10 +699,10 @@ will default to consuming the larger of
|
||||
and
|
||||
.Sy all_system_memory No / Sy 32 .
|
||||
.
|
||||
.It Sy zfs_arc_min_prefetch_ms Ns = Ns Sy 0 Ns ms Ns Po Ns ≡ Ns 1s Pc Pq int
|
||||
.It Sy zfs_arc_min_prefetch_ms Ns = Ns Sy 0 Ns ms Ns Po Ns ≡ Ns 1s Pc Pq uint
|
||||
Minimum time prefetched blocks are locked in the ARC.
|
||||
.
|
||||
.It Sy zfs_arc_min_prescient_prefetch_ms Ns = Ns Sy 0 Ns ms Ns Po Ns ≡ Ns 6s Pc Pq int
|
||||
.It Sy zfs_arc_min_prescient_prefetch_ms Ns = Ns Sy 0 Ns ms Ns Po Ns ≡ Ns 6s Pc Pq uint
|
||||
Minimum time "prescient prefetched" blocks are locked in the ARC.
|
||||
These blocks are meant to be prefetched fairly aggressively ahead of
|
||||
the code that may use them.
|
||||
@ -733,7 +739,7 @@ and to
|
||||
.Sy 134217728 Ns B Pq 128 MiB
|
||||
under Linux.
|
||||
.
|
||||
.It Sy zfs_multilist_num_sublists Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_multilist_num_sublists Ns = Ns Sy 0 Pq uint
|
||||
To allow more fine-grained locking, each ARC state contains a series
|
||||
of lists for both data and metadata objects.
|
||||
Locking is performed at the level of these "sub-lists".
|
||||
@ -766,7 +772,7 @@ causes the ARC to start reclamation if it exceeds the target size by
|
||||
of the target size, and block allocations by
|
||||
.Em 0.6% .
|
||||
.
|
||||
.It Sy zfs_arc_p_min_shift Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_arc_p_min_shift Ns = Ns Sy 0 Pq uint
|
||||
If nonzero, this will update
|
||||
.Sy arc_p_min_shift Pq default Sy 4
|
||||
with the new value.
|
||||
@ -780,7 +786,7 @@ Disable
|
||||
adapt dampener, which reduces the maximum single adjustment to
|
||||
.Sy arc_p .
|
||||
.
|
||||
.It Sy zfs_arc_shrink_shift Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_arc_shrink_shift Ns = Ns Sy 0 Pq uint
|
||||
If nonzero, this will update
|
||||
.Sy arc_shrink_shift Pq default Sy 7
|
||||
with the new value.
|
||||
@ -831,7 +837,7 @@ Note that this should not be set below the ZED thresholds
|
||||
(currently 10 checksums over 10 seconds)
|
||||
or else the daemon may not trigger any action.
|
||||
.
|
||||
.It Sy zfs_commit_timeout_pct Ns = Ns Sy 5 Ns % Pq int
|
||||
.It Sy zfs_commit_timeout_pct Ns = Ns Sy 5 Ns % Pq uint
|
||||
This controls the amount of time that a ZIL block (lwb) will remain "open"
|
||||
when it isn't "full", and it has a thread waiting for it to be committed to
|
||||
stable storage.
|
||||
@ -844,7 +850,7 @@ Vdev indirection layer (used for device removal) sleeps for this many
|
||||
milliseconds during mapping generation.
|
||||
Intended for use with the test suite to throttle vdev removal speed.
|
||||
.
|
||||
.It Sy zfs_condense_indirect_obsolete_pct Ns = Ns Sy 25 Ns % Pq int
|
||||
.It Sy zfs_condense_indirect_obsolete_pct Ns = Ns Sy 25 Ns % Pq uint
|
||||
Minimum percent of obsolete bytes in vdev mapping required to attempt to condense
|
||||
.Pq see Sy zfs_condense_indirect_vdevs_enable .
|
||||
Intended for use with the test suite
|
||||
@ -881,7 +887,7 @@ to the file clears the log.
|
||||
This setting does not influence debug prints due to
|
||||
.Sy zfs_flags .
|
||||
.
|
||||
.It Sy zfs_dbgmsg_maxsize Ns = Ns Sy 4194304 Ns B Po 4 MiB Pc Pq int
|
||||
.It Sy zfs_dbgmsg_maxsize Ns = Ns Sy 4194304 Ns B Po 4 MiB Pc Pq uint
|
||||
Maximum size of the internal ZFS debug log.
|
||||
.
|
||||
.It Sy zfs_dbuf_state_index Ns = Ns Sy 0 Pq int
|
||||
@ -946,7 +952,7 @@ milliseconds until the operation completes.
|
||||
.It Sy zfs_dedup_prefetch Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
Enable prefetching dedup-ed blocks which are going to be freed.
|
||||
.
|
||||
.It Sy zfs_delay_min_dirty_percent Ns = Ns Sy 60 Ns % Pq int
|
||||
.It Sy zfs_delay_min_dirty_percent Ns = Ns Sy 60 Ns % Pq uint
|
||||
Start to delay each transaction once there is this amount of dirty data,
|
||||
expressed as a percentage of
|
||||
.Sy zfs_dirty_data_max .
|
||||
@ -1081,7 +1087,7 @@ This parameter takes precedence over
|
||||
Defaults to
|
||||
.Sy physical_ram/4 ,
|
||||
.
|
||||
.It Sy zfs_dirty_data_max_max_percent Ns = Ns Sy 25 Ns % Pq int
|
||||
.It Sy zfs_dirty_data_max_max_percent Ns = Ns Sy 25 Ns % Pq uint
|
||||
Maximum allowable value of
|
||||
.Sy zfs_dirty_data_max ,
|
||||
expressed as a percentage of physical RAM.
|
||||
@ -1093,7 +1099,7 @@ The parameter
|
||||
takes precedence over this one.
|
||||
.No See Sx ZFS TRANSACTION DELAY .
|
||||
.
|
||||
.It Sy zfs_dirty_data_max_percent Ns = Ns Sy 10 Ns % Pq int
|
||||
.It Sy zfs_dirty_data_max_percent Ns = Ns Sy 10 Ns % Pq uint
|
||||
Determines the dirty space limit, expressed as a percentage of all memory.
|
||||
Once this limit is exceeded, new writes are halted until space frees up.
|
||||
The parameter
|
||||
@ -1104,7 +1110,7 @@ takes precedence over this one.
|
||||
Subject to
|
||||
.Sy zfs_dirty_data_max_max .
|
||||
.
|
||||
.It Sy zfs_dirty_data_sync_percent Ns = Ns Sy 20 Ns % Pq int
|
||||
.It Sy zfs_dirty_data_sync_percent Ns = Ns Sy 20 Ns % Pq uint
|
||||
Start syncing out a transaction group if there's at least this much dirty data
|
||||
.Pq as a percentage of Sy zfs_dirty_data_max .
|
||||
This should be less than
|
||||
@ -1185,15 +1191,15 @@ 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
|
||||
Maximum number of dedup blocks freed in a single TXG.
|
||||
.
|
||||
.It Sy zfs_vdev_async_read_max_active Ns = Ns Sy 3 Pq int
|
||||
.It Sy zfs_vdev_async_read_max_active Ns = Ns Sy 3 Pq uint
|
||||
Maximum asynchronous read I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_async_read_min_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_async_read_min_active Ns = Ns Sy 1 Pq uint
|
||||
Minimum asynchronous read I/O operation active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_async_write_active_max_dirty_percent Ns = Ns Sy 60 Ns % Pq int
|
||||
.It Sy zfs_vdev_async_write_active_max_dirty_percent Ns = Ns Sy 60 Ns % Pq uint
|
||||
When the pool has more than this much dirty data, use
|
||||
.Sy zfs_vdev_async_write_max_active
|
||||
to limit active async writes.
|
||||
@ -1201,7 +1207,7 @@ If the dirty data is between the minimum and maximum,
|
||||
the active I/O limit is linearly interpolated.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_async_write_active_min_dirty_percent Ns = Ns Sy 30 Ns % Pq int
|
||||
.It Sy zfs_vdev_async_write_active_min_dirty_percent Ns = Ns Sy 30 Ns % Pq uint
|
||||
When the pool has less than this much dirty data, use
|
||||
.Sy zfs_vdev_async_write_min_active
|
||||
to limit active async writes.
|
||||
@ -1210,11 +1216,11 @@ the active I/O limit is linearly
|
||||
interpolated.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_async_write_max_active Ns = Ns Sy 30 Pq int
|
||||
.It Sy zfs_vdev_async_write_max_active Ns = Ns Sy 30 Pq uint
|
||||
Maximum asynchronous write I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_async_write_min_active Ns = Ns Sy 2 Pq int
|
||||
.It Sy zfs_vdev_async_write_min_active Ns = Ns Sy 2 Pq uint
|
||||
Minimum asynchronous write I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.Pp
|
||||
@ -1228,69 +1234,69 @@ A value of
|
||||
has been shown to improve resilver performance further at a cost of
|
||||
further increasing latency.
|
||||
.
|
||||
.It Sy zfs_vdev_initializing_max_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_initializing_max_active Ns = Ns Sy 1 Pq uint
|
||||
Maximum initializing I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_initializing_min_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_initializing_min_active Ns = Ns Sy 1 Pq uint
|
||||
Minimum initializing I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_max_active Ns = Ns Sy 1000 Pq int
|
||||
.It Sy zfs_vdev_max_active Ns = Ns Sy 1000 Pq uint
|
||||
The maximum number of I/O operations active to each device.
|
||||
Ideally, this will be at least the sum of each queue's
|
||||
.Sy max_active .
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_rebuild_max_active Ns = Ns Sy 3 Pq int
|
||||
.It Sy zfs_vdev_rebuild_max_active Ns = Ns Sy 3 Pq uint
|
||||
Maximum sequential resilver I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_rebuild_min_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_rebuild_min_active Ns = Ns Sy 1 Pq uint
|
||||
Minimum sequential resilver I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_removal_max_active Ns = Ns Sy 2 Pq int
|
||||
.It Sy zfs_vdev_removal_max_active Ns = Ns Sy 2 Pq uint
|
||||
Maximum removal I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_removal_min_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_removal_min_active Ns = Ns Sy 1 Pq uint
|
||||
Minimum removal I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_scrub_max_active Ns = Ns Sy 2 Pq int
|
||||
.It Sy zfs_vdev_scrub_max_active Ns = Ns Sy 2 Pq uint
|
||||
Maximum scrub I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_scrub_min_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_scrub_min_active Ns = Ns Sy 1 Pq uint
|
||||
Minimum scrub I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_sync_read_max_active Ns = Ns Sy 10 Pq int
|
||||
.It Sy zfs_vdev_sync_read_max_active Ns = Ns Sy 10 Pq uint
|
||||
Maximum synchronous read I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_sync_read_min_active Ns = Ns Sy 10 Pq int
|
||||
.It Sy zfs_vdev_sync_read_min_active Ns = Ns Sy 10 Pq uint
|
||||
Minimum synchronous read I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_sync_write_max_active Ns = Ns Sy 10 Pq int
|
||||
.It Sy zfs_vdev_sync_write_max_active Ns = Ns Sy 10 Pq uint
|
||||
Maximum synchronous write I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_sync_write_min_active Ns = Ns Sy 10 Pq int
|
||||
.It Sy zfs_vdev_sync_write_min_active Ns = Ns Sy 10 Pq uint
|
||||
Minimum synchronous write I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_trim_max_active Ns = Ns Sy 2 Pq int
|
||||
.It Sy zfs_vdev_trim_max_active Ns = Ns Sy 2 Pq uint
|
||||
Maximum trim/discard I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_trim_min_active Ns = Ns Sy 1 Pq int
|
||||
.It Sy zfs_vdev_trim_min_active Ns = Ns Sy 1 Pq uint
|
||||
Minimum trim/discard I/O operations active to each device.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_nia_delay Ns = Ns Sy 5 Pq int
|
||||
.It Sy zfs_vdev_nia_delay Ns = Ns Sy 5 Pq uint
|
||||
For non-interactive I/O (scrub, resilver, removal, initialize and rebuild),
|
||||
the number of concurrently-active I/O operations is limited to
|
||||
.Sy zfs_*_min_active ,
|
||||
@ -1304,7 +1310,7 @@ and the number of concurrently-active non-interactive operations is increased to
|
||||
.Sy zfs_*_max_active .
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_nia_credit Ns = Ns Sy 5 Pq int
|
||||
.It Sy zfs_vdev_nia_credit Ns = Ns Sy 5 Pq uint
|
||||
Some HDDs tend to prioritize sequential I/O so strongly, that concurrent
|
||||
random I/O latency reaches several seconds.
|
||||
On some HDDs this happens even if sequential I/O operations
|
||||
@ -1319,7 +1325,7 @@ This enforced wait ensures the HDD services the interactive I/O
|
||||
within a reasonable amount of time.
|
||||
.No See Sx ZFS I/O SCHEDULER .
|
||||
.
|
||||
.It Sy zfs_vdev_queue_depth_pct Ns = Ns Sy 1000 Ns % Pq int
|
||||
.It Sy zfs_vdev_queue_depth_pct Ns = Ns Sy 1000 Ns % Pq uint
|
||||
Maximum number of queued allocations per top-level vdev expressed as
|
||||
a percentage of
|
||||
.Sy zfs_vdev_async_write_max_active ,
|
||||
@ -1425,7 +1431,7 @@ but we chose the more conservative approach of not setting it,
|
||||
so that there is no possibility of
|
||||
leaking space in the "partial temporary" failure case.
|
||||
.
|
||||
.It Sy zfs_free_min_time_ms Ns = Ns Sy 1000 Ns ms Po 1s Pc Pq int
|
||||
.It Sy zfs_free_min_time_ms Ns = Ns Sy 1000 Ns ms Po 1s Pc Pq uint
|
||||
During a
|
||||
.Nm zfs Cm destroy
|
||||
operation using the
|
||||
@ -1433,7 +1439,7 @@ operation using the
|
||||
feature,
|
||||
a minimum of this much time will be spent working on freeing blocks per TXG.
|
||||
.
|
||||
.It Sy zfs_obsolete_min_time_ms Ns = Ns Sy 500 Ns ms Pq int
|
||||
.It Sy zfs_obsolete_min_time_ms Ns = Ns Sy 500 Ns ms Pq uint
|
||||
Similar to
|
||||
.Sy zfs_free_min_time_ms ,
|
||||
but for cleanup of old indirection records for removed vdevs.
|
||||
@ -1512,7 +1518,7 @@ feature uses to estimate incoming log blocks.
|
||||
.It Sy zfs_max_logsm_summary_length Ns = Ns Sy 10 Pq ulong
|
||||
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 int
|
||||
.It Sy zfs_max_recordsize Ns = Ns Sy 16777216 Po 16 MiB Pc Pq uint
|
||||
We currently support block sizes from
|
||||
.Em 512 Po 512 B Pc No to Em 16777216 Po 16 MiB Pc .
|
||||
The benefits of larger blocks, and thus larger I/O,
|
||||
@ -1531,13 +1537,13 @@ Normally disabled because these datasets may be missing key data.
|
||||
.It Sy zfs_min_metaslabs_to_flush Ns = Ns Sy 1 Pq ulong
|
||||
Minimum number of metaslabs to flush per dirty TXG.
|
||||
.
|
||||
.It Sy zfs_metaslab_fragmentation_threshold Ns = Ns Sy 70 Ns % Pq int
|
||||
.It Sy zfs_metaslab_fragmentation_threshold Ns = Ns Sy 70 Ns % Pq uint
|
||||
Allow metaslabs to keep their active state as long as their fragmentation
|
||||
percentage is no more than this value.
|
||||
An active metaslab that exceeds this threshold
|
||||
will no longer keep its active status allowing better metaslabs to be selected.
|
||||
.
|
||||
.It Sy zfs_mg_fragmentation_threshold Ns = Ns Sy 95 Ns % Pq int
|
||||
.It Sy zfs_mg_fragmentation_threshold Ns = Ns Sy 95 Ns % Pq uint
|
||||
Metaslab groups are considered eligible for allocations if their
|
||||
fragmentation metric (measured as a percentage) is less than or equal to
|
||||
this value.
|
||||
@ -1545,7 +1551,7 @@ If a metaslab group exceeds this threshold then it will be
|
||||
skipped unless all metaslab groups within the metaslab class have also
|
||||
crossed this threshold.
|
||||
.
|
||||
.It Sy zfs_mg_noalloc_threshold Ns = Ns Sy 0 Ns % Pq int
|
||||
.It Sy zfs_mg_noalloc_threshold Ns = Ns Sy 0 Ns % Pq uint
|
||||
Defines a threshold at which metaslab groups should be eligible for allocations.
|
||||
The value is expressed as a percentage of free space
|
||||
beyond which a metaslab group is always eligible for allocations.
|
||||
@ -1574,7 +1580,7 @@ If enabled, ZFS will place DDT data into the special allocation class.
|
||||
If enabled, ZFS will place user data indirect blocks
|
||||
into the special allocation class.
|
||||
.
|
||||
.It Sy zfs_multihost_history Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_multihost_history Ns = Ns Sy 0 Pq uint
|
||||
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 .
|
||||
.
|
||||
@ -1665,7 +1671,7 @@ The number of bytes which should be prefetched during a pool traversal, like
|
||||
.Nm zfs Cm send
|
||||
or other data crawling operations.
|
||||
.
|
||||
.It Sy zfs_traverse_indirect_prefetch_limit Ns = Ns Sy 32 Pq int
|
||||
.It Sy zfs_traverse_indirect_prefetch_limit Ns = Ns Sy 32 Pq uint
|
||||
The number of blocks pointed by indirect (non-L0) block which should be
|
||||
prefetched during a pool traversal, like
|
||||
.Nm zfs Cm send
|
||||
@ -1702,7 +1708,7 @@ 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
|
||||
Bytes to read per chunk.
|
||||
.
|
||||
.It Sy zfs_read_history Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_read_history Ns = Ns Sy 0 Pq uint
|
||||
Historical statistics for this many latest reads will be available in
|
||||
.Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /reads .
|
||||
.
|
||||
@ -1747,11 +1753,11 @@ and is hence not recommended.
|
||||
This should only be used as a last resort when the
|
||||
pool cannot be returned to a healthy state prior to removing the device.
|
||||
.
|
||||
.It Sy zfs_removal_suspend_progress Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
.It Sy zfs_removal_suspend_progress Ns = Ns Sy 0 Ns | Ns 1 Pq uint
|
||||
This is used by the test suite so that it can ensure that certain actions
|
||||
happen while in the middle of a removal.
|
||||
.
|
||||
.It Sy zfs_remove_max_segment Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq int
|
||||
.It Sy zfs_remove_max_segment Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq uint
|
||||
The largest contiguous segment that we will attempt to allocate when removing
|
||||
a device.
|
||||
If there is a performance problem with attempting to allocate large blocks,
|
||||
@ -1764,7 +1770,7 @@ Ignore the
|
||||
feature, causing an operation that would start a resilver to
|
||||
immediately restart the one in progress.
|
||||
.
|
||||
.It Sy zfs_resilver_min_time_ms Ns = Ns Sy 3000 Ns ms Po 3 s Pc Pq int
|
||||
.It Sy zfs_resilver_min_time_ms Ns = Ns Sy 3000 Ns ms Po 3 s Pc Pq uint
|
||||
Resilvers are processed by the sync thread.
|
||||
While resilvering, it will spend at least this much time
|
||||
working on a resilver between TXG flushes.
|
||||
@ -1775,17 +1781,17 @@ even if there were unrepairable errors.
|
||||
Intended to be used during pool repair or recovery to
|
||||
stop resilvering when the pool is next imported.
|
||||
.
|
||||
.It Sy zfs_scrub_min_time_ms Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq int
|
||||
.It Sy zfs_scrub_min_time_ms Ns = Ns Sy 1000 Ns ms Po 1 s Pc Pq uint
|
||||
Scrubs are processed by the sync thread.
|
||||
While scrubbing, it will spend at least this much time
|
||||
working on a scrub between TXG flushes.
|
||||
.
|
||||
.It Sy zfs_scan_checkpoint_intval Ns = Ns Sy 7200 Ns s Po 2 hour Pc Pq int
|
||||
.It Sy zfs_scan_checkpoint_intval Ns = Ns Sy 7200 Ns s Po 2 hour Pc Pq uint
|
||||
To preserve progress across reboots, the sequential scan algorithm periodically
|
||||
needs to stop metadata scanning and issue all the verification I/O to disk.
|
||||
The frequency of this flushing is determined by this tunable.
|
||||
.
|
||||
.It Sy zfs_scan_fill_weight Ns = Ns Sy 3 Pq int
|
||||
.It Sy zfs_scan_fill_weight Ns = Ns Sy 3 Pq uint
|
||||
This tunable affects how scrub and resilver I/O segments are ordered.
|
||||
A higher number indicates that we care more about how filled in a segment is,
|
||||
while a lower number indicates we care more about the size of the extent without
|
||||
@ -1793,7 +1799,7 @@ considering the gaps within a segment.
|
||||
This value is only tunable upon module insertion.
|
||||
Changing the value afterwards will have no effect on scrub or resilver performance.
|
||||
.
|
||||
.It Sy zfs_scan_issue_strategy Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_scan_issue_strategy Ns = Ns Sy 0 Pq uint
|
||||
Determines the order that data will be verified while scrubbing or resilvering:
|
||||
.Bl -tag -compact -offset 4n -width "a"
|
||||
.It Sy 1
|
||||
@ -1823,14 +1829,14 @@ that will still be considered sequential for sorting purposes.
|
||||
Changing this value will not
|
||||
affect scrubs or resilvers that are already in progress.
|
||||
.
|
||||
.It Sy zfs_scan_mem_lim_fact Ns = Ns Sy 20 Ns ^-1 Pq int
|
||||
.It Sy zfs_scan_mem_lim_fact Ns = Ns Sy 20 Ns ^-1 Pq uint
|
||||
Maximum fraction of RAM used for I/O sorting by sequential scan algorithm.
|
||||
This tunable determines the hard limit for I/O sorting memory usage.
|
||||
When the hard limit is reached we stop scanning metadata and start issuing
|
||||
data verification I/O.
|
||||
This is done until we get below the soft limit.
|
||||
.
|
||||
.It Sy zfs_scan_mem_lim_soft_fact Ns = Ns Sy 20 Ns ^-1 Pq int
|
||||
.It Sy zfs_scan_mem_lim_soft_fact Ns = Ns Sy 20 Ns ^-1 Pq uint
|
||||
The fraction of the hard limit used to determined the soft limit for I/O sorting
|
||||
by the sequential scan algorithm.
|
||||
When we cross this limit from below no action is taken.
|
||||
@ -1860,41 +1866,41 @@ remove the spill block from an existing object.
|
||||
Including unmodified copies of the spill blocks creates a backwards-compatible
|
||||
stream which will recreate a spill block if it was incorrectly removed.
|
||||
.
|
||||
.It Sy zfs_send_no_prefetch_queue_ff Ns = Ns Sy 20 Ns ^\-1 Pq int
|
||||
.It Sy zfs_send_no_prefetch_queue_ff Ns = Ns Sy 20 Ns ^\-1 Pq uint
|
||||
The fill fraction of the
|
||||
.Nm zfs Cm send
|
||||
internal queues.
|
||||
The fill fraction controls the timing with which internal threads are woken up.
|
||||
.
|
||||
.It Sy zfs_send_no_prefetch_queue_length Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq int
|
||||
.It Sy zfs_send_no_prefetch_queue_length Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq uint
|
||||
The maximum number of bytes allowed in
|
||||
.Nm zfs Cm send Ns 's
|
||||
internal queues.
|
||||
.
|
||||
.It Sy zfs_send_queue_ff Ns = Ns Sy 20 Ns ^\-1 Pq int
|
||||
.It Sy zfs_send_queue_ff Ns = Ns Sy 20 Ns ^\-1 Pq uint
|
||||
The fill fraction of the
|
||||
.Nm zfs Cm send
|
||||
prefetch queue.
|
||||
The fill fraction controls the timing with which internal threads are woken up.
|
||||
.
|
||||
.It Sy zfs_send_queue_length Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq int
|
||||
.It Sy zfs_send_queue_length Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq uint
|
||||
The maximum number of bytes allowed that will be prefetched by
|
||||
.Nm zfs Cm send .
|
||||
This value must be at least twice the maximum block size in use.
|
||||
.
|
||||
.It Sy zfs_recv_queue_ff Ns = Ns Sy 20 Ns ^\-1 Pq int
|
||||
.It Sy zfs_recv_queue_ff Ns = Ns Sy 20 Ns ^\-1 Pq uint
|
||||
The fill fraction of the
|
||||
.Nm zfs Cm receive
|
||||
queue.
|
||||
The fill fraction controls the timing with which internal threads are woken up.
|
||||
.
|
||||
.It Sy zfs_recv_queue_length Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq int
|
||||
.It Sy zfs_recv_queue_length Ns = Ns Sy 16777216 Ns B Po 16 MiB Pc Pq uint
|
||||
The maximum number of bytes allowed in the
|
||||
.Nm zfs Cm receive
|
||||
queue.
|
||||
This value must be at least twice the maximum block size in use.
|
||||
.
|
||||
.It Sy zfs_recv_write_batch_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq int
|
||||
.It Sy zfs_recv_write_batch_size Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq uint
|
||||
The maximum amount of data, in bytes, that
|
||||
.Nm zfs Cm receive
|
||||
will write in one DMU transaction.
|
||||
@ -1914,7 +1920,7 @@ If there is an error during healing, the healing receive is not
|
||||
terminated instead it moves on to the next record.
|
||||
.El
|
||||
.
|
||||
.It Sy zfs_override_estimate_recordsize Ns = Ns Sy 0 Ns | Ns 1 Pq ulong
|
||||
.It Sy zfs_override_estimate_recordsize Ns = Ns Sy 0 Ns | Ns 1 Pq uint
|
||||
Setting this variable overrides the default logic for estimating block
|
||||
sizes when doing a
|
||||
.Nm zfs Cm send .
|
||||
@ -1923,7 +1929,7 @@ will be the current recordsize.
|
||||
Override this value if most data in your dataset is not of that size
|
||||
and you require accurate zfs send size estimates.
|
||||
.
|
||||
.It Sy zfs_sync_pass_deferred_free Ns = Ns Sy 2 Pq int
|
||||
.It Sy zfs_sync_pass_deferred_free Ns = Ns Sy 2 Pq uint
|
||||
Flushing of data to disk is done in passes.
|
||||
Defer frees starting in this pass.
|
||||
.
|
||||
@ -1931,13 +1937,13 @@ Defer frees starting in this pass.
|
||||
Maximum memory used for prefetching a checkpoint's space map on each
|
||||
vdev while discarding the checkpoint.
|
||||
.
|
||||
.It Sy zfs_special_class_metadata_reserve_pct Ns = Ns Sy 25 Ns % Pq int
|
||||
.It Sy zfs_special_class_metadata_reserve_pct Ns = Ns Sy 25 Ns % Pq uint
|
||||
Only allow small data blocks to be allocated on the special and dedup vdev
|
||||
types when the available free space percentage on these vdevs exceeds this value.
|
||||
This ensures reserved space is available for pool metadata as the
|
||||
special vdevs approach capacity.
|
||||
.
|
||||
.It Sy zfs_sync_pass_dont_compress Ns = Ns Sy 8 Pq int
|
||||
.It Sy zfs_sync_pass_dont_compress Ns = Ns Sy 8 Pq uint
|
||||
Starting in this sync pass, disable compression (including of metadata).
|
||||
With the default setting, in practice, we don't have this many sync passes,
|
||||
so this has no effect.
|
||||
@ -1958,7 +1964,7 @@ allocations are especially detrimental to performance
|
||||
on highly fragmented systems, which may have very few free segments of this size,
|
||||
and may need to load new metaslabs to satisfy these allocations.
|
||||
.
|
||||
.It Sy zfs_sync_pass_rewrite Ns = Ns Sy 2 Pq int
|
||||
.It Sy zfs_sync_pass_rewrite Ns = Ns Sy 2 Pq uint
|
||||
Rewrite new block pointers starting in this pass.
|
||||
.
|
||||
.It Sy zfs_sync_taskq_batch_pct Ns = Ns Sy 75 Ns % Pq int
|
||||
@ -2007,35 +2013,35 @@ The default of
|
||||
.Sy 32
|
||||
was determined to be a reasonable compromise.
|
||||
.
|
||||
.It Sy zfs_txg_history Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_txg_history Ns = Ns Sy 0 Pq uint
|
||||
Historical statistics for this many latest TXGs will be available in
|
||||
.Pa /proc/spl/kstat/zfs/ Ns Ao Ar pool Ac Ns Pa /TXGs .
|
||||
.
|
||||
.It Sy zfs_txg_timeout Ns = Ns Sy 5 Ns s Pq int
|
||||
.It Sy zfs_txg_timeout Ns = Ns Sy 5 Ns s Pq uint
|
||||
Flush dirty data to disk at least every this many seconds (maximum TXG duration).
|
||||
.
|
||||
.It Sy zfs_vdev_aggregate_trim Ns = Ns Sy 0 Ns | Ns 1 Pq int
|
||||
.It Sy zfs_vdev_aggregate_trim Ns = Ns Sy 0 Ns | Ns 1 Pq uint
|
||||
Allow TRIM I/O operations to be aggregated.
|
||||
This is normally not helpful because the extents to be trimmed
|
||||
will have been already been aggregated by the metaslab.
|
||||
This option is provided for debugging and performance analysis.
|
||||
.
|
||||
.It Sy zfs_vdev_aggregation_limit Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq int
|
||||
.It Sy zfs_vdev_aggregation_limit Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq uint
|
||||
Max vdev I/O aggregation size.
|
||||
.
|
||||
.It Sy zfs_vdev_aggregation_limit_non_rotating Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq int
|
||||
.It Sy zfs_vdev_aggregation_limit_non_rotating Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq uint
|
||||
Max vdev I/O aggregation size for non-rotating media.
|
||||
.
|
||||
.It Sy zfs_vdev_cache_bshift Ns = Ns Sy 16 Po 64 KiB Pc Pq int
|
||||
.It Sy zfs_vdev_cache_bshift Ns = Ns Sy 16 Po 64 KiB Pc Pq uint
|
||||
Shift size to inflate reads to.
|
||||
.
|
||||
.It Sy zfs_vdev_cache_max Ns = Ns Sy 16384 Ns B Po 16 KiB Pc Pq int
|
||||
.It Sy zfs_vdev_cache_max Ns = Ns Sy 16384 Ns B Po 16 KiB Pc Pq uint
|
||||
Inflate reads smaller than this value to meet the
|
||||
.Sy zfs_vdev_cache_bshift
|
||||
size
|
||||
.Pq default Sy 64 KiB .
|
||||
.
|
||||
.It Sy zfs_vdev_cache_size Ns = Ns Sy 0 Pq int
|
||||
.It Sy zfs_vdev_cache_size Ns = Ns Sy 0 Pq uint
|
||||
Total size of the per-disk cache in bytes.
|
||||
.Pp
|
||||
Currently this feature is disabled, as it has been found to not be helpful
|
||||
@ -2073,11 +2079,11 @@ locality as defined by the
|
||||
Operations within this that are not immediately following the previous operation
|
||||
are incremented by half.
|
||||
.
|
||||
.It Sy zfs_vdev_read_gap_limit Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq int
|
||||
.It Sy zfs_vdev_read_gap_limit Ns = Ns Sy 32768 Ns B Po 32 KiB Pc Pq uint
|
||||
Aggregate read I/O operations if the on-disk gap between them is within this
|
||||
threshold.
|
||||
.
|
||||
.It Sy zfs_vdev_write_gap_limit Ns = Ns Sy 4096 Ns B Po 4 KiB Pc Pq int
|
||||
.It Sy zfs_vdev_write_gap_limit Ns = Ns Sy 4096 Ns B Po 4 KiB Pc Pq uint
|
||||
Aggregate write I/O operations if the on-disk gap between them is within this
|
||||
threshold.
|
||||
.
|
||||
@ -2114,7 +2120,7 @@ powerpc_altivec Altivec PowerPC
|
||||
.Sy DEPRECATED .
|
||||
Prints warning to kernel log for compatibility.
|
||||
.
|
||||
.It Sy zfs_zevent_len_max Ns = Ns Sy 512 Pq int
|
||||
.It Sy zfs_zevent_len_max Ns = Ns Sy 512 Pq uint
|
||||
Max event queue length.
|
||||
Events in the queue can be viewed with
|
||||
.Xr zpool-events 8 .
|
||||
@ -2144,7 +2150,7 @@ The default value of
|
||||
.Sy 100%
|
||||
will create a maximum of one thread per cpu.
|
||||
.
|
||||
.It Sy zil_maxblocksize Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq int
|
||||
.It Sy zil_maxblocksize Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq uint
|
||||
This sets the maximum block size used by the ZIL.
|
||||
On very fragmented pools, lowering this
|
||||
.Pq typically to Sy 36 KiB
|
||||
@ -2175,7 +2181,7 @@ This would only be necessary to work around bugs in the ZIL logging or replay
|
||||
code for this record type.
|
||||
The tunable has no effect if the feature is disabled.
|
||||
.
|
||||
.It Sy zfs_embedded_slog_min_ms Ns = Ns Sy 64 Pq int
|
||||
.It Sy zfs_embedded_slog_min_ms Ns = Ns Sy 64 Pq uint
|
||||
Usually, one metaslab from each normal-class vdev is dedicated for use by
|
||||
the ZIL to log synchronous writes.
|
||||
However, if there are fewer than
|
||||
@ -2183,11 +2189,11 @@ However, if there are fewer than
|
||||
metaslabs in the vdev, this functionality is disabled.
|
||||
This ensures that we don't set aside an unreasonable amount of space for the ZIL.
|
||||
.
|
||||
.It Sy zstd_earlyabort_pass Ns = Ns Sy 1 Pq int
|
||||
.It Sy zstd_earlyabort_pass Ns = Ns Sy 1 Pq uint
|
||||
Whether heuristic for detection of incompressible data with zstd levels >= 3
|
||||
using LZ4 and zstd-1 passes is enabled.
|
||||
.
|
||||
.It Sy zstd_abort_size Ns = Ns Sy 131072 Pq int
|
||||
.It Sy zstd_abort_size Ns = Ns Sy 131072 Pq uint
|
||||
Minimal uncompressed size (inclusive) of a record before the early abort
|
||||
heuristic will be attempted.
|
||||
.
|
||||
|
@ -155,7 +155,6 @@ blake3_impl_setid(uint32_t id)
|
||||
atomic_swap_32(&blake3_impl_chosen, IMPL_CYCLE);
|
||||
break;
|
||||
default:
|
||||
ASSERT3U(id, >=, 0);
|
||||
ASSERT3U(id, <, blake3_supp_impls_cnt);
|
||||
atomic_swap_32(&blake3_impl_chosen, id);
|
||||
break;
|
||||
|
@ -421,7 +421,7 @@ skein_update(crypto_ctx_t *ctx, crypto_data_t *data)
|
||||
* Supported output digest formats are raw, uio and mblk.
|
||||
*/
|
||||
static int
|
||||
skein_final(crypto_ctx_t *ctx, crypto_data_t *digest)
|
||||
skein_final_nofree(crypto_ctx_t *ctx, crypto_data_t *digest)
|
||||
{
|
||||
int error = CRYPTO_SUCCESS;
|
||||
|
||||
@ -452,6 +452,17 @@ skein_final(crypto_ctx_t *ctx, crypto_data_t *digest)
|
||||
else
|
||||
digest->cd_length = 0;
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
skein_final(crypto_ctx_t *ctx, crypto_data_t *digest)
|
||||
{
|
||||
int error = skein_final_nofree(ctx, digest);
|
||||
|
||||
if (error == CRYPTO_BUFFER_TOO_SMALL)
|
||||
return (error);
|
||||
|
||||
memset(SKEIN_CTX(ctx), 0, sizeof (*SKEIN_CTX(ctx)));
|
||||
kmem_free(SKEIN_CTX(ctx), sizeof (*(SKEIN_CTX(ctx))));
|
||||
SKEIN_CTX_LVALUE(ctx) = NULL;
|
||||
@ -485,7 +496,7 @@ skein_digest_atomic(crypto_mechanism_t *mechanism, crypto_data_t *data,
|
||||
|
||||
if ((error = skein_update(&ctx, data)) != CRYPTO_SUCCESS)
|
||||
goto out;
|
||||
if ((error = skein_final(&ctx, data)) != CRYPTO_SUCCESS)
|
||||
if ((error = skein_final_nofree(&ctx, data)) != CRYPTO_SUCCESS)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
@ -588,7 +599,7 @@ skein_mac_atomic(crypto_mechanism_t *mechanism,
|
||||
|
||||
if ((error = skein_update(&ctx, data)) != CRYPTO_SUCCESS)
|
||||
goto errout;
|
||||
if ((error = skein_final(&ctx, mac)) != CRYPTO_SUCCESS)
|
||||
if ((error = skein_final_nofree(&ctx, mac)) != CRYPTO_SUCCESS)
|
||||
goto errout;
|
||||
|
||||
return (CRYPTO_SUCCESS);
|
||||
|
@ -405,7 +405,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
StkId base;
|
||||
Proto *p = clLvalue(func)->p;
|
||||
n = cast_int(L->top - func) - 1; /* number of real arguments */
|
||||
luaD_checkstack(L, p->maxstacksize);
|
||||
luaD_checkstack(L, p->maxstacksize + p->numparams);
|
||||
for (; n < p->numparams; n++)
|
||||
setnilvalue(L->top++); /* complete missing arguments */
|
||||
if (!p->is_vararg) {
|
||||
|
@ -160,8 +160,7 @@ callb_add_common(boolean_t (*func)(void *arg, int code),
|
||||
"too long -- truncated to %d chars",
|
||||
name, CB_MAXNAME);
|
||||
#endif
|
||||
(void) strncpy(cp->c_name, name, CB_MAXNAME);
|
||||
cp->c_name[CB_MAXNAME] = '\0';
|
||||
(void) strlcpy(cp->c_name, name, sizeof (cp->c_name));
|
||||
|
||||
/*
|
||||
* Insert the new callb at the head of its class list.
|
||||
|
@ -94,7 +94,7 @@ ddi_copyout(const void *from, void *to, size_t len, int flags)
|
||||
return (copyout(from, to, len));
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
spl_panic(const char *file, const char *func, int line, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -138,7 +138,7 @@ arc_default_max(uint64_t min, uint64_t allmem)
|
||||
static void
|
||||
arc_prune_task(void *arg)
|
||||
{
|
||||
int64_t nr_scan = (intptr_t)arg;
|
||||
uint64_t nr_scan = (uintptr_t)arg;
|
||||
|
||||
arc_reduce_target_size(ptob(nr_scan));
|
||||
|
||||
@ -168,12 +168,12 @@ arc_prune_task(void *arg)
|
||||
* for releasing it once the registered arc_prune_func_t has completed.
|
||||
*/
|
||||
void
|
||||
arc_prune_async(int64_t adjust)
|
||||
arc_prune_async(uint64_t adjust)
|
||||
{
|
||||
|
||||
#ifndef __LP64__
|
||||
if (adjust > INTPTR_MAX)
|
||||
adjust = INTPTR_MAX;
|
||||
if (adjust > UINTPTR_MAX)
|
||||
adjust = UINTPTR_MAX;
|
||||
#endif
|
||||
taskq_dispatch(arc_prune_taskq, arc_prune_task,
|
||||
(void *)(intptr_t)adjust, TQ_SLEEP);
|
||||
|
@ -514,19 +514,19 @@ SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, sm_blksz_with_log,
|
||||
* space map representation must be before we compact it on-disk.
|
||||
* Values should be greater than or equal to 100.
|
||||
*/
|
||||
extern int zfs_condense_pct;
|
||||
extern uint_t zfs_condense_pct;
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
SYSCTL_INT(_vfs_zfs, OID_AUTO, condense_pct,
|
||||
SYSCTL_UINT(_vfs_zfs, OID_AUTO, condense_pct,
|
||||
CTLFLAG_RWTUN, &zfs_condense_pct, 0,
|
||||
"Condense on-disk spacemap when it is more than this many percents"
|
||||
" of in-memory counterpart");
|
||||
/* END CSTYLED */
|
||||
|
||||
extern int zfs_remove_max_segment;
|
||||
extern uint_t zfs_remove_max_segment;
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
SYSCTL_INT(_vfs_zfs, OID_AUTO, remove_max_segment,
|
||||
SYSCTL_UINT(_vfs_zfs, OID_AUTO, remove_max_segment,
|
||||
CTLFLAG_RWTUN, &zfs_remove_max_segment, 0,
|
||||
"Largest contiguous segment ZFS will attempt to allocate when removing"
|
||||
" a device");
|
||||
@ -561,10 +561,10 @@ SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, df_alloc_threshold,
|
||||
* Once the space map's free space drops below this level we dynamically
|
||||
* switch to using best-fit allocations.
|
||||
*/
|
||||
extern int metaslab_df_free_pct;
|
||||
extern uint_t metaslab_df_free_pct;
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, df_free_pct,
|
||||
SYSCTL_UINT(_vfs_zfs_metaslab, OID_AUTO, df_free_pct,
|
||||
CTLFLAG_RWTUN, &metaslab_df_free_pct, 0,
|
||||
"The minimum free space, in percent, which must be available in a"
|
||||
" space map to continue allocations in a first-fit fashion");
|
||||
@ -584,10 +584,10 @@ SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, load_pct,
|
||||
/*
|
||||
* Max number of metaslabs per group to preload.
|
||||
*/
|
||||
extern int metaslab_preload_limit;
|
||||
extern uint_t metaslab_preload_limit;
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, preload_limit,
|
||||
SYSCTL_UINT(_vfs_zfs_metaslab, OID_AUTO, preload_limit,
|
||||
CTLFLAG_RWTUN, &metaslab_preload_limit, 0,
|
||||
"Max number of metaslabs per group to preload");
|
||||
/* END CSTYLED */
|
||||
@ -852,7 +852,7 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, validate_skip,
|
||||
|
||||
/* vdev_queue.c */
|
||||
|
||||
extern uint32_t zfs_vdev_max_active;
|
||||
extern uint_t zfs_vdev_max_active;
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
SYSCTL_UINT(_vfs_zfs, OID_AUTO, top_maxinflight,
|
||||
@ -861,10 +861,10 @@ SYSCTL_UINT(_vfs_zfs, OID_AUTO, top_maxinflight,
|
||||
" (LEGACY)");
|
||||
/* END CSTYLED */
|
||||
|
||||
extern int zfs_vdev_def_queue_depth;
|
||||
extern uint_t zfs_vdev_def_queue_depth;
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
SYSCTL_INT(_vfs_zfs_vdev, OID_AUTO, def_queue_depth,
|
||||
SYSCTL_UINT(_vfs_zfs_vdev, OID_AUTO, def_queue_depth,
|
||||
CTLFLAG_RWTUN, &zfs_vdev_def_queue_depth, 0,
|
||||
"Default queue depth for each allocator");
|
||||
/* END CSTYLED */
|
||||
|
@ -527,7 +527,7 @@ zfs_acl_valid_ace_type(uint_t type, uint_t flags)
|
||||
entry_type == ACE_EVERYONE || entry_type == 0 ||
|
||||
entry_type == ACE_IDENTIFIER_GROUP);
|
||||
default:
|
||||
if (type >= MIN_ACE_TYPE && type <= MAX_ACE_TYPE)
|
||||
if (type <= MAX_ACE_TYPE)
|
||||
return (B_TRUE);
|
||||
}
|
||||
return (B_FALSE);
|
||||
|
@ -29,14 +29,14 @@
|
||||
typedef struct zfs_dbgmsg {
|
||||
list_node_t zdm_node;
|
||||
time_t zdm_timestamp;
|
||||
int zdm_size;
|
||||
uint_t zdm_size;
|
||||
char zdm_msg[1]; /* variable length allocation */
|
||||
} zfs_dbgmsg_t;
|
||||
|
||||
static list_t zfs_dbgmsgs;
|
||||
static int zfs_dbgmsg_size = 0;
|
||||
static uint_t zfs_dbgmsg_size = 0;
|
||||
static kmutex_t zfs_dbgmsgs_lock;
|
||||
int zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
|
||||
uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
|
||||
static kstat_t *zfs_dbgmsg_kstat;
|
||||
|
||||
/*
|
||||
@ -88,10 +88,10 @@ zfs_dbgmsg_addr(kstat_t *ksp, loff_t n)
|
||||
}
|
||||
|
||||
static void
|
||||
zfs_dbgmsg_purge(int max_size)
|
||||
zfs_dbgmsg_purge(uint_t max_size)
|
||||
{
|
||||
zfs_dbgmsg_t *zdm;
|
||||
int size;
|
||||
uint_t size;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zfs_dbgmsgs_lock));
|
||||
|
||||
@ -155,7 +155,7 @@ void
|
||||
__zfs_dbgmsg(char *buf)
|
||||
{
|
||||
zfs_dbgmsg_t *zdm;
|
||||
int size;
|
||||
uint_t size;
|
||||
|
||||
DTRACE_PROBE1(zfs__dbgmsg, char *, buf);
|
||||
|
||||
@ -168,7 +168,7 @@ __zfs_dbgmsg(char *buf)
|
||||
mutex_enter(&zfs_dbgmsgs_lock);
|
||||
list_insert_tail(&zfs_dbgmsgs, zdm);
|
||||
zfs_dbgmsg_size += size;
|
||||
zfs_dbgmsg_purge(MAX(zfs_dbgmsg_maxsize, 0));
|
||||
zfs_dbgmsg_purge(zfs_dbgmsg_maxsize);
|
||||
mutex_exit(&zfs_dbgmsgs_lock);
|
||||
}
|
||||
|
||||
@ -248,5 +248,5 @@ zfs_dbgmsg_print(const char *tag)
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, dbgmsg_enable, INT, ZMOD_RW,
|
||||
"Enable ZFS debug message log");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, dbgmsg_maxsize, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, dbgmsg_maxsize, UINT, ZMOD_RW,
|
||||
"Maximum ZFS debug log size");
|
||||
|
@ -1272,8 +1272,7 @@ getpoolname(const char *osname, char *poolname)
|
||||
} else {
|
||||
if (p - osname >= MAXNAMELEN)
|
||||
return (ENAMETOOLONG);
|
||||
(void) strncpy(poolname, osname, p - osname);
|
||||
poolname[p - osname] = '\0';
|
||||
(void) strlcpy(poolname, osname, p - osname + 1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ spl_dumpstack(void)
|
||||
}
|
||||
EXPORT_SYMBOL(spl_dumpstack);
|
||||
|
||||
int
|
||||
void
|
||||
spl_panic(const char *file, const char *func, int line, const char *fmt, ...)
|
||||
{
|
||||
const char *newfile;
|
||||
@ -75,7 +75,6 @@ spl_panic(const char *file, const char *func, int line, const char *fmt, ...)
|
||||
schedule();
|
||||
|
||||
/* Unreachable */
|
||||
return (1);
|
||||
}
|
||||
EXPORT_SYMBOL(spl_panic);
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <linux/mod_compat.h>
|
||||
#include <sys/cred.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/misc.h>
|
||||
|
||||
unsigned long spl_hostid = 0;
|
||||
EXPORT_SYMBOL(spl_hostid);
|
||||
@ -517,6 +518,38 @@ ddi_copyin(const void *from, void *to, size_t len, int flags)
|
||||
}
|
||||
EXPORT_SYMBOL(ddi_copyin);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* during device hotplug to identify the vdev.
|
||||
*/
|
||||
void
|
||||
spl_signal_kobj_evt(struct block_device *bdev)
|
||||
{
|
||||
#if defined(HAVE_BDEV_KOBJ) || defined(HAVE_PART_TO_DEV)
|
||||
#ifdef HAVE_BDEV_KOBJ
|
||||
struct kobject *disk_kobj = bdev_kobj(bdev);
|
||||
#else
|
||||
struct kobject *disk_kobj = &part_to_dev(bdev->bd_part)->kobj;
|
||||
#endif
|
||||
if (disk_kobj) {
|
||||
int ret = kobject_uevent(disk_kobj, KOBJ_CHANGE);
|
||||
if (ret) {
|
||||
pr_warn("ZFS: Sending event '%d' to kobject: '%s'"
|
||||
" (%p): failed(ret:%d)\n", KOBJ_CHANGE,
|
||||
kobject_name(disk_kobj), disk_kobj, ret);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* This is encountered if neither bdev_kobj() nor part_to_dev() is available
|
||||
* in the kernel - likely due to an API change that needs to be chased down.
|
||||
*/
|
||||
#error "Unsupported kernel: unable to get struct kobj from bdev"
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(spl_signal_kobj_evt);
|
||||
|
||||
int
|
||||
ddi_copyout(const void *from, void *to, size_t len, int flags)
|
||||
{
|
||||
|
@ -706,7 +706,7 @@ spl_kmem_cache_create(const char *name, size_t size, size_t align,
|
||||
kfree(skc);
|
||||
return (NULL);
|
||||
}
|
||||
strncpy(skc->skc_name, name, skc->skc_name_size);
|
||||
strlcpy(skc->skc_name, name, skc->skc_name_size);
|
||||
|
||||
skc->skc_ctor = ctor;
|
||||
skc->skc_dtor = dtor;
|
||||
|
@ -390,7 +390,7 @@ kstat_create_module(char *name)
|
||||
|
||||
module = kmem_alloc(sizeof (kstat_module_t), KM_SLEEP);
|
||||
module->ksm_proc = pde;
|
||||
strlcpy(module->ksm_name, name, KSTAT_STRLEN+1);
|
||||
strlcpy(module->ksm_name, name, KSTAT_STRLEN);
|
||||
INIT_LIST_HEAD(&module->ksm_kstat_list);
|
||||
list_add_tail(&module->ksm_module_list, &kstat_module_list);
|
||||
|
||||
@ -479,8 +479,8 @@ kstat_proc_entry_init(kstat_proc_entry_t *kpep, const char *module,
|
||||
kpep->kpe_owner = NULL;
|
||||
kpep->kpe_proc = NULL;
|
||||
INIT_LIST_HEAD(&kpep->kpe_list);
|
||||
strncpy(kpep->kpe_module, module, KSTAT_STRLEN);
|
||||
strncpy(kpep->kpe_name, name, KSTAT_STRLEN);
|
||||
strlcpy(kpep->kpe_module, module, sizeof (kpep->kpe_module));
|
||||
strlcpy(kpep->kpe_name, name, sizeof (kpep->kpe_name));
|
||||
}
|
||||
EXPORT_SYMBOL(kstat_proc_entry_init);
|
||||
|
||||
@ -514,7 +514,7 @@ __kstat_create(const char *ks_module, int ks_instance, const char *ks_name,
|
||||
ksp->ks_crtime = gethrtime();
|
||||
ksp->ks_snaptime = ksp->ks_crtime;
|
||||
ksp->ks_instance = ks_instance;
|
||||
strncpy(ksp->ks_class, ks_class, KSTAT_STRLEN);
|
||||
strlcpy(ksp->ks_class, ks_class, sizeof (ksp->ks_class));
|
||||
ksp->ks_type = ks_type;
|
||||
ksp->ks_flags = ks_flags;
|
||||
ksp->ks_update = kstat_default_update;
|
||||
|
@ -46,8 +46,10 @@ module_param(spl_taskq_thread_priority, int, 0644);
|
||||
MODULE_PARM_DESC(spl_taskq_thread_priority,
|
||||
"Allow non-default priority for taskq threads");
|
||||
|
||||
static int spl_taskq_thread_sequential = 4;
|
||||
module_param(spl_taskq_thread_sequential, int, 0644);
|
||||
static uint_t spl_taskq_thread_sequential = 4;
|
||||
/* BEGIN CSTYLED */
|
||||
module_param(spl_taskq_thread_sequential, uint, 0644);
|
||||
/* END CSTYLED */
|
||||
MODULE_PARM_DESC(spl_taskq_thread_sequential,
|
||||
"Create new taskq threads after N sequential tasks");
|
||||
|
||||
|
@ -92,7 +92,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
strncpy(tp->tp_name, name, tp->tp_name_size);
|
||||
strlcpy(tp->tp_name, name, tp->tp_name_size);
|
||||
|
||||
/*
|
||||
* Strip trailing "_thread" from passed name which will be the func
|
||||
|
@ -203,8 +203,7 @@ zone_dataset_attach(cred_t *cred, const char *dataset, int userns_fd)
|
||||
|
||||
zd = kmem_alloc(sizeof (zone_dataset_t) + dsnamelen + 1, KM_SLEEP);
|
||||
zd->zd_dsnamelen = dsnamelen;
|
||||
strncpy(zd->zd_dsname, dataset, dsnamelen);
|
||||
zd->zd_dsname[dsnamelen] = '\0';
|
||||
strlcpy(zd->zd_dsname, dataset, dsnamelen + 1);
|
||||
INIT_LIST_HEAD(&zd->zd_list);
|
||||
list_add_tail(&zd->zd_list, &zds->zds_datasets);
|
||||
|
||||
|
@ -513,7 +513,7 @@ arc_prune_task(void *ptr)
|
||||
* for releasing it once the registered arc_prune_func_t has completed.
|
||||
*/
|
||||
void
|
||||
arc_prune_async(int64_t adjust)
|
||||
arc_prune_async(uint64_t adjust)
|
||||
{
|
||||
arc_prune_t *ap;
|
||||
|
||||
|
@ -179,6 +179,18 @@ vdev_disk_error(zio_t *zio)
|
||||
zio->io_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
vdev_disk_kobj_evt_post(vdev_t *v)
|
||||
{
|
||||
vdev_disk_t *vd = v->vdev_tsd;
|
||||
if (vd && vd->vd_bdev) {
|
||||
spl_signal_kobj_evt(vd->vd_bdev);
|
||||
} else {
|
||||
vdev_dbgmsg(v, "vdev_disk_t is NULL for VDEV:%s\n",
|
||||
v->vdev_path);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
||||
uint64_t *logical_ashift, uint64_t *physical_ashift)
|
||||
@ -290,6 +302,13 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
|
||||
bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL,
|
||||
zfs_vdev_holder);
|
||||
if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
|
||||
/*
|
||||
* There is no point of waiting since device is removed
|
||||
* explicitly
|
||||
*/
|
||||
if (v->vdev_removed)
|
||||
break;
|
||||
|
||||
schedule_timeout(MSEC_TO_TICK(10));
|
||||
} else if (unlikely(PTR_ERR(bdev) == -ERESTARTSYS)) {
|
||||
timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms * 10);
|
||||
@ -901,7 +920,7 @@ vdev_disk_io_done(zio_t *zio)
|
||||
vdev_t *v = zio->io_vd;
|
||||
vdev_disk_t *vd = v->vdev_tsd;
|
||||
|
||||
if (zfs_check_media_change(vd->vd_bdev)) {
|
||||
if (!zfs_check_disk_status(vd->vd_bdev)) {
|
||||
invalidate_bdev(vd->vd_bdev);
|
||||
v->vdev_remove_wanted = B_TRUE;
|
||||
spa_async_request(zio->io_spa, SPA_ASYNC_REMOVE);
|
||||
@ -957,7 +976,8 @@ vdev_ops_t vdev_disk_ops = {
|
||||
.vdev_op_nparity = NULL,
|
||||
.vdev_op_ndisks = NULL,
|
||||
.vdev_op_type = VDEV_TYPE_DISK, /* name of this vdev type */
|
||||
.vdev_op_leaf = B_TRUE /* leaf vdev */
|
||||
.vdev_op_leaf = B_TRUE, /* leaf vdev */
|
||||
.vdev_op_kobj_evt_post = vdev_disk_kobj_evt_post
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -525,7 +525,7 @@ zfs_acl_valid_ace_type(uint_t type, uint_t flags)
|
||||
entry_type == ACE_EVERYONE || entry_type == 0 ||
|
||||
entry_type == ACE_IDENTIFIER_GROUP);
|
||||
default:
|
||||
if (type >= MIN_ACE_TYPE && type <= MAX_ACE_TYPE)
|
||||
if (type <= MAX_ACE_TYPE)
|
||||
return (B_TRUE);
|
||||
}
|
||||
return (B_FALSE);
|
||||
|
@ -29,13 +29,13 @@
|
||||
typedef struct zfs_dbgmsg {
|
||||
procfs_list_node_t zdm_node;
|
||||
uint64_t zdm_timestamp;
|
||||
int zdm_size;
|
||||
uint_t zdm_size;
|
||||
char zdm_msg[1]; /* variable length allocation */
|
||||
} zfs_dbgmsg_t;
|
||||
|
||||
static procfs_list_t zfs_dbgmsgs;
|
||||
static int zfs_dbgmsg_size = 0;
|
||||
int zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
|
||||
static uint_t zfs_dbgmsg_size = 0;
|
||||
uint_t zfs_dbgmsg_maxsize = 4<<20; /* 4MB */
|
||||
|
||||
/*
|
||||
* Internal ZFS debug messages are enabled by default.
|
||||
@ -68,14 +68,14 @@ zfs_dbgmsg_show(struct seq_file *f, void *p)
|
||||
}
|
||||
|
||||
static void
|
||||
zfs_dbgmsg_purge(int max_size)
|
||||
zfs_dbgmsg_purge(uint_t max_size)
|
||||
{
|
||||
while (zfs_dbgmsg_size > max_size) {
|
||||
zfs_dbgmsg_t *zdm = list_remove_head(&zfs_dbgmsgs.pl_list);
|
||||
if (zdm == NULL)
|
||||
return;
|
||||
|
||||
int size = zdm->zdm_size;
|
||||
uint_t size = zdm->zdm_size;
|
||||
kmem_free(zdm, size);
|
||||
zfs_dbgmsg_size -= size;
|
||||
}
|
||||
@ -135,7 +135,7 @@ __set_error(const char *file, const char *func, int line, int err)
|
||||
void
|
||||
__zfs_dbgmsg(char *buf)
|
||||
{
|
||||
int size = sizeof (zfs_dbgmsg_t) + strlen(buf);
|
||||
uint_t size = sizeof (zfs_dbgmsg_t) + strlen(buf);
|
||||
zfs_dbgmsg_t *zdm = kmem_zalloc(size, KM_SLEEP);
|
||||
zdm->zdm_size = size;
|
||||
zdm->zdm_timestamp = gethrestime_sec();
|
||||
@ -144,7 +144,7 @@ __zfs_dbgmsg(char *buf)
|
||||
mutex_enter(&zfs_dbgmsgs.pl_lock);
|
||||
procfs_list_add(&zfs_dbgmsgs, zdm);
|
||||
zfs_dbgmsg_size += size;
|
||||
zfs_dbgmsg_purge(MAX(zfs_dbgmsg_maxsize, 0));
|
||||
zfs_dbgmsg_purge(zfs_dbgmsg_maxsize);
|
||||
mutex_exit(&zfs_dbgmsgs.pl_lock);
|
||||
}
|
||||
|
||||
@ -252,6 +252,8 @@ zfs_dbgmsg_print(const char *tag)
|
||||
module_param(zfs_dbgmsg_enable, int, 0644);
|
||||
MODULE_PARM_DESC(zfs_dbgmsg_enable, "Enable ZFS debug message log");
|
||||
|
||||
module_param(zfs_dbgmsg_maxsize, int, 0644);
|
||||
/* BEGIN CSTYLED */
|
||||
module_param(zfs_dbgmsg_maxsize, uint, 0644);
|
||||
/* END CSTYLED */
|
||||
MODULE_PARM_DESC(zfs_dbgmsg_maxsize, "Maximum ZFS debug log size");
|
||||
#endif
|
||||
|
@ -1891,6 +1891,9 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key,
|
||||
crypto_ctx_template_t tmpl;
|
||||
uint8_t *authbuf = NULL;
|
||||
|
||||
memset(&puio, 0, sizeof (puio));
|
||||
memset(&cuio, 0, sizeof (cuio));
|
||||
|
||||
/*
|
||||
* If the needed key is the current one, just use it. Otherwise we
|
||||
* need to generate a temporary one from the given salt + master key.
|
||||
@ -1950,9 +1953,6 @@ zio_do_crypt_data(boolean_t encrypt, zio_crypt_key_t *key,
|
||||
/* If the hardware implementation fails fall back to software */
|
||||
}
|
||||
|
||||
memset(&puio, 0, sizeof (puio));
|
||||
memset(&cuio, 0, sizeof (cuio));
|
||||
|
||||
/* create uios for encryption */
|
||||
ret = zio_crypt_init_uios(encrypt, key->zk_version, ot, plainbuf,
|
||||
cipherbuf, datalen, byteswap, mac, &puio, &cuio, &enc_len,
|
||||
|
@ -208,7 +208,7 @@ zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
|
||||
return (!!dentry->d_inode);
|
||||
}
|
||||
|
||||
static const dentry_operations_t zpl_dops_snapdirs = {
|
||||
static dentry_operations_t zpl_dops_snapdirs = {
|
||||
/*
|
||||
* Auto mounting of snapshots is only supported for 2.6.37 and
|
||||
* newer kernels. Prior to this kernel the ops->follow_link()
|
||||
|
@ -1433,7 +1433,7 @@ zvol_os_create_minor(const char *name)
|
||||
* Prefetching the blocks commonly scanned by blkid(8) will speed
|
||||
* up this process.
|
||||
*/
|
||||
len = MIN(MAX(zvol_prefetch_bytes, 0), SPA_MAXBLOCKSIZE);
|
||||
len = MIN(zvol_prefetch_bytes, SPA_MAXBLOCKSIZE);
|
||||
if (len > 0) {
|
||||
dmu_prefetch(os, ZVOL_OBJ, 0, 0, len, ZIO_PRIORITY_SYNC_READ);
|
||||
dmu_prefetch(os, ZVOL_OBJ, 0, volsize - len, len,
|
||||
|
@ -354,7 +354,7 @@ static list_t arc_evict_waiters;
|
||||
* can still happen, even during the potentially long time that arc_size is
|
||||
* more than arc_c.
|
||||
*/
|
||||
static int zfs_arc_eviction_pct = 200;
|
||||
static uint_t zfs_arc_eviction_pct = 200;
|
||||
|
||||
/*
|
||||
* The number of headers to evict in arc_evict_state_impl() before
|
||||
@ -363,10 +363,10 @@ static int zfs_arc_eviction_pct = 200;
|
||||
* oldest header in the arc state), but comes with higher overhead
|
||||
* (i.e. more invocations of arc_evict_state_impl()).
|
||||
*/
|
||||
static int zfs_arc_evict_batch_limit = 10;
|
||||
static uint_t zfs_arc_evict_batch_limit = 10;
|
||||
|
||||
/* number of seconds before growing cache again */
|
||||
int arc_grow_retry = 5;
|
||||
uint_t arc_grow_retry = 5;
|
||||
|
||||
/*
|
||||
* Minimum time between calls to arc_kmem_reap_soon().
|
||||
@ -377,10 +377,10 @@ static const int arc_kmem_cache_reap_retry_ms = 1000;
|
||||
static int zfs_arc_overflow_shift = 8;
|
||||
|
||||
/* shift of arc_c for calculating both min and max arc_p */
|
||||
static int arc_p_min_shift = 4;
|
||||
static uint_t arc_p_min_shift = 4;
|
||||
|
||||
/* log2(fraction of arc to reclaim) */
|
||||
int arc_shrink_shift = 7;
|
||||
uint_t arc_shrink_shift = 7;
|
||||
|
||||
/* percent of pagecache to reclaim arc to */
|
||||
#ifdef _KERNEL
|
||||
@ -396,20 +396,20 @@ uint_t zfs_arc_pc_percent = 0;
|
||||
* This must be less than arc_shrink_shift, so that when we shrink the ARC,
|
||||
* we will still not allow it to grow.
|
||||
*/
|
||||
int arc_no_grow_shift = 5;
|
||||
uint_t arc_no_grow_shift = 5;
|
||||
|
||||
|
||||
/*
|
||||
* minimum lifespan of a prefetch block in clock ticks
|
||||
* (initialized in arc_init())
|
||||
*/
|
||||
static int arc_min_prefetch_ms;
|
||||
static int arc_min_prescient_prefetch_ms;
|
||||
static uint_t arc_min_prefetch_ms;
|
||||
static uint_t arc_min_prescient_prefetch_ms;
|
||||
|
||||
/*
|
||||
* If this percent of memory is free, don't throttle.
|
||||
*/
|
||||
int arc_lotsfree_percent = 10;
|
||||
uint_t arc_lotsfree_percent = 10;
|
||||
|
||||
/*
|
||||
* The arc has filled available memory and has now warmed up.
|
||||
@ -425,10 +425,10 @@ 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;
|
||||
static int zfs_arc_grow_retry = 0;
|
||||
static int zfs_arc_shrink_shift = 0;
|
||||
static int zfs_arc_p_min_shift = 0;
|
||||
int zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
|
||||
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;
|
||||
uint_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
|
||||
|
||||
/*
|
||||
* ARC dirty data constraints for arc_tempreserve_space() throttle:
|
||||
@ -460,13 +460,13 @@ static unsigned long zfs_arc_dnode_limit_percent = 10;
|
||||
* These tunables are Linux-specific
|
||||
*/
|
||||
static unsigned long zfs_arc_sys_free = 0;
|
||||
static int zfs_arc_min_prefetch_ms = 0;
|
||||
static int zfs_arc_min_prescient_prefetch_ms = 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;
|
||||
static int zfs_arc_meta_prune = 10000;
|
||||
static int zfs_arc_meta_strategy = ARC_STRATEGY_META_BALANCED;
|
||||
static int zfs_arc_meta_adjust_restarts = 4096;
|
||||
static int zfs_arc_lotsfree_percent = 10;
|
||||
static uint_t zfs_arc_meta_prune = 10000;
|
||||
static uint_t zfs_arc_meta_strategy = ARC_STRATEGY_META_BALANCED;
|
||||
static uint_t zfs_arc_meta_adjust_restarts = 4096;
|
||||
static uint_t zfs_arc_lotsfree_percent = 10;
|
||||
|
||||
/*
|
||||
* Number of arc_prune threads
|
||||
@ -790,7 +790,7 @@ unsigned long 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 */
|
||||
static int l2arc_meta_percent = 33; /* limit on headers size */
|
||||
static uint_t l2arc_meta_percent = 33; /* limit on headers size */
|
||||
|
||||
/*
|
||||
* L2ARC Internals
|
||||
@ -3898,7 +3898,7 @@ arc_evict_hdr(arc_buf_hdr_t *hdr, kmutex_t *hash_lock, uint64_t *real_evicted)
|
||||
{
|
||||
arc_state_t *evicted_state, *state;
|
||||
int64_t bytes_evicted = 0;
|
||||
int min_lifetime = HDR_PRESCIENT_PREFETCH(hdr) ?
|
||||
uint_t min_lifetime = HDR_PRESCIENT_PREFETCH(hdr) ?
|
||||
arc_min_prescient_prefetch_ms : arc_min_prefetch_ms;
|
||||
|
||||
ASSERT(MUTEX_HELD(hash_lock));
|
||||
@ -4053,7 +4053,7 @@ arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
|
||||
uint64_t bytes_evicted = 0, real_evicted = 0;
|
||||
arc_buf_hdr_t *hdr;
|
||||
kmutex_t *hash_lock;
|
||||
int evict_count = zfs_arc_evict_batch_limit;
|
||||
uint_t evict_count = zfs_arc_evict_batch_limit;
|
||||
|
||||
ASSERT3P(marker, !=, NULL);
|
||||
|
||||
@ -4061,7 +4061,7 @@ arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
|
||||
|
||||
for (hdr = multilist_sublist_prev(mls, marker); likely(hdr != NULL);
|
||||
hdr = multilist_sublist_prev(mls, marker)) {
|
||||
if ((evict_count <= 0) || (bytes_evicted >= bytes))
|
||||
if ((evict_count == 0) || (bytes_evicted >= bytes))
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -4404,10 +4404,10 @@ arc_evict_impl(arc_state_t *state, uint64_t spa, int64_t bytes,
|
||||
static uint64_t
|
||||
arc_evict_meta_balanced(uint64_t meta_used)
|
||||
{
|
||||
int64_t delta, prune = 0, adjustmnt;
|
||||
uint64_t total_evicted = 0;
|
||||
int64_t delta, adjustmnt;
|
||||
uint64_t total_evicted = 0, prune = 0;
|
||||
arc_buf_contents_t type = ARC_BUFC_DATA;
|
||||
int restarts = MAX(zfs_arc_meta_adjust_restarts, 0);
|
||||
uint_t restarts = zfs_arc_meta_adjust_restarts;
|
||||
|
||||
restart:
|
||||
/*
|
||||
@ -7656,15 +7656,14 @@ arc_tuning_update(boolean_t verbose)
|
||||
}
|
||||
|
||||
/* Valid range: 0 - 100 */
|
||||
if ((zfs_arc_lotsfree_percent >= 0) &&
|
||||
(zfs_arc_lotsfree_percent <= 100))
|
||||
if (zfs_arc_lotsfree_percent <= 100)
|
||||
arc_lotsfree_percent = zfs_arc_lotsfree_percent;
|
||||
WARN_IF_TUNING_IGNORED(zfs_arc_lotsfree_percent, arc_lotsfree_percent,
|
||||
verbose);
|
||||
|
||||
/* Valid range: 0 - <all physical memory> */
|
||||
if ((zfs_arc_sys_free) && (zfs_arc_sys_free != arc_sys_free))
|
||||
arc_sys_free = MIN(MAX(zfs_arc_sys_free, 0), allmem);
|
||||
arc_sys_free = MIN(zfs_arc_sys_free, allmem);
|
||||
WARN_IF_TUNING_IGNORED(zfs_arc_sys_free, arc_sys_free, verbose);
|
||||
}
|
||||
|
||||
@ -11077,56 +11076,56 @@ 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_long, ZMOD_RW, "Minimum ARC size in bytes");
|
||||
param_get_ulong, ZMOD_RW, "Minimum ARC size in bytes");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, max, param_set_arc_max,
|
||||
param_get_long, ZMOD_RW, "Maximum ARC size in bytes");
|
||||
param_get_ulong, ZMOD_RW, "Maximum ARC size in bytes");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, meta_limit, param_set_arc_long,
|
||||
param_get_long, ZMOD_RW, "Metadata limit for ARC size in bytes");
|
||||
param_get_ulong, 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_long, ZMOD_RW,
|
||||
param_set_arc_long, param_get_ulong, 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_long, ZMOD_RW, "Minimum ARC metadata size in bytes");
|
||||
param_get_ulong, 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");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, meta_adjust_restarts, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, meta_adjust_restarts, UINT, ZMOD_RW,
|
||||
"Limit number of restarts in arc_evict_meta");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, meta_strategy, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, meta_strategy, UINT, ZMOD_RW,
|
||||
"Meta reclaim strategy");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, grow_retry, param_set_arc_int,
|
||||
param_get_int, ZMOD_RW, "Seconds before growing ARC size");
|
||||
param_get_uint, ZMOD_RW, "Seconds before growing ARC size");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, p_dampener_disable, INT, ZMOD_RW,
|
||||
"Disable arc_p adapt dampener");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, shrink_shift, param_set_arc_int,
|
||||
param_get_int, ZMOD_RW, "log2(fraction of ARC to reclaim)");
|
||||
param_get_uint, ZMOD_RW, "log2(fraction of ARC to reclaim)");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, pc_percent, UINT, ZMOD_RW,
|
||||
"Percent of pagecache to reclaim ARC to");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, p_min_shift, param_set_arc_int,
|
||||
param_get_int, ZMOD_RW, "arc_c shift to calc min/max arc_p");
|
||||
param_get_uint, ZMOD_RW, "arc_c shift to calc min/max arc_p");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, average_blocksize, INT, ZMOD_RD,
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, average_blocksize, UINT, ZMOD_RD,
|
||||
"Target average block size");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, compressed_arc_enabled, INT, ZMOD_RW,
|
||||
"Disable compressed ARC buffers");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min_prefetch_ms, param_set_arc_int,
|
||||
param_get_int, ZMOD_RW, "Min life of prefetch block in ms");
|
||||
param_get_uint, ZMOD_RW, "Min life of prefetch block in ms");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, min_prescient_prefetch_ms,
|
||||
param_set_arc_int, param_get_int, ZMOD_RW,
|
||||
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,
|
||||
@ -11159,7 +11158,7 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, feed_again, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, norw, INT, ZMOD_RW,
|
||||
"No reads during writes");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, meta_percent, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, meta_percent, UINT, ZMOD_RW,
|
||||
"Percent of ARC size allowed for L2ARC-only headers");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, rebuild_enabled, INT, ZMOD_RW,
|
||||
@ -11175,25 +11174,25 @@ ZFS_MODULE_PARAM(zfs_l2arc, l2arc_, exclude_special, INT, ZMOD_RW,
|
||||
"Exclude dbufs on special vdevs from being cached to L2ARC if set.");
|
||||
|
||||
ZFS_MODULE_PARAM_CALL(zfs_arc, zfs_arc_, lotsfree_percent, param_set_arc_int,
|
||||
param_get_int, ZMOD_RW, "System free memory I/O throttle in bytes");
|
||||
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_long, ZMOD_RW, "System free memory target size in bytes");
|
||||
param_get_ulong, 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_long, ZMOD_RW, "Minimum bytes of dnodes in ARC");
|
||||
param_get_ulong, 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_long, ZMOD_RW,
|
||||
param_set_arc_long, param_get_ulong, ZMOD_RW,
|
||||
"Percent of ARC meta buffers for dnodes");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, dnode_reduce_percent, ULONG, ZMOD_RW,
|
||||
"Percentage of excess dnodes to try to unpin");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, eviction_pct, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, eviction_pct, UINT, ZMOD_RW,
|
||||
"When full, ARC allocation waits for eviction of this % of alloc size");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, evict_batch_limit, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, evict_batch_limit, UINT, ZMOD_RW,
|
||||
"The number of headers to evict per sublist before moving to the next");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, prune_task_threads, INT, ZMOD_RW,
|
||||
|
@ -99,6 +99,11 @@ typedef struct dbuf_stats {
|
||||
* already created and in the dbuf hash table.
|
||||
*/
|
||||
kstat_named_t hash_insert_race;
|
||||
/*
|
||||
* Number of entries in the hash table dbuf and mutex arrays.
|
||||
*/
|
||||
kstat_named_t hash_table_count;
|
||||
kstat_named_t hash_mutex_count;
|
||||
/*
|
||||
* Statistics about the size of the metadata dbuf cache.
|
||||
*/
|
||||
@ -131,6 +136,8 @@ dbuf_stats_t dbuf_stats = {
|
||||
{ "hash_chains", KSTAT_DATA_UINT64 },
|
||||
{ "hash_chain_max", KSTAT_DATA_UINT64 },
|
||||
{ "hash_insert_race", KSTAT_DATA_UINT64 },
|
||||
{ "hash_table_count", KSTAT_DATA_UINT64 },
|
||||
{ "hash_mutex_count", KSTAT_DATA_UINT64 },
|
||||
{ "metadata_cache_count", KSTAT_DATA_UINT64 },
|
||||
{ "metadata_cache_size_bytes", KSTAT_DATA_UINT64 },
|
||||
{ "metadata_cache_size_bytes_max", KSTAT_DATA_UINT64 },
|
||||
@ -224,8 +231,11 @@ static unsigned long dbuf_cache_max_bytes = ULONG_MAX;
|
||||
static unsigned long dbuf_metadata_cache_max_bytes = ULONG_MAX;
|
||||
|
||||
/* Set the default sizes of the caches to log2 fraction of arc size */
|
||||
static int dbuf_cache_shift = 5;
|
||||
static int dbuf_metadata_cache_shift = 6;
|
||||
static uint_t dbuf_cache_shift = 5;
|
||||
static uint_t dbuf_metadata_cache_shift = 6;
|
||||
|
||||
/* Set the dbuf hash mutex count as log2 shift (dynamic by default) */
|
||||
static uint_t dbuf_mutex_cache_shift = 0;
|
||||
|
||||
static unsigned long dbuf_cache_target_bytes(void);
|
||||
static unsigned long dbuf_metadata_cache_target_bytes(void);
|
||||
@ -339,18 +349,18 @@ dbuf_find(objset_t *os, uint64_t obj, uint8_t level, uint64_t blkid)
|
||||
hv = dbuf_hash(os, obj, level, blkid);
|
||||
idx = hv & h->hash_table_mask;
|
||||
|
||||
rw_enter(DBUF_HASH_RWLOCK(h, idx), RW_READER);
|
||||
mutex_enter(DBUF_HASH_MUTEX(h, idx));
|
||||
for (db = h->hash_table[idx]; db != NULL; db = db->db_hash_next) {
|
||||
if (DBUF_EQUAL(db, os, obj, level, blkid)) {
|
||||
mutex_enter(&db->db_mtx);
|
||||
if (db->db_state != DB_EVICTING) {
|
||||
rw_exit(DBUF_HASH_RWLOCK(h, idx));
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, idx));
|
||||
return (db);
|
||||
}
|
||||
mutex_exit(&db->db_mtx);
|
||||
}
|
||||
}
|
||||
rw_exit(DBUF_HASH_RWLOCK(h, idx));
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, idx));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -393,13 +403,13 @@ dbuf_hash_insert(dmu_buf_impl_t *db)
|
||||
hv = dbuf_hash(os, obj, level, blkid);
|
||||
idx = hv & h->hash_table_mask;
|
||||
|
||||
rw_enter(DBUF_HASH_RWLOCK(h, idx), RW_WRITER);
|
||||
mutex_enter(DBUF_HASH_MUTEX(h, idx));
|
||||
for (dbf = h->hash_table[idx], i = 0; dbf != NULL;
|
||||
dbf = dbf->db_hash_next, i++) {
|
||||
if (DBUF_EQUAL(dbf, os, obj, level, blkid)) {
|
||||
mutex_enter(&dbf->db_mtx);
|
||||
if (dbf->db_state != DB_EVICTING) {
|
||||
rw_exit(DBUF_HASH_RWLOCK(h, idx));
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, idx));
|
||||
return (dbf);
|
||||
}
|
||||
mutex_exit(&dbf->db_mtx);
|
||||
@ -417,7 +427,7 @@ dbuf_hash_insert(dmu_buf_impl_t *db)
|
||||
mutex_enter(&db->db_mtx);
|
||||
db->db_hash_next = h->hash_table[idx];
|
||||
h->hash_table[idx] = db;
|
||||
rw_exit(DBUF_HASH_RWLOCK(h, idx));
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, idx));
|
||||
uint64_t he = atomic_inc_64_nv(&dbuf_stats.hash_elements.value.ui64);
|
||||
DBUF_STAT_MAX(hash_elements_max, he);
|
||||
|
||||
@ -474,13 +484,13 @@ dbuf_hash_remove(dmu_buf_impl_t *db)
|
||||
|
||||
/*
|
||||
* We mustn't hold db_mtx to maintain lock ordering:
|
||||
* DBUF_HASH_RWLOCK > db_mtx.
|
||||
* DBUF_HASH_MUTEX > db_mtx.
|
||||
*/
|
||||
ASSERT(zfs_refcount_is_zero(&db->db_holds));
|
||||
ASSERT(db->db_state == DB_EVICTING);
|
||||
ASSERT(!MUTEX_HELD(&db->db_mtx));
|
||||
|
||||
rw_enter(DBUF_HASH_RWLOCK(h, idx), RW_WRITER);
|
||||
mutex_enter(DBUF_HASH_MUTEX(h, idx));
|
||||
dbp = &h->hash_table[idx];
|
||||
while ((dbf = *dbp) != db) {
|
||||
dbp = &dbf->db_hash_next;
|
||||
@ -491,7 +501,7 @@ dbuf_hash_remove(dmu_buf_impl_t *db)
|
||||
if (h->hash_table[idx] &&
|
||||
h->hash_table[idx]->db_hash_next == NULL)
|
||||
DBUF_STAT_BUMPDOWN(hash_chains);
|
||||
rw_exit(DBUF_HASH_RWLOCK(h, idx));
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, idx));
|
||||
atomic_dec_64(&dbuf_stats.hash_elements.value.ui64);
|
||||
}
|
||||
|
||||
@ -838,6 +848,7 @@ static int
|
||||
dbuf_kstat_update(kstat_t *ksp, int rw)
|
||||
{
|
||||
dbuf_stats_t *ds = ksp->ks_data;
|
||||
dbuf_hash_table_t *h = &dbuf_hash_table;
|
||||
|
||||
if (rw == KSTAT_WRITE)
|
||||
return (SET_ERROR(EACCES));
|
||||
@ -867,6 +878,8 @@ dbuf_kstat_update(kstat_t *ksp, int rw)
|
||||
wmsum_value(&dbuf_sums.hash_chains);
|
||||
ds->hash_insert_race.value.ui64 =
|
||||
wmsum_value(&dbuf_sums.hash_insert_race);
|
||||
ds->hash_table_count.value.ui64 = h->hash_table_mask + 1;
|
||||
ds->hash_mutex_count.value.ui64 = h->hash_mutex_mask + 1;
|
||||
ds->metadata_cache_count.value.ui64 =
|
||||
wmsum_value(&dbuf_sums.metadata_cache_count);
|
||||
ds->metadata_cache_size_bytes.value.ui64 = zfs_refcount_count(
|
||||
@ -879,9 +892,8 @@ dbuf_kstat_update(kstat_t *ksp, int rw)
|
||||
void
|
||||
dbuf_init(void)
|
||||
{
|
||||
uint64_t hsize = 1ULL << 16;
|
||||
uint64_t hmsize, hsize = 1ULL << 16;
|
||||
dbuf_hash_table_t *h = &dbuf_hash_table;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The hash table is big enough to fill one eighth of physical memory
|
||||
@ -892,30 +904,43 @@ dbuf_init(void)
|
||||
while (hsize * zfs_arc_average_blocksize < arc_all_memory() / 8)
|
||||
hsize <<= 1;
|
||||
|
||||
retry:
|
||||
h->hash_table_mask = hsize - 1;
|
||||
#if defined(_KERNEL)
|
||||
h->hash_table = NULL;
|
||||
while (h->hash_table == NULL) {
|
||||
h->hash_table_mask = hsize - 1;
|
||||
|
||||
h->hash_table = vmem_zalloc(hsize * sizeof (void *), KM_SLEEP);
|
||||
if (h->hash_table == NULL)
|
||||
hsize >>= 1;
|
||||
|
||||
ASSERT3U(hsize, >=, 1ULL << 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Large allocations which do not require contiguous pages
|
||||
* should be using vmem_alloc() in the linux kernel
|
||||
* The hash table buckets are protected by an array of mutexes where
|
||||
* each mutex is reponsible for protecting 128 buckets. A minimum
|
||||
* array size of 8192 is targeted to avoid contention.
|
||||
*/
|
||||
h->hash_table = vmem_zalloc(hsize * sizeof (void *), KM_SLEEP);
|
||||
#else
|
||||
h->hash_table = kmem_zalloc(hsize * sizeof (void *), KM_NOSLEEP);
|
||||
#endif
|
||||
if (h->hash_table == NULL) {
|
||||
/* XXX - we should really return an error instead of assert */
|
||||
ASSERT(hsize > (1ULL << 10));
|
||||
hsize >>= 1;
|
||||
goto retry;
|
||||
if (dbuf_mutex_cache_shift == 0)
|
||||
hmsize = MAX(hsize >> 7, 1ULL << 13);
|
||||
else
|
||||
hmsize = 1ULL << MIN(dbuf_mutex_cache_shift, 24);
|
||||
|
||||
h->hash_mutexes = NULL;
|
||||
while (h->hash_mutexes == NULL) {
|
||||
h->hash_mutex_mask = hmsize - 1;
|
||||
|
||||
h->hash_mutexes = vmem_zalloc(hmsize * sizeof (kmutex_t),
|
||||
KM_SLEEP);
|
||||
if (h->hash_mutexes == NULL)
|
||||
hmsize >>= 1;
|
||||
}
|
||||
|
||||
dbuf_kmem_cache = kmem_cache_create("dmu_buf_impl_t",
|
||||
sizeof (dmu_buf_impl_t),
|
||||
0, dbuf_cons, dbuf_dest, NULL, NULL, NULL, 0);
|
||||
|
||||
for (i = 0; i < DBUF_RWLOCKS; i++)
|
||||
rw_init(&h->hash_rwlocks[i], NULL, RW_DEFAULT, NULL);
|
||||
for (int i = 0; i < hmsize; i++)
|
||||
mutex_init(&h->hash_mutexes[i], NULL, MUTEX_DEFAULT, NULL);
|
||||
|
||||
dbuf_stats_init(h);
|
||||
|
||||
@ -941,7 +966,7 @@ dbuf_init(void)
|
||||
|
||||
wmsum_init(&dbuf_sums.cache_count, 0);
|
||||
wmsum_init(&dbuf_sums.cache_total_evicts, 0);
|
||||
for (i = 0; i < DN_MAX_LEVELS; i++) {
|
||||
for (int i = 0; i < DN_MAX_LEVELS; i++) {
|
||||
wmsum_init(&dbuf_sums.cache_levels[i], 0);
|
||||
wmsum_init(&dbuf_sums.cache_levels_bytes[i], 0);
|
||||
}
|
||||
@ -957,7 +982,7 @@ dbuf_init(void)
|
||||
KSTAT_TYPE_NAMED, sizeof (dbuf_stats) / sizeof (kstat_named_t),
|
||||
KSTAT_FLAG_VIRTUAL);
|
||||
if (dbuf_ksp != NULL) {
|
||||
for (i = 0; i < DN_MAX_LEVELS; i++) {
|
||||
for (int i = 0; i < DN_MAX_LEVELS; i++) {
|
||||
snprintf(dbuf_stats.cache_levels[i].name,
|
||||
KSTAT_STRLEN, "cache_level_%d", i);
|
||||
dbuf_stats.cache_levels[i].data_type =
|
||||
@ -977,21 +1002,16 @@ void
|
||||
dbuf_fini(void)
|
||||
{
|
||||
dbuf_hash_table_t *h = &dbuf_hash_table;
|
||||
int i;
|
||||
|
||||
dbuf_stats_destroy();
|
||||
|
||||
for (i = 0; i < DBUF_RWLOCKS; i++)
|
||||
rw_destroy(&h->hash_rwlocks[i]);
|
||||
#if defined(_KERNEL)
|
||||
/*
|
||||
* Large allocations which do not require contiguous pages
|
||||
* should be using vmem_free() in the linux kernel
|
||||
*/
|
||||
for (int i = 0; i < (h->hash_mutex_mask + 1); i++)
|
||||
mutex_destroy(&h->hash_mutexes[i]);
|
||||
|
||||
vmem_free(h->hash_table, (h->hash_table_mask + 1) * sizeof (void *));
|
||||
#else
|
||||
kmem_free(h->hash_table, (h->hash_table_mask + 1) * sizeof (void *));
|
||||
#endif
|
||||
vmem_free(h->hash_mutexes, (h->hash_mutex_mask + 1) *
|
||||
sizeof (kmutex_t));
|
||||
|
||||
kmem_cache_destroy(dbuf_kmem_cache);
|
||||
taskq_destroy(dbu_evict_taskq);
|
||||
|
||||
@ -1018,7 +1038,7 @@ dbuf_fini(void)
|
||||
|
||||
wmsum_fini(&dbuf_sums.cache_count);
|
||||
wmsum_fini(&dbuf_sums.cache_total_evicts);
|
||||
for (i = 0; i < DN_MAX_LEVELS; i++) {
|
||||
for (int i = 0; i < DN_MAX_LEVELS; i++) {
|
||||
wmsum_fini(&dbuf_sums.cache_levels[i]);
|
||||
wmsum_fini(&dbuf_sums.cache_levels_bytes[i]);
|
||||
}
|
||||
@ -5112,8 +5132,11 @@ ZFS_MODULE_PARAM(zfs_dbuf_cache, dbuf_cache_, lowater_pct, UINT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_max_bytes, ULONG, ZMOD_RW,
|
||||
"Maximum size in bytes of dbuf metadata cache.");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, cache_shift, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, cache_shift, UINT, ZMOD_RW,
|
||||
"Set size of dbuf cache to log2 fraction of arc size.");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_shift, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, metadata_cache_shift, UINT, ZMOD_RW,
|
||||
"Set size of dbuf metadata cache to log2 fraction of arc size.");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_dbuf, dbuf_, mutex_cache_shift, UINT, ZMOD_RD,
|
||||
"Set size of dbuf cache mutex array as log2 shift.");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user