75 char c = name[i++];
76 if (c == ':') {
77 if (has_colon)
78 return (B_FALSE);
79 has_colon = B_TRUE;
80 continue;
81 }
82 if (!valid_char(c, has_colon))
83 return (B_FALSE);
84 }
85
86 return (has_colon);
87 }
88
89 boolean_t
90 zfeature_is_supported(const char *guid)
91 {
92 if (zfeature_checks_disable)
93 return (B_TRUE);
94
95 return (0 == zfeature_lookup_guid(guid, NULL));
96 }
97
98 int
99 zfeature_lookup_guid(const char *guid, zfeature_info_t **res)
100 {
101 for (int i = 0; i < SPA_FEATURES; i++) {
102 zfeature_info_t *feature = &spa_feature_table[i];
103 if (strcmp(guid, feature->fi_guid) == 0) {
104 if (res != NULL)
105 *res = feature;
106 return (0);
107 }
108 }
109
110 return (ENOENT);
111 }
112
113 int
114 zfeature_lookup_name(const char *name, zfeature_info_t **res)
115 {
116 for (int i = 0; i < SPA_FEATURES; i++) {
117 zfeature_info_t *feature = &spa_feature_table[i];
118 if (strcmp(name, feature->fi_uname) == 0) {
119 if (res != NULL)
120 *res = feature;
121 return (0);
122 }
123 }
124
125 return (ENOENT);
126 }
127
128 static void
129 zfeature_register(int fid, const char *guid, const char *name, const char *desc,
130 boolean_t readonly, boolean_t mos, zfeature_info_t **deps)
131 {
132 zfeature_info_t *feature = &spa_feature_table[fid];
133 static zfeature_info_t *nodeps[] = { NULL };
134
135 ASSERT(name != NULL);
136 ASSERT(desc != NULL);
137 ASSERT(!readonly || !mos);
138 ASSERT3U(fid, <, SPA_FEATURES);
139 ASSERT(zfeature_is_valid_guid(guid));
140
141 if (deps == NULL)
142 deps = nodeps;
143
144 feature->fi_guid = guid;
145 feature->fi_uname = name;
146 feature->fi_desc = desc;
147 feature->fi_can_readonly = readonly;
148 feature->fi_mos = mos;
149 feature->fi_depends = deps;
150 }
151
152 void
153 zpool_feature_init(void)
154 {
155 zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
156 "com.delphix:async_destroy", "async_destroy",
157 "Destroy filesystems asynchronously.", B_TRUE, B_FALSE, NULL);
158 zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
159 "com.delphix:empty_bpobj", "empty_bpobj",
160 "Snapshots use less space.", B_TRUE, B_FALSE, NULL);
161 zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
162 "org.illumos:lz4_compress", "lz4_compress",
163 "LZ4 compression algorithm support.", B_FALSE, B_FALSE, NULL);
164 zfeature_register(SPA_FEATURE_MULTI_VDEV_CRASH_DUMP,
165 "com.joyent:multi_vdev_crash_dump", "multi_vdev_crash_dump",
166 "Crash dumps to multiple vdev pools.", B_FALSE, B_FALSE, NULL);
167 zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM,
168 "com.delphix:spacemap_histogram", "spacemap_histogram",
169 "Spacemaps maintain space histograms.", B_TRUE, B_FALSE, NULL);
170 }
|
75 char c = name[i++];
76 if (c == ':') {
77 if (has_colon)
78 return (B_FALSE);
79 has_colon = B_TRUE;
80 continue;
81 }
82 if (!valid_char(c, has_colon))
83 return (B_FALSE);
84 }
85
86 return (has_colon);
87 }
88
89 boolean_t
90 zfeature_is_supported(const char *guid)
91 {
92 if (zfeature_checks_disable)
93 return (B_TRUE);
94
95 for (spa_feature_t i = 0; i < SPA_FEATURES; i++) {
96 zfeature_info_t *feature = &spa_feature_table[i];
97 if (strcmp(guid, feature->fi_guid) == 0)
98 return (B_TRUE);
99 }
100 return (B_FALSE);
101 }
102
103 int
104 zfeature_lookup_name(const char *name, spa_feature_t *res)
105 {
106 for (spa_feature_t i = 0; i < SPA_FEATURES; i++) {
107 zfeature_info_t *feature = &spa_feature_table[i];
108 if (strcmp(name, feature->fi_uname) == 0) {
109 if (res != NULL)
110 *res = i;
111 return (0);
112 }
113 }
114
115 return (ENOENT);
116 }
117
118 static void
119 zfeature_register(spa_feature_t fid, const char *guid, const char *name,
120 const char *desc, boolean_t readonly, boolean_t mos,
121 const spa_feature_t *deps)
122 {
123 zfeature_info_t *feature = &spa_feature_table[fid];
124 static spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
125
126 ASSERT(name != NULL);
127 ASSERT(desc != NULL);
128 ASSERT(!readonly || !mos);
129 ASSERT3U(fid, <, SPA_FEATURES);
130 ASSERT(zfeature_is_valid_guid(guid));
131
132 if (deps == NULL)
133 deps = nodeps;
134
135 feature->fi_feature = fid;
136 feature->fi_guid = guid;
137 feature->fi_uname = name;
138 feature->fi_desc = desc;
139 feature->fi_can_readonly = readonly;
140 feature->fi_mos = mos;
141 feature->fi_depends = deps;
142 }
143
144 void
145 zpool_feature_init(void)
146 {
147 zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
148 "com.delphix:async_destroy", "async_destroy",
149 "Destroy filesystems asynchronously.", B_TRUE, B_FALSE, NULL);
150 zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
151 "com.delphix:empty_bpobj", "empty_bpobj",
152 "Snapshots use less space.", B_TRUE, B_FALSE, NULL);
153 zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
154 "org.illumos:lz4_compress", "lz4_compress",
155 "LZ4 compression algorithm support.", B_FALSE, B_FALSE, NULL);
156 zfeature_register(SPA_FEATURE_MULTI_VDEV_CRASH_DUMP,
157 "com.joyent:multi_vdev_crash_dump", "multi_vdev_crash_dump",
158 "Crash dumps to multiple vdev pools.", B_FALSE, B_FALSE, NULL);
159 zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM,
160 "com.delphix:spacemap_histogram", "spacemap_histogram",
161 "Spacemaps maintain space histograms.", B_TRUE, B_FALSE, NULL);
162 zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET,
163 "com.delphix:extensible_dataset", "extensible_dataset",
164 "Enhanced dataset functionality, used by other features.",
165 B_FALSE, B_FALSE, NULL);
166 }
|