1b7b97454Sperrin /* 2b7b97454Sperrin * CDDL HEADER START 3b7b97454Sperrin * 4b7b97454Sperrin * The contents of this file are subject to the terms of the 5b7b97454Sperrin * Common Development and Distribution License (the "License"). 6b7b97454Sperrin * You may not use this file except in compliance with the License. 7b7b97454Sperrin * 8b7b97454Sperrin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9b7b97454Sperrin * or http://www.opensolaris.org/os/licensing. 10b7b97454Sperrin * See the License for the specific language governing permissions 11b7b97454Sperrin * and limitations under the License. 12b7b97454Sperrin * 13b7b97454Sperrin * When distributing Covered Code, include this CDDL HEADER in each 14b7b97454Sperrin * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15b7b97454Sperrin * If applicable, add the following below this CDDL HEADER, with the 16b7b97454Sperrin * fields enclosed by brackets "[]" replaced with your own identifying 17b7b97454Sperrin * information: Portions Copyright [yyyy] [name of copyright owner] 18b7b97454Sperrin * 19b7b97454Sperrin * CDDL HEADER END 20b7b97454Sperrin */ 21b7b97454Sperrin /* 22c8ee1847SVictor Latushkin * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23b7b97454Sperrin * Use is subject to license terms. 24b7b97454Sperrin */ 25b7b97454Sperrin 26b7b97454Sperrin /* 27b7b97454Sperrin * This file is intended for functions that ought to be common between user 28b7b97454Sperrin * land (libzfs) and the kernel. When many common routines need to be shared 29b7b97454Sperrin * then a separate file should to be created. 30b7b97454Sperrin */ 31b7b97454Sperrin 32b7b97454Sperrin #if defined(_KERNEL) 33b7b97454Sperrin #include <sys/systm.h> 34468c413aSTim Haley #else 35468c413aSTim Haley #include <string.h> 36b7b97454Sperrin #endif 37b7b97454Sperrin 38b7b97454Sperrin #include <sys/types.h> 39b7b97454Sperrin #include <sys/fs/zfs.h> 40468c413aSTim Haley #include <sys/int_limits.h> 41b7b97454Sperrin #include <sys/nvpair.h> 42*0a586ceaSMark Shellenbaum #include "zfs_comutil.h" 43b7b97454Sperrin 44b7b97454Sperrin /* 45b7b97454Sperrin * Are there allocatable vdevs? 46b7b97454Sperrin */ 47b7b97454Sperrin boolean_t 48b7b97454Sperrin zfs_allocatable_devs(nvlist_t *nv) 49b7b97454Sperrin { 50b7b97454Sperrin uint64_t is_log; 51b7b97454Sperrin uint_t c; 52b7b97454Sperrin nvlist_t **child; 53b7b97454Sperrin uint_t children; 54b7b97454Sperrin 55b7b97454Sperrin if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 56b7b97454Sperrin &child, &children) != 0) { 57b7b97454Sperrin return (B_FALSE); 58b7b97454Sperrin } 59b7b97454Sperrin for (c = 0; c < children; c++) { 60b7b97454Sperrin is_log = 0; 61b7b97454Sperrin (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 62b7b97454Sperrin &is_log); 63b7b97454Sperrin if (!is_log) 64b7b97454Sperrin return (B_TRUE); 65b7b97454Sperrin } 66b7b97454Sperrin return (B_FALSE); 67b7b97454Sperrin } 68468c413aSTim Haley 69468c413aSTim Haley void 70468c413aSTim Haley zpool_get_rewind_policy(nvlist_t *nvl, zpool_rewind_policy_t *zrpp) 71468c413aSTim Haley { 72468c413aSTim Haley nvlist_t *policy; 73468c413aSTim Haley nvpair_t *elem; 74468c413aSTim Haley char *nm; 75468c413aSTim Haley 76468c413aSTim Haley /* Defaults */ 77468c413aSTim Haley zrpp->zrp_request = ZPOOL_NO_REWIND; 78468c413aSTim Haley zrpp->zrp_maxmeta = 0; 79c8ee1847SVictor Latushkin zrpp->zrp_maxdata = UINT64_MAX; 80468c413aSTim Haley zrpp->zrp_txg = UINT64_MAX; 81468c413aSTim Haley 82468c413aSTim Haley if (nvl == NULL) 83468c413aSTim Haley return; 84468c413aSTim Haley 85468c413aSTim Haley elem = NULL; 86468c413aSTim Haley while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 87468c413aSTim Haley nm = nvpair_name(elem); 88468c413aSTim Haley if (strcmp(nm, ZPOOL_REWIND_POLICY) == 0) { 89468c413aSTim Haley if (nvpair_value_nvlist(elem, &policy) == 0) 90468c413aSTim Haley zpool_get_rewind_policy(policy, zrpp); 91468c413aSTim Haley return; 92468c413aSTim Haley } else if (strcmp(nm, ZPOOL_REWIND_REQUEST) == 0) { 93c8ee1847SVictor Latushkin if (nvpair_value_uint32(elem, &zrpp->zrp_request) == 0) 94c8ee1847SVictor Latushkin if (zrpp->zrp_request & ~ZPOOL_REWIND_POLICIES) 95468c413aSTim Haley zrpp->zrp_request = ZPOOL_NO_REWIND; 96468c413aSTim Haley } else if (strcmp(nm, ZPOOL_REWIND_REQUEST_TXG) == 0) { 97468c413aSTim Haley (void) nvpair_value_uint64(elem, &zrpp->zrp_txg); 98468c413aSTim Haley } else if (strcmp(nm, ZPOOL_REWIND_META_THRESH) == 0) { 99c8ee1847SVictor Latushkin (void) nvpair_value_uint64(elem, &zrpp->zrp_maxmeta); 100468c413aSTim Haley } else if (strcmp(nm, ZPOOL_REWIND_DATA_THRESH) == 0) { 101c8ee1847SVictor Latushkin (void) nvpair_value_uint64(elem, &zrpp->zrp_maxdata); 102468c413aSTim Haley } 103468c413aSTim Haley } 104c8ee1847SVictor Latushkin if (zrpp->zrp_request == 0) 105c8ee1847SVictor Latushkin zrpp->zrp_request = ZPOOL_NO_REWIND; 106468c413aSTim Haley } 107*0a586ceaSMark Shellenbaum 108*0a586ceaSMark Shellenbaum typedef struct zfs_version_spa_map { 109*0a586ceaSMark Shellenbaum int version_zpl; 110*0a586ceaSMark Shellenbaum int version_spa; 111*0a586ceaSMark Shellenbaum } zfs_version_spa_map_t; 112*0a586ceaSMark Shellenbaum 113*0a586ceaSMark Shellenbaum /* 114*0a586ceaSMark Shellenbaum * Keep this table in monotonically increasing version number order. 115*0a586ceaSMark Shellenbaum */ 116*0a586ceaSMark Shellenbaum static zfs_version_spa_map_t zfs_version_table[] = { 117*0a586ceaSMark Shellenbaum {ZPL_VERSION_INITIAL, SPA_VERSION_INITIAL}, 118*0a586ceaSMark Shellenbaum {ZPL_VERSION_DIRENT_TYPE, SPA_VERSION_INITIAL}, 119*0a586ceaSMark Shellenbaum {ZPL_VERSION_FUID, SPA_VERSION_FUID}, 120*0a586ceaSMark Shellenbaum {ZPL_VERSION_USERSPACE, SPA_VERSION_USERSPACE}, 121*0a586ceaSMark Shellenbaum {ZPL_VERSION_SA, SPA_VERSION_SA}, 122*0a586ceaSMark Shellenbaum {0, 0} 123*0a586ceaSMark Shellenbaum }; 124*0a586ceaSMark Shellenbaum 125*0a586ceaSMark Shellenbaum /* 126*0a586ceaSMark Shellenbaum * Return the max zpl version for a corresponding spa version 127*0a586ceaSMark Shellenbaum * -1 is returned if no mapping exists. 128*0a586ceaSMark Shellenbaum */ 129*0a586ceaSMark Shellenbaum int 130*0a586ceaSMark Shellenbaum zfs_zpl_version_map(int spa_version) 131*0a586ceaSMark Shellenbaum { 132*0a586ceaSMark Shellenbaum int i; 133*0a586ceaSMark Shellenbaum int version = -1; 134*0a586ceaSMark Shellenbaum 135*0a586ceaSMark Shellenbaum for (i = 0; zfs_version_table[i].version_spa; i++) { 136*0a586ceaSMark Shellenbaum if (spa_version >= zfs_version_table[i].version_spa) 137*0a586ceaSMark Shellenbaum version = zfs_version_table[i].version_zpl; 138*0a586ceaSMark Shellenbaum } 139*0a586ceaSMark Shellenbaum 140*0a586ceaSMark Shellenbaum return (version); 141*0a586ceaSMark Shellenbaum } 142*0a586ceaSMark Shellenbaum 143*0a586ceaSMark Shellenbaum /* 144*0a586ceaSMark Shellenbaum * Return the min spa version for a corresponding spa version 145*0a586ceaSMark Shellenbaum * -1 is returned if no mapping exists. 146*0a586ceaSMark Shellenbaum */ 147*0a586ceaSMark Shellenbaum int 148*0a586ceaSMark Shellenbaum zfs_spa_version_map(int zpl_version) 149*0a586ceaSMark Shellenbaum { 150*0a586ceaSMark Shellenbaum int i; 151*0a586ceaSMark Shellenbaum int version = -1; 152*0a586ceaSMark Shellenbaum 153*0a586ceaSMark Shellenbaum for (i = 0; zfs_version_table[i].version_zpl; i++) { 154*0a586ceaSMark Shellenbaum if (zfs_version_table[i].version_zpl >= zpl_version) 155*0a586ceaSMark Shellenbaum return (zfs_version_table[i].version_spa); 156*0a586ceaSMark Shellenbaum } 157*0a586ceaSMark Shellenbaum 158*0a586ceaSMark Shellenbaum return (version); 159*0a586ceaSMark Shellenbaum } 160