usr/src/uts/common/fs/zfs/zfeature.c
author eschrock
Mon, 21 May 2012 13:37:21 -0700
changeset 13701 1949b688d5fb
child 13753 2aba784c276b
permissions -rw-r--r--
2619 asynchronous destruction of ZFS file systems (missed files)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13701
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     1
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     2
 * CDDL HEADER START
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     3
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     7
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    11
 * and limitations under the License.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    12
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    18
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    19
 * CDDL HEADER END
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    20
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    21
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    22
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    23
 * Copyright (c) 2012 by Delphix. All rights reserved.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    24
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    25
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    26
#include <sys/zfs_context.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    27
#include <sys/zfeature.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    28
#include <sys/dmu.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    29
#include <sys/nvpair.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    30
#include <sys/zap.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    31
#include <sys/dmu_tx.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    32
#include "zfeature_common.h"
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    33
#include <sys/spa_impl.h>
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    34
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    35
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    36
 * ZFS Feature Flags
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    37
 * -----------------
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    38
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    39
 * ZFS feature flags are used to provide fine-grained versioning to the ZFS
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    40
 * on-disk format. Once enabled on a pool feature flags replace the old
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    41
 * spa_version() number.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    42
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    43
 * Each new on-disk format change will be given a uniquely identifying string
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    44
 * guid rather than a version number. This avoids the problem of different
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    45
 * organizations creating new on-disk formats with the same version number. To
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    46
 * keep feature guids unique they should consist of the reverse dns name of the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    47
 * organization which implemented the feature and a short name for the feature,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    48
 * separated by a colon (e.g. com.delphix:async_destroy).
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    49
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    50
 * Reference Counts
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    51
 * ----------------
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    52
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    53
 * Within each pool features can be in one of three states: disabled, enabled,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    54
 * or active. These states are differentiated by a reference count stored on
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    55
 * disk for each feature:
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    56
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    57
 *   1) If there is no reference count stored on disk the feature is disabled.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    58
 *   2) If the reference count is 0 a system administrator has enabled the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    59
 *      feature, but the feature has not been used yet, so no on-disk
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    60
 *      format changes have been made.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    61
 *   3) If the reference count is greater than 0 the feature is active.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    62
 *      The format changes required by the feature are currently on disk.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    63
 *      Note that if the feature's format changes are reversed the feature
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    64
 *      may choose to set its reference count back to 0.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    65
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    66
 * Feature flags makes no differentiation between non-zero reference counts
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    67
 * for an active feature (e.g. a reference count of 1 means the same thing as a
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    68
 * reference count of 27834721), but feature implementations may choose to use
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    69
 * the reference count to store meaningful information. For example, a new RAID
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    70
 * implementation might set the reference count to the number of vdevs using
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    71
 * it. If all those disks are removed from the pool the feature goes back to
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    72
 * having a reference count of 0.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    73
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    74
 * It is the responsibility of the individual features to maintain a non-zero
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    75
 * reference count as long as the feature's format changes are present on disk.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    76
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    77
 * Dependencies
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    78
 * ------------
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    79
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    80
 * Each feature may depend on other features. The only effect of this
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    81
 * relationship is that when a feature is enabled all of its dependencies are
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    82
 * automatically enabled as well. Any future work to support disabling of
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    83
 * features would need to ensure that features cannot be disabled if other
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    84
 * enabled features depend on them.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    85
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    86
 * On-disk Format
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    87
 * --------------
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    88
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    89
 * When feature flags are enabled spa_version() is set to SPA_VERSION_FEATURES
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    90
 * (5000). In order for this to work the pool is automatically upgraded to
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    91
 * SPA_VERSION_BEFORE_FEATURES (28) first, so all pre-feature flags on disk
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    92
 * format changes will be in use.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    93
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    94
 * Information about features is stored in 3 ZAP objects in the pool's MOS.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    95
 * These objects are linked to by the following names in the pool directory
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    96
 * object:
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    97
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    98
 * 1) features_for_read: feature guid -> reference count
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
    99
 *    Features needed to open the pool for reading.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   100
 * 2) features_for_write: feature guid -> reference count
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   101
 *    Features needed to open the pool for writing.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   102
 * 3) feature_descriptions: feature guid -> descriptive string
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   103
 *    A human readable string.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   104
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   105
 * All enabled features appear in either features_for_read or
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   106
 * features_for_write, but not both.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   107
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   108
 * To open a pool in read-only mode only the features listed in
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   109
 * features_for_read need to be supported.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   110
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   111
 * To open the pool in read-write mode features in both features_for_read and
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   112
 * features_for_write need to be supported.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   113
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   114
 * Some features may be required to read the ZAP objects containing feature
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   115
 * information. To allow software to check for compatibility with these features
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   116
 * before the pool is opened their names must be stored in the label in a
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   117
 * new "features_for_read" entry (note that features that are only required
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   118
 * to write to a pool never need to be stored in the label since the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   119
 * features_for_write ZAP object can be read before the pool is written to).
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   120
 * To save space in the label features must be explicitly marked as needing to
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   121
 * be written to the label. Also, reference counts are not stored in the label,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   122
 * instead any feature whose reference count drops to 0 is removed from the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   123
 * label.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   124
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   125
 * Adding New Features
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   126
 * -------------------
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   127
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   128
 * Features must be registered in zpool_feature_init() function in
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   129
 * zfeature_common.c using the zfeature_register() function. This function
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   130
 * has arguments to specify if the feature should be stored in the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   131
 * features_for_read or features_for_write ZAP object and if it needs to be
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   132
 * written to the label when active.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   133
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   134
 * Once a feature is registered it will appear as a "feature@<feature name>"
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   135
 * property which can be set by an administrator. Feature implementors should
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   136
 * use the spa_feature_is_enabled() and spa_feature_is_active() functions to
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   137
 * query the state of a feature and the spa_feature_incr() and
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   138
 * spa_feature_decr() functions to change an enabled feature's reference count.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   139
 * Reference counts may only be updated in the syncing context.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   140
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   141
 * Features may not perform enable-time initialization. Instead, any such
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   142
 * initialization should occur when the feature is first used. This design
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   143
 * enforces that on-disk changes be made only when features are used. Code
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   144
 * should only check if a feature is enabled using spa_feature_is_enabled(),
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   145
 * not by relying on any feature specific metadata existing. If a feature is
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   146
 * enabled, but the feature's metadata is not on disk yet then it should be
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   147
 * created as needed.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   148
 *
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   149
 * As an example, consider the com.delphix:async_destroy feature. This feature
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   150
 * relies on the existence of a bptree in the MOS that store blocks for
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   151
 * asynchronous freeing. This bptree is not created when async_destroy is
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   152
 * enabled. Instead, when a dataset is destroyed spa_feature_is_enabled() is
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   153
 * called to check if async_destroy is enabled. If it is and the bptree object
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   154
 * does not exist yet, the bptree object is created as part of the dataset
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   155
 * destroy and async_destroy's reference count is incremented to indicate it
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   156
 * has made an on-disk format change. Later, after the destroyed dataset's
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   157
 * blocks have all been asynchronously freed there is no longer any use for the
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   158
 * bptree object, so it is destroyed and async_destroy's reference count is
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   159
 * decremented back to 0 to indicate that it has undone its on-disk format
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   160
 * changes.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   161
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   162
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   163
typedef enum {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   164
	FEATURE_ACTION_ENABLE,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   165
	FEATURE_ACTION_INCR,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   166
	FEATURE_ACTION_DECR,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   167
} feature_action_t;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   168
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   169
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   170
 * Checks that the features active in the specified object are supported by
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   171
 * this software.  Adds each unsupported feature (name -> description) to
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   172
 * the supplied nvlist.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   173
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   174
boolean_t
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   175
feature_is_supported(objset_t *os, uint64_t obj, uint64_t desc_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   176
    nvlist_t *unsup_feat)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   177
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   178
	boolean_t supported;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   179
	zap_cursor_t zc;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   180
	zap_attribute_t za;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   181
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   182
	supported = B_TRUE;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   183
	for (zap_cursor_init(&zc, os, obj);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   184
	    zap_cursor_retrieve(&zc, &za) == 0;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   185
	    zap_cursor_advance(&zc)) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   186
		ASSERT(za.za_integer_length == sizeof (uint64_t) &&
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   187
		    za.za_num_integers == 1);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   188
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   189
		if (za.za_first_integer != 0 &&
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   190
		    !zfeature_is_supported(za.za_name)) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   191
			supported = B_FALSE;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   192
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   193
			if (unsup_feat != NULL) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   194
				char *desc = "";
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   195
				char buf[MAXPATHLEN];
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   196
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   197
				if (zap_lookup(os, desc_obj, za.za_name,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   198
				    1, sizeof (buf), buf) == 0)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   199
					desc = buf;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   200
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   201
				VERIFY(nvlist_add_string(unsup_feat, za.za_name,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   202
				    desc) == 0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   203
			}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   204
		}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   205
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   206
	zap_cursor_fini(&zc);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   207
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   208
	return (supported);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   209
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   210
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   211
static int
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   212
feature_get_refcount(objset_t *os, uint64_t read_obj, uint64_t write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   213
    zfeature_info_t *feature, uint64_t *res)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   214
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   215
	int err;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   216
	uint64_t refcount;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   217
	uint64_t zapobj = feature->fi_can_readonly ? write_obj : read_obj;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   218
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   219
	ASSERT(0 != zapobj);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   220
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   221
	err = zap_lookup(os, zapobj, feature->fi_guid, sizeof (uint64_t), 1,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   222
	    &refcount);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   223
	if (err != 0) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   224
		if (err == ENOENT)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   225
			return (ENOTSUP);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   226
		else
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   227
			return (err);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   228
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   229
	*res = refcount;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   230
	return (0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   231
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   232
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   233
static int
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   234
feature_do_action(objset_t *os, uint64_t read_obj, uint64_t write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   235
    uint64_t desc_obj, zfeature_info_t *feature, feature_action_t action,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   236
    dmu_tx_t *tx)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   237
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   238
	int error;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   239
	uint64_t refcount;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   240
	uint64_t zapobj = feature->fi_can_readonly ? write_obj : read_obj;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   241
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   242
	ASSERT(0 != zapobj);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   243
	ASSERT(zfeature_is_valid_guid(feature->fi_guid));
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   244
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   245
	error = zap_lookup(os, zapobj, feature->fi_guid,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   246
	    sizeof (uint64_t), 1, &refcount);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   247
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   248
	/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   249
	 * If we can't ascertain the status of the specified feature, an I/O
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   250
	 * error occurred.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   251
	 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   252
	if (error != 0 && error != ENOENT)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   253
		return (error);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   254
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   255
	switch (action) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   256
	case FEATURE_ACTION_ENABLE:
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   257
		/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   258
		 * If the feature is already enabled, ignore the request.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   259
		 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   260
		if (error == 0)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   261
			return (0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   262
		refcount = 0;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   263
		break;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   264
	case FEATURE_ACTION_INCR:
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   265
		if (error == ENOENT)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   266
			return (ENOTSUP);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   267
		if (refcount == UINT64_MAX)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   268
			return (EOVERFLOW);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   269
		refcount++;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   270
		break;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   271
	case FEATURE_ACTION_DECR:
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   272
		if (error == ENOENT)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   273
			return (ENOTSUP);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   274
		if (refcount == 0)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   275
			return (EOVERFLOW);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   276
		refcount--;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   277
		break;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   278
	default:
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   279
		ASSERT(0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   280
		break;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   281
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   282
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   283
	if (action == FEATURE_ACTION_ENABLE) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   284
		int i;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   285
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   286
		for (i = 0; feature->fi_depends[i] != NULL; i++) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   287
			zfeature_info_t *dep = feature->fi_depends[i];
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   288
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   289
			error = feature_do_action(os, read_obj, write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   290
			    desc_obj, dep, FEATURE_ACTION_ENABLE, tx);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   291
			if (error != 0)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   292
				return (error);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   293
		}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   294
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   295
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   296
	error = zap_update(os, zapobj, feature->fi_guid,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   297
	    sizeof (uint64_t), 1, &refcount, tx);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   298
	if (error != 0)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   299
		return (error);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   300
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   301
	if (action == FEATURE_ACTION_ENABLE) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   302
		error = zap_update(os, desc_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   303
		    feature->fi_guid, 1, strlen(feature->fi_desc) + 1,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   304
		    feature->fi_desc, tx);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   305
		if (error != 0)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   306
			return (error);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   307
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   308
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   309
	if (action == FEATURE_ACTION_INCR && refcount == 1 && feature->fi_mos) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   310
		spa_activate_mos_feature(dmu_objset_spa(os), feature->fi_guid);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   311
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   312
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   313
	if (action == FEATURE_ACTION_DECR && refcount == 0) {
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   314
		spa_deactivate_mos_feature(dmu_objset_spa(os),
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   315
		    feature->fi_guid);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   316
	}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   317
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   318
	return (0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   319
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   320
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   321
void
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   322
spa_feature_create_zap_objects(spa_t *spa, dmu_tx_t *tx)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   323
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   324
	/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   325
	 * We create feature flags ZAP objects in two instances: during pool
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   326
	 * creation and during pool upgrade.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   327
	 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   328
	ASSERT(dsl_pool_sync_context(spa_get_dsl(spa)) || (!spa->spa_sync_on &&
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   329
	    tx->tx_txg == TXG_INITIAL));
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   330
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   331
	spa->spa_feat_for_read_obj = zap_create_link(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   332
	    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   333
	    DMU_POOL_FEATURES_FOR_READ, tx);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   334
	spa->spa_feat_for_write_obj = zap_create_link(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   335
	    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   336
	    DMU_POOL_FEATURES_FOR_WRITE, tx);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   337
	spa->spa_feat_desc_obj = zap_create_link(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   338
	    DMU_OTN_ZAP_METADATA, DMU_POOL_DIRECTORY_OBJECT,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   339
	    DMU_POOL_FEATURE_DESCRIPTIONS, tx);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   340
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   341
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   342
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   343
 * Enable any required dependencies, then enable the requested feature.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   344
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   345
void
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   346
spa_feature_enable(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   347
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   348
	ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   349
	VERIFY3U(0, ==, feature_do_action(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   350
	    spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   351
	    spa->spa_feat_desc_obj, feature, FEATURE_ACTION_ENABLE, tx));
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   352
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   353
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   354
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   355
 * If the specified feature has not yet been enabled, this function returns
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   356
 * ENOTSUP; otherwise, this function increments the feature's refcount (or
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   357
 * returns EOVERFLOW if the refcount cannot be incremented). This function must
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   358
 * be called from syncing context.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   359
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   360
void
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   361
spa_feature_incr(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   362
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   363
	ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   364
	VERIFY3U(0, ==, feature_do_action(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   365
	    spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   366
	    spa->spa_feat_desc_obj, feature, FEATURE_ACTION_INCR, tx));
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   367
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   368
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   369
/*
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   370
 * If the specified feature has not yet been enabled, this function returns
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   371
 * ENOTSUP; otherwise, this function decrements the feature's refcount (or
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   372
 * returns EOVERFLOW if the refcount is already 0). This function must
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   373
 * be called from syncing context.
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   374
 */
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   375
void
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   376
spa_feature_decr(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   377
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   378
	ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   379
	VERIFY3U(0, ==, feature_do_action(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   380
	    spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   381
	    spa->spa_feat_desc_obj, feature, FEATURE_ACTION_DECR, tx));
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   382
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   383
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   384
boolean_t
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   385
spa_feature_is_enabled(spa_t *spa, zfeature_info_t *feature)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   386
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   387
	int err;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   388
	uint64_t refcount;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   389
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   390
	if (spa_version(spa) < SPA_VERSION_FEATURES)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   391
		return (B_FALSE);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   392
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   393
	err = feature_get_refcount(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   394
	    spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   395
	    feature, &refcount);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   396
	ASSERT(err == 0 || err == ENOTSUP);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   397
	return (err == 0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   398
}
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   399
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   400
boolean_t
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   401
spa_feature_is_active(spa_t *spa, zfeature_info_t *feature)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   402
{
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   403
	int err;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   404
	uint64_t refcount;
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   405
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   406
	if (spa_version(spa) < SPA_VERSION_FEATURES)
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   407
		return (B_FALSE);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   408
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   409
	err = feature_get_refcount(spa->spa_meta_objset,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   410
	    spa->spa_feat_for_read_obj, spa->spa_feat_for_write_obj,
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   411
	    feature, &refcount);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   412
	ASSERT(err == 0 || err == ENOTSUP);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   413
	return (err == 0 && refcount > 0);
1949b688d5fb 2619 asynchronous destruction of ZFS file systems (missed files)
eschrock
parents:
diff changeset
   414
}