15913Sperrin /* 25913Sperrin * CDDL HEADER START 35913Sperrin * 45913Sperrin * The contents of this file are subject to the terms of the 55913Sperrin * Common Development and Distribution License (the "License"). 65913Sperrin * You may not use this file except in compliance with the License. 75913Sperrin * 85913Sperrin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95913Sperrin * or http://www.opensolaris.org/os/licensing. 105913Sperrin * See the License for the specific language governing permissions 115913Sperrin * and limitations under the License. 125913Sperrin * 135913Sperrin * When distributing Covered Code, include this CDDL HEADER in each 145913Sperrin * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155913Sperrin * If applicable, add the following below this CDDL HEADER, with the 165913Sperrin * fields enclosed by brackets "[]" replaced with your own identifying 175913Sperrin * information: Portions Copyright [yyyy] [name of copyright owner] 185913Sperrin * 195913Sperrin * CDDL HEADER END 205913Sperrin */ 215913Sperrin /* 2211727SVictor.Latushkin@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 235913Sperrin * Use is subject to license terms. 245913Sperrin */ 255913Sperrin 265913Sperrin /* 275913Sperrin * This file is intended for functions that ought to be common between user 285913Sperrin * land (libzfs) and the kernel. When many common routines need to be shared 295913Sperrin * then a separate file should to be created. 305913Sperrin */ 315913Sperrin 325913Sperrin #if defined(_KERNEL) 335913Sperrin #include <sys/systm.h> 3410921STim.Haley@Sun.COM #else 3510921STim.Haley@Sun.COM #include <string.h> 365913Sperrin #endif 375913Sperrin 385913Sperrin #include <sys/types.h> 395913Sperrin #include <sys/fs/zfs.h> 4010921STim.Haley@Sun.COM #include <sys/int_limits.h> 415913Sperrin #include <sys/nvpair.h> 42*11935SMark.Shellenbaum@Sun.COM #include "zfs_comutil.h" 435913Sperrin 445913Sperrin /* 455913Sperrin * Are there allocatable vdevs? 465913Sperrin */ 475913Sperrin boolean_t 485913Sperrin zfs_allocatable_devs(nvlist_t *nv) 495913Sperrin { 505913Sperrin uint64_t is_log; 515913Sperrin uint_t c; 525913Sperrin nvlist_t **child; 535913Sperrin uint_t children; 545913Sperrin 555913Sperrin if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 565913Sperrin &child, &children) != 0) { 575913Sperrin return (B_FALSE); 585913Sperrin } 595913Sperrin for (c = 0; c < children; c++) { 605913Sperrin is_log = 0; 615913Sperrin (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 625913Sperrin &is_log); 635913Sperrin if (!is_log) 645913Sperrin return (B_TRUE); 655913Sperrin } 665913Sperrin return (B_FALSE); 675913Sperrin } 6810921STim.Haley@Sun.COM 6910921STim.Haley@Sun.COM void 7010921STim.Haley@Sun.COM zpool_get_rewind_policy(nvlist_t *nvl, zpool_rewind_policy_t *zrpp) 7110921STim.Haley@Sun.COM { 7210921STim.Haley@Sun.COM nvlist_t *policy; 7310921STim.Haley@Sun.COM nvpair_t *elem; 7410921STim.Haley@Sun.COM char *nm; 7510921STim.Haley@Sun.COM 7610921STim.Haley@Sun.COM /* Defaults */ 7710921STim.Haley@Sun.COM zrpp->zrp_request = ZPOOL_NO_REWIND; 7810921STim.Haley@Sun.COM zrpp->zrp_maxmeta = 0; 7911727SVictor.Latushkin@Sun.COM zrpp->zrp_maxdata = UINT64_MAX; 8010921STim.Haley@Sun.COM zrpp->zrp_txg = UINT64_MAX; 8110921STim.Haley@Sun.COM 8210921STim.Haley@Sun.COM if (nvl == NULL) 8310921STim.Haley@Sun.COM return; 8410921STim.Haley@Sun.COM 8510921STim.Haley@Sun.COM elem = NULL; 8610921STim.Haley@Sun.COM while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 8710921STim.Haley@Sun.COM nm = nvpair_name(elem); 8810921STim.Haley@Sun.COM if (strcmp(nm, ZPOOL_REWIND_POLICY) == 0) { 8910921STim.Haley@Sun.COM if (nvpair_value_nvlist(elem, &policy) == 0) 9010921STim.Haley@Sun.COM zpool_get_rewind_policy(policy, zrpp); 9110921STim.Haley@Sun.COM return; 9210921STim.Haley@Sun.COM } else if (strcmp(nm, ZPOOL_REWIND_REQUEST) == 0) { 9311727SVictor.Latushkin@Sun.COM if (nvpair_value_uint32(elem, &zrpp->zrp_request) == 0) 9411727SVictor.Latushkin@Sun.COM if (zrpp->zrp_request & ~ZPOOL_REWIND_POLICIES) 9510921STim.Haley@Sun.COM zrpp->zrp_request = ZPOOL_NO_REWIND; 9610921STim.Haley@Sun.COM } else if (strcmp(nm, ZPOOL_REWIND_REQUEST_TXG) == 0) { 9710921STim.Haley@Sun.COM (void) nvpair_value_uint64(elem, &zrpp->zrp_txg); 9810921STim.Haley@Sun.COM } else if (strcmp(nm, ZPOOL_REWIND_META_THRESH) == 0) { 9911727SVictor.Latushkin@Sun.COM (void) nvpair_value_uint64(elem, &zrpp->zrp_maxmeta); 10010921STim.Haley@Sun.COM } else if (strcmp(nm, ZPOOL_REWIND_DATA_THRESH) == 0) { 10111727SVictor.Latushkin@Sun.COM (void) nvpair_value_uint64(elem, &zrpp->zrp_maxdata); 10210921STim.Haley@Sun.COM } 10310921STim.Haley@Sun.COM } 10411727SVictor.Latushkin@Sun.COM if (zrpp->zrp_request == 0) 10511727SVictor.Latushkin@Sun.COM zrpp->zrp_request = ZPOOL_NO_REWIND; 10610921STim.Haley@Sun.COM } 107*11935SMark.Shellenbaum@Sun.COM 108*11935SMark.Shellenbaum@Sun.COM typedef struct zfs_version_spa_map { 109*11935SMark.Shellenbaum@Sun.COM int version_zpl; 110*11935SMark.Shellenbaum@Sun.COM int version_spa; 111*11935SMark.Shellenbaum@Sun.COM } zfs_version_spa_map_t; 112*11935SMark.Shellenbaum@Sun.COM 113*11935SMark.Shellenbaum@Sun.COM /* 114*11935SMark.Shellenbaum@Sun.COM * Keep this table in monotonically increasing version number order. 115*11935SMark.Shellenbaum@Sun.COM */ 116*11935SMark.Shellenbaum@Sun.COM static zfs_version_spa_map_t zfs_version_table[] = { 117*11935SMark.Shellenbaum@Sun.COM {ZPL_VERSION_INITIAL, SPA_VERSION_INITIAL}, 118*11935SMark.Shellenbaum@Sun.COM {ZPL_VERSION_DIRENT_TYPE, SPA_VERSION_INITIAL}, 119*11935SMark.Shellenbaum@Sun.COM {ZPL_VERSION_FUID, SPA_VERSION_FUID}, 120*11935SMark.Shellenbaum@Sun.COM {ZPL_VERSION_USERSPACE, SPA_VERSION_USERSPACE}, 121*11935SMark.Shellenbaum@Sun.COM {ZPL_VERSION_SA, SPA_VERSION_SA}, 122*11935SMark.Shellenbaum@Sun.COM {0, 0} 123*11935SMark.Shellenbaum@Sun.COM }; 124*11935SMark.Shellenbaum@Sun.COM 125*11935SMark.Shellenbaum@Sun.COM /* 126*11935SMark.Shellenbaum@Sun.COM * Return the max zpl version for a corresponding spa version 127*11935SMark.Shellenbaum@Sun.COM * -1 is returned if no mapping exists. 128*11935SMark.Shellenbaum@Sun.COM */ 129*11935SMark.Shellenbaum@Sun.COM int 130*11935SMark.Shellenbaum@Sun.COM zfs_zpl_version_map(int spa_version) 131*11935SMark.Shellenbaum@Sun.COM { 132*11935SMark.Shellenbaum@Sun.COM int i; 133*11935SMark.Shellenbaum@Sun.COM int version = -1; 134*11935SMark.Shellenbaum@Sun.COM 135*11935SMark.Shellenbaum@Sun.COM for (i = 0; zfs_version_table[i].version_spa; i++) { 136*11935SMark.Shellenbaum@Sun.COM if (spa_version >= zfs_version_table[i].version_spa) 137*11935SMark.Shellenbaum@Sun.COM version = zfs_version_table[i].version_zpl; 138*11935SMark.Shellenbaum@Sun.COM } 139*11935SMark.Shellenbaum@Sun.COM 140*11935SMark.Shellenbaum@Sun.COM return (version); 141*11935SMark.Shellenbaum@Sun.COM } 142*11935SMark.Shellenbaum@Sun.COM 143*11935SMark.Shellenbaum@Sun.COM /* 144*11935SMark.Shellenbaum@Sun.COM * Return the min spa version for a corresponding spa version 145*11935SMark.Shellenbaum@Sun.COM * -1 is returned if no mapping exists. 146*11935SMark.Shellenbaum@Sun.COM */ 147*11935SMark.Shellenbaum@Sun.COM int 148*11935SMark.Shellenbaum@Sun.COM zfs_spa_version_map(int zpl_version) 149*11935SMark.Shellenbaum@Sun.COM { 150*11935SMark.Shellenbaum@Sun.COM int i; 151*11935SMark.Shellenbaum@Sun.COM int version = -1; 152*11935SMark.Shellenbaum@Sun.COM 153*11935SMark.Shellenbaum@Sun.COM for (i = 0; zfs_version_table[i].version_zpl; i++) { 154*11935SMark.Shellenbaum@Sun.COM if (zfs_version_table[i].version_zpl >= zpl_version) 155*11935SMark.Shellenbaum@Sun.COM return (zfs_version_table[i].version_spa); 156*11935SMark.Shellenbaum@Sun.COM } 157*11935SMark.Shellenbaum@Sun.COM 158*11935SMark.Shellenbaum@Sun.COM return (version); 159*11935SMark.Shellenbaum@Sun.COM } 160