Path: blob/main/sys/contrib/openzfs/module/zcommon/zfs_comutil.c
48383 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.23* Copyright (c) 2012, 2017 by Delphix. All rights reserved.24*/2526/*27* This file is intended for functions that ought to be common between user28* land (libzfs) and the kernel. When many common routines need to be shared29* then a separate file should be created.30*/3132#if !defined(_KERNEL)33#include <string.h>34#endif3536#include <sys/types.h>37#include <sys/fs/zfs.h>38#include <sys/nvpair.h>39#include "zfs_comutil.h"40#include <sys/zfs_ratelimit.h>4142/*43* Are there allocatable vdevs?44*/45boolean_t46zfs_allocatable_devs(nvlist_t *nv)47{48uint64_t is_log;49uint_t c;50nvlist_t **child;51uint_t children;5253if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,54&child, &children) != 0) {55return (B_FALSE);56}57for (c = 0; c < children; c++) {58is_log = 0;59(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,60&is_log);61if (!is_log)62return (B_TRUE);63}64return (B_FALSE);65}6667/*68* Are there special vdevs?69*/70boolean_t71zfs_special_devs(nvlist_t *nv, const char *type)72{73const char *bias;74uint_t c;75nvlist_t **child;76uint_t children;7778if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,79&child, &children) != 0) {80return (B_FALSE);81}82for (c = 0; c < children; c++) {83if (nvlist_lookup_string(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS,84&bias) == 0) {85if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0 ||86strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0) {87if (type == NULL ||88(type != NULL && strcmp(bias, type) == 0))89return (B_TRUE);90}91}92}93return (B_FALSE);94}9596void97zpool_get_load_policy(nvlist_t *nvl, zpool_load_policy_t *zlpp)98{99nvlist_t *policy;100nvpair_t *elem;101const char *nm;102103/* Defaults */104zlpp->zlp_rewind = ZPOOL_NO_REWIND;105zlpp->zlp_maxmeta = 0;106zlpp->zlp_maxdata = UINT64_MAX;107zlpp->zlp_txg = UINT64_MAX;108109if (nvl == NULL)110return;111112elem = NULL;113while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {114nm = nvpair_name(elem);115if (strcmp(nm, ZPOOL_LOAD_POLICY) == 0) {116if (nvpair_value_nvlist(elem, &policy) == 0)117zpool_get_load_policy(policy, zlpp);118return;119} else if (strcmp(nm, ZPOOL_LOAD_REWIND_POLICY) == 0) {120if (nvpair_value_uint32(elem, &zlpp->zlp_rewind) == 0)121if (zlpp->zlp_rewind & ~ZPOOL_REWIND_POLICIES)122zlpp->zlp_rewind = ZPOOL_NO_REWIND;123} else if (strcmp(nm, ZPOOL_LOAD_REQUEST_TXG) == 0) {124(void) nvpair_value_uint64(elem, &zlpp->zlp_txg);125} else if (strcmp(nm, ZPOOL_LOAD_META_THRESH) == 0) {126(void) nvpair_value_uint64(elem, &zlpp->zlp_maxmeta);127} else if (strcmp(nm, ZPOOL_LOAD_DATA_THRESH) == 0) {128(void) nvpair_value_uint64(elem, &zlpp->zlp_maxdata);129}130}131if (zlpp->zlp_rewind == 0)132zlpp->zlp_rewind = ZPOOL_NO_REWIND;133}134135typedef struct zfs_version_spa_map {136int version_zpl;137int version_spa;138} zfs_version_spa_map_t;139140/*141* Keep this table in monotonically increasing version number order.142*/143static zfs_version_spa_map_t zfs_version_table[] = {144{ZPL_VERSION_INITIAL, SPA_VERSION_INITIAL},145{ZPL_VERSION_DIRENT_TYPE, SPA_VERSION_INITIAL},146{ZPL_VERSION_FUID, SPA_VERSION_FUID},147{ZPL_VERSION_USERSPACE, SPA_VERSION_USERSPACE},148{ZPL_VERSION_SA, SPA_VERSION_SA},149{0, 0}150};151152/*153* Return the max zpl version for a corresponding spa version154* -1 is returned if no mapping exists.155*/156int157zfs_zpl_version_map(int spa_version)158{159int version = -1;160161for (int i = 0; zfs_version_table[i].version_spa; i++)162if (spa_version >= zfs_version_table[i].version_spa)163version = zfs_version_table[i].version_zpl;164165return (version);166}167168/*169* Return the min spa version for a corresponding spa version170* -1 is returned if no mapping exists.171*/172int173zfs_spa_version_map(int zpl_version)174{175for (int i = 0; zfs_version_table[i].version_zpl; i++)176if (zfs_version_table[i].version_zpl >= zpl_version)177return (zfs_version_table[i].version_spa);178179return (-1);180}181182/*183* This is the table of legacy internal event names; it should not be modified.184* The internal events are now stored in the history log as strings.185*/186const char *const zfs_history_event_names[ZFS_NUM_LEGACY_HISTORY_EVENTS] = {187"invalid event",188"pool create",189"vdev add",190"pool remove",191"pool destroy",192"pool export",193"pool import",194"vdev attach",195"vdev replace",196"vdev detach",197"vdev online",198"vdev offline",199"vdev upgrade",200"pool clear",201"pool scrub",202"pool property set",203"create",204"clone",205"destroy",206"destroy_begin_sync",207"inherit",208"property set",209"quota set",210"permission update",211"permission remove",212"permission who remove",213"promote",214"receive",215"rename",216"reservation set",217"replay_inc_sync",218"replay_full_sync",219"rollback",220"snapshot",221"filesystem version upgrade",222"refquota set",223"refreservation set",224"pool scrub done",225"user hold",226"user release",227"pool split",228};229230boolean_t231zfs_dataset_name_hidden(const char *name)232{233/*234* Skip over datasets that are not visible in this zone,235* internal datasets (which have a $ in their name), and236* temporary datasets (which have a % in their name).237*/238if (strpbrk(name, "$%") != NULL)239return (B_TRUE);240if (!INGLOBALZONE(curproc) && !zone_dataset_visible(name, NULL))241return (B_TRUE);242return (B_FALSE);243}244245#if defined(_KERNEL)246EXPORT_SYMBOL(zfs_allocatable_devs);247EXPORT_SYMBOL(zfs_special_devs);248EXPORT_SYMBOL(zpool_get_load_policy);249EXPORT_SYMBOL(zfs_zpl_version_map);250EXPORT_SYMBOL(zfs_spa_version_map);251EXPORT_SYMBOL(zfs_history_event_names);252EXPORT_SYMBOL(zfs_dataset_name_hidden);253#endif254255256