Print this page
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ new/usr/src/uts/common/fs/zfs/zfs_ioctl.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Portions Copyright 2011 Martin Matuska
25 25 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
26 - * Copyright (c) 2012 by Delphix. All rights reserved.
27 26 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
27 + * Copyright (c) 2012 by Delphix. All rights reserved.
28 + */
29 +
30 +/*
31 + * ZFS ioctls.
32 + *
33 + * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
34 + * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
35 + *
36 + * There are two ways that we handle ioctls: the legacy way where almost
37 + * all of the logic is in the ioctl callback, and the new way where most
38 + * of the marshalling is handled in the common entry point, zfsdev_ioctl().
39 + *
40 + * Non-legacy ioctls should be registered by calling
41 + * zfs_ioctl_register() from zfs_ioctl_init(). The ioctl is invoked
42 + * from userland by lzc_ioctl().
43 + *
44 + * The registration arguments are as follows:
45 + *
46 + * const char *name
47 + * The name of the ioctl. This is used for history logging. If the
48 + * ioctl returns successfully (the callback returns 0), and allow_log
49 + * is true, then a history log entry will be recorded with the input &
50 + * output nvlists. The log entry can be printed with "zpool history -i".
51 + *
52 + * zfs_ioc_t ioc
53 + * The ioctl request number, which userland will pass to ioctl(2).
54 + * The ioctl numbers can change from release to release, because
55 + * the caller (libzfs) must be matched to the kernel.
56 + *
57 + * zfs_secpolicy_func_t *secpolicy
58 + * This function will be called before the zfs_ioc_func_t, to
59 + * determine if this operation is permitted. It should return EPERM
60 + * on failure, and 0 on success. Checks include determining if the
61 + * dataset is visible in this zone, and if the user has either all
62 + * zfs privileges in the zone (SYS_MOUNT), or has been granted permission
63 + * to do this operation on this dataset with "zfs allow".
64 + *
65 + * zfs_ioc_namecheck_t namecheck
66 + * This specifies what to expect in the zfs_cmd_t:zc_name -- a pool
67 + * name, a dataset name, or nothing. If the name is not well-formed,
68 + * the ioctl will fail and the callback will not be called.
69 + * Therefore, the callback can assume that the name is well-formed
70 + * (e.g. is null-terminated, doesn't have more than one '@' character,
71 + * doesn't have invalid characters).
72 + *
73 + * zfs_ioc_poolcheck_t pool_check
74 + * This specifies requirements on the pool state. If the pool does
75 + * not meet them (is suspended or is readonly), the ioctl will fail
76 + * and the callback will not be called. If any checks are specified
77 + * (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME.
78 + * Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED |
79 + * POOL_CHECK_READONLY).
80 + *
81 + * boolean_t smush_outnvlist
82 + * If smush_outnvlist is true, then the output is presumed to be a
83 + * list of errors, and it will be "smushed" down to fit into the
84 + * caller's buffer, by removing some entries and replacing them with a
85 + * single "N_MORE_ERRORS" entry indicating how many were removed. See
86 + * nvlist_smush() for details. If smush_outnvlist is false, and the
87 + * outnvlist does not fit into the userland-provided buffer, then the
88 + * ioctl will fail with ENOMEM.
89 + *
90 + * zfs_ioc_func_t *func
91 + * The callback function that will perform the operation.
92 + *
93 + * The callback should return 0 on success, or an error number on
94 + * failure. If the function fails, the userland ioctl will return -1,
95 + * and errno will be set to the callback's return value. The callback
96 + * will be called with the following arguments:
97 + *
98 + * const char *name
99 + * The name of the pool or dataset to operate on, from
100 + * zfs_cmd_t:zc_name. The 'namecheck' argument specifies the
101 + * expected type (pool, dataset, or none).
102 + *
103 + * nvlist_t *innvl
104 + * The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src. Or
105 + * NULL if no input nvlist was provided. Changes to this nvlist are
106 + * ignored. If the input nvlist could not be deserialized, the
107 + * ioctl will fail and the callback will not be called.
108 + *
109 + * nvlist_t *outnvl
110 + * The output nvlist, initially empty. The callback can fill it in,
111 + * and it will be returned to userland by serializing it into
112 + * zfs_cmd_t:zc_nvlist_dst. If it is non-empty, and serialization
113 + * fails (e.g. because the caller didn't supply a large enough
114 + * buffer), then the overall ioctl will fail. See the
115 + * 'smush_nvlist' argument above for additional behaviors.
116 + *
117 + * There are two typical uses of the output nvlist:
118 + * - To return state, e.g. property values. In this case,
119 + * smush_outnvlist should be false. If the buffer was not large
120 + * enough, the caller will reallocate a larger buffer and try
121 + * the ioctl again.
122 + *
123 + * - To return multiple errors from an ioctl which makes on-disk
124 + * changes. In this case, smush_outnvlist should be true.
125 + * Ioctls which make on-disk modifications should generally not
126 + * use the outnvl if they succeed, because the caller can not
127 + * distinguish between the operation failing, and
128 + * deserialization failing.
28 129 */
29 130
30 131 #include <sys/types.h>
31 132 #include <sys/param.h>
32 133 #include <sys/errno.h>
33 134 #include <sys/uio.h>
34 135 #include <sys/buf.h>
35 136 #include <sys/modctl.h>
36 137 #include <sys/open.h>
37 138 #include <sys/file.h>
38 139 #include <sys/kmem.h>
39 140 #include <sys/conf.h>
40 141 #include <sys/cmn_err.h>
41 142 #include <sys/stat.h>
42 143 #include <sys/zfs_ioctl.h>
43 144 #include <sys/zfs_vfsops.h>
44 145 #include <sys/zfs_znode.h>
45 146 #include <sys/zap.h>
46 147 #include <sys/spa.h>
47 148 #include <sys/spa_impl.h>
48 149 #include <sys/vdev.h>
49 150 #include <sys/priv_impl.h>
50 151 #include <sys/dmu.h>
51 152 #include <sys/dsl_dir.h>
52 153 #include <sys/dsl_dataset.h>
53 154 #include <sys/dsl_prop.h>
54 155 #include <sys/dsl_deleg.h>
55 156 #include <sys/dmu_objset.h>
56 157 #include <sys/dmu_impl.h>
57 158 #include <sys/ddi.h>
58 159 #include <sys/sunddi.h>
59 160 #include <sys/sunldi.h>
60 161 #include <sys/policy.h>
61 162 #include <sys/zone.h>
62 163 #include <sys/nvpair.h>
63 164 #include <sys/pathname.h>
64 165 #include <sys/mount.h>
65 166 #include <sys/sdt.h>
66 167 #include <sys/fs/zfs.h>
67 168 #include <sys/zfs_ctldir.h>
68 169 #include <sys/zfs_dir.h>
69 170 #include <sys/zfs_onexit.h>
70 171 #include <sys/zvol.h>
71 172 #include <sys/dsl_scan.h>
72 173 #include <sharefs/share.h>
73 174 #include <sys/dmu_objset.h>
74 175
75 176 #include "zfs_namecheck.h"
76 177 #include "zfs_prop.h"
77 178 #include "zfs_deleg.h"
↓ open down ↓ |
40 lines elided |
↑ open up ↑ |
78 179 #include "zfs_comutil.h"
79 180
80 181 extern struct modlfs zfs_modlfs;
81 182
82 183 extern void zfs_init(void);
83 184 extern void zfs_fini(void);
84 185
85 186 ldi_ident_t zfs_li = NULL;
86 187 dev_info_t *zfs_dip;
87 188
88 -typedef int zfs_ioc_func_t(zfs_cmd_t *);
89 -typedef int zfs_secpolicy_func_t(zfs_cmd_t *, cred_t *);
189 +uint_t zfs_fsyncer_key;
190 +extern uint_t rrw_tsd_key;
191 +static uint_t zfs_allow_log_key;
192 +
193 +typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
194 +typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
195 +typedef int zfs_secpolicy_func_t(zfs_cmd_t *, nvlist_t *, cred_t *);
90 196
91 197 typedef enum {
92 198 NO_NAME,
93 199 POOL_NAME,
94 200 DATASET_NAME
95 201 } zfs_ioc_namecheck_t;
96 202
97 203 typedef enum {
98 204 POOL_CHECK_NONE = 1 << 0,
99 205 POOL_CHECK_SUSPENDED = 1 << 1,
100 - POOL_CHECK_READONLY = 1 << 2
206 + POOL_CHECK_READONLY = 1 << 2,
101 207 } zfs_ioc_poolcheck_t;
102 208
103 209 typedef struct zfs_ioc_vec {
210 + zfs_ioc_legacy_func_t *zvec_legacy_func;
104 211 zfs_ioc_func_t *zvec_func;
105 212 zfs_secpolicy_func_t *zvec_secpolicy;
106 213 zfs_ioc_namecheck_t zvec_namecheck;
107 - boolean_t zvec_his_log;
214 + boolean_t zvec_allow_log;
108 215 zfs_ioc_poolcheck_t zvec_pool_check;
216 + boolean_t zvec_smush_outnvlist;
217 + const char *zvec_name;
109 218 } zfs_ioc_vec_t;
110 219
111 220 /* This array is indexed by zfs_userquota_prop_t */
112 221 static const char *userquota_perms[] = {
113 222 ZFS_DELEG_PERM_USERUSED,
114 223 ZFS_DELEG_PERM_USERQUOTA,
115 224 ZFS_DELEG_PERM_GROUPUSED,
116 225 ZFS_DELEG_PERM_GROUPQUOTA,
117 226 };
118 227
119 228 static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
120 229 static int zfs_check_settable(const char *name, nvpair_t *property,
121 230 cred_t *cr);
122 231 static int zfs_check_clearable(char *dataset, nvlist_t *props,
123 232 nvlist_t **errors);
124 233 static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
125 234 boolean_t *);
126 -int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t **);
235 +int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
236 +static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
127 237
128 238 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
129 239 void
130 240 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
131 241 {
132 242 const char *newfile;
133 243 char buf[512];
134 244 va_list adx;
135 245
136 246 /*
137 247 * Get rid of annoying "../common/" prefix to filename.
138 248 */
139 249 newfile = strrchr(file, '/');
140 250 if (newfile != NULL) {
141 251 newfile = newfile + 1; /* Get rid of leading / */
142 252 } else {
143 253 newfile = file;
144 254 }
145 255
146 256 va_start(adx, fmt);
147 257 (void) vsnprintf(buf, sizeof (buf), fmt, adx);
148 258 va_end(adx);
149 259
150 260 /*
151 261 * To get this data, use the zfs-dprintf probe as so:
152 262 * dtrace -q -n 'zfs-dprintf \
153 263 * /stringof(arg0) == "dbuf.c"/ \
154 264 * {printf("%s: %s", stringof(arg1), stringof(arg3))}'
155 265 * arg0 = file name
156 266 * arg1 = function name
157 267 * arg2 = line number
158 268 * arg3 = message
159 269 */
160 270 DTRACE_PROBE4(zfs__dprintf,
161 271 char *, newfile, char *, func, int, line, char *, buf);
162 272 }
163 273
164 274 static void
165 275 history_str_free(char *buf)
166 276 {
167 277 kmem_free(buf, HIS_MAX_RECORD_LEN);
168 278 }
169 279
170 280 static char *
171 281 history_str_get(zfs_cmd_t *zc)
172 282 {
173 283 char *buf;
174 284
175 285 if (zc->zc_history == NULL)
176 286 return (NULL);
177 287
178 288 buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
179 289 if (copyinstr((void *)(uintptr_t)zc->zc_history,
180 290 buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
181 291 history_str_free(buf);
182 292 return (NULL);
183 293 }
184 294
185 295 buf[HIS_MAX_RECORD_LEN -1] = '\0';
186 296
187 297 return (buf);
188 298 }
189 299
190 300 /*
191 301 * Check to see if the named dataset is currently defined as bootable
192 302 */
193 303 static boolean_t
194 304 zfs_is_bootfs(const char *name)
195 305 {
196 306 objset_t *os;
197 307
198 308 if (dmu_objset_hold(name, FTAG, &os) == 0) {
199 309 boolean_t ret;
200 310 ret = (dmu_objset_id(os) == spa_bootfs(dmu_objset_spa(os)));
201 311 dmu_objset_rele(os, FTAG);
202 312 return (ret);
203 313 }
204 314 return (B_FALSE);
205 315 }
206 316
207 317 /*
208 318 * zfs_earlier_version
209 319 *
210 320 * Return non-zero if the spa version is less than requested version.
211 321 */
212 322 static int
213 323 zfs_earlier_version(const char *name, int version)
214 324 {
215 325 spa_t *spa;
216 326
217 327 if (spa_open(name, &spa, FTAG) == 0) {
218 328 if (spa_version(spa) < version) {
219 329 spa_close(spa, FTAG);
220 330 return (1);
221 331 }
222 332 spa_close(spa, FTAG);
223 333 }
224 334 return (0);
225 335 }
226 336
227 337 /*
228 338 * zpl_earlier_version
229 339 *
230 340 * Return TRUE if the ZPL version is less than requested version.
231 341 */
232 342 static boolean_t
233 343 zpl_earlier_version(const char *name, int version)
234 344 {
235 345 objset_t *os;
236 346 boolean_t rc = B_TRUE;
237 347
238 348 if (dmu_objset_hold(name, FTAG, &os) == 0) {
239 349 uint64_t zplversion;
240 350
241 351 if (dmu_objset_type(os) != DMU_OST_ZFS) {
242 352 dmu_objset_rele(os, FTAG);
243 353 return (B_TRUE);
244 354 }
245 355 /* XXX reading from non-owned objset */
246 356 if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
247 357 rc = zplversion < version;
248 358 dmu_objset_rele(os, FTAG);
249 359 }
250 360 return (rc);
251 361 }
252 362
253 363 static void
↓ open down ↓ |
117 lines elided |
↑ open up ↑ |
254 364 zfs_log_history(zfs_cmd_t *zc)
255 365 {
256 366 spa_t *spa;
257 367 char *buf;
258 368
259 369 if ((buf = history_str_get(zc)) == NULL)
260 370 return;
261 371
262 372 if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
263 373 if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
264 - (void) spa_history_log(spa, buf, LOG_CMD_NORMAL);
374 + (void) spa_history_log(spa, buf);
265 375 spa_close(spa, FTAG);
266 376 }
267 377 history_str_free(buf);
268 378 }
269 379
270 380 /*
271 381 * Policy for top-level read operations (list pools). Requires no privileges,
272 382 * and can be used in the local zone, as there is no associated dataset.
273 383 */
274 384 /* ARGSUSED */
275 385 static int
276 -zfs_secpolicy_none(zfs_cmd_t *zc, cred_t *cr)
386 +zfs_secpolicy_none(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
277 387 {
278 388 return (0);
279 389 }
280 390
281 391 /*
282 392 * Policy for dataset read operations (list children, get statistics). Requires
283 393 * no privileges, but must be visible in the local zone.
284 394 */
285 395 /* ARGSUSED */
286 396 static int
287 -zfs_secpolicy_read(zfs_cmd_t *zc, cred_t *cr)
397 +zfs_secpolicy_read(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
288 398 {
289 399 if (INGLOBALZONE(curproc) ||
290 400 zone_dataset_visible(zc->zc_name, NULL))
291 401 return (0);
292 402
293 403 return (ENOENT);
294 404 }
295 405
296 406 static int
297 407 zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
298 408 {
299 409 int writable = 1;
300 410
301 411 /*
302 412 * The dataset must be visible by this zone -- check this first
303 413 * so they don't see EPERM on something they shouldn't know about.
304 414 */
305 415 if (!INGLOBALZONE(curproc) &&
306 416 !zone_dataset_visible(dataset, &writable))
307 417 return (ENOENT);
308 418
309 419 if (INGLOBALZONE(curproc)) {
310 420 /*
311 421 * If the fs is zoned, only root can access it from the
312 422 * global zone.
313 423 */
314 424 if (secpolicy_zfs(cr) && zoned)
315 425 return (EPERM);
316 426 } else {
317 427 /*
318 428 * If we are in a local zone, the 'zoned' property must be set.
319 429 */
320 430 if (!zoned)
321 431 return (EPERM);
322 432
323 433 /* must be writable by this zone */
324 434 if (!writable)
325 435 return (EPERM);
326 436 }
327 437 return (0);
328 438 }
329 439
330 440 static int
331 441 zfs_dozonecheck(const char *dataset, cred_t *cr)
332 442 {
333 443 uint64_t zoned;
334 444
335 445 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL))
336 446 return (ENOENT);
337 447
338 448 return (zfs_dozonecheck_impl(dataset, zoned, cr));
339 449 }
340 450
341 451 static int
342 452 zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
343 453 {
344 454 uint64_t zoned;
345 455
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
346 456 rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER);
347 457 if (dsl_prop_get_ds(ds, "zoned", 8, 1, &zoned, NULL)) {
348 458 rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
349 459 return (ENOENT);
350 460 }
351 461 rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock);
352 462
353 463 return (zfs_dozonecheck_impl(dataset, zoned, cr));
354 464 }
355 465
356 -/*
357 - * If name ends in a '@', then require recursive permissions.
358 - */
359 -int
466 +static int
360 467 zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
361 468 {
362 469 int error;
363 - boolean_t descendent = B_FALSE;
364 470 dsl_dataset_t *ds;
365 - char *at;
366 -
367 - at = strchr(name, '@');
368 - if (at != NULL && at[1] == '\0') {
369 - *at = '\0';
370 - descendent = B_TRUE;
371 - }
372 471
373 472 error = dsl_dataset_hold(name, FTAG, &ds);
374 - if (at != NULL)
375 - *at = '@';
376 473 if (error != 0)
377 474 return (error);
378 475
379 476 error = zfs_dozonecheck_ds(name, ds, cr);
380 477 if (error == 0) {
381 478 error = secpolicy_zfs(cr);
382 479 if (error)
383 - error = dsl_deleg_access_impl(ds, descendent, perm, cr);
480 + error = dsl_deleg_access_impl(ds, perm, cr);
384 481 }
385 482
386 483 dsl_dataset_rele(ds, FTAG);
387 484 return (error);
388 485 }
389 486
390 -int
487 +static int
391 488 zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
392 489 const char *perm, cred_t *cr)
393 490 {
394 491 int error;
395 492
396 493 error = zfs_dozonecheck_ds(name, ds, cr);
397 494 if (error == 0) {
398 495 error = secpolicy_zfs(cr);
399 496 if (error)
400 - error = dsl_deleg_access_impl(ds, B_FALSE, perm, cr);
497 + error = dsl_deleg_access_impl(ds, perm, cr);
401 498 }
402 499 return (error);
403 500 }
404 501
405 502 /*
406 503 * Policy for setting the security label property.
407 504 *
408 505 * Returns 0 for success, non-zero for access and other errors.
409 506 */
410 507 static int
411 508 zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
412 509 {
413 510 char ds_hexsl[MAXNAMELEN];
414 511 bslabel_t ds_sl, new_sl;
415 512 boolean_t new_default = FALSE;
416 513 uint64_t zoned;
417 514 int needed_priv = -1;
418 515 int error;
419 516
420 517 /* First get the existing dataset label. */
421 518 error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
422 519 1, sizeof (ds_hexsl), &ds_hexsl, NULL);
423 520 if (error)
424 521 return (EPERM);
425 522
426 523 if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
427 524 new_default = TRUE;
428 525
429 526 /* The label must be translatable */
430 527 if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
431 528 return (EINVAL);
432 529
433 530 /*
434 531 * In a non-global zone, disallow attempts to set a label that
435 532 * doesn't match that of the zone; otherwise no other checks
436 533 * are needed.
437 534 */
438 535 if (!INGLOBALZONE(curproc)) {
439 536 if (new_default || !blequal(&new_sl, CR_SL(CRED())))
440 537 return (EPERM);
441 538 return (0);
442 539 }
443 540
444 541 /*
445 542 * For global-zone datasets (i.e., those whose zoned property is
446 543 * "off", verify that the specified new label is valid for the
447 544 * global zone.
448 545 */
449 546 if (dsl_prop_get_integer(name,
450 547 zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
451 548 return (EPERM);
452 549 if (!zoned) {
453 550 if (zfs_check_global_label(name, strval) != 0)
454 551 return (EPERM);
455 552 }
456 553
457 554 /*
458 555 * If the existing dataset label is nondefault, check if the
459 556 * dataset is mounted (label cannot be changed while mounted).
460 557 * Get the zfsvfs; if there isn't one, then the dataset isn't
461 558 * mounted (or isn't a dataset, doesn't exist, ...).
462 559 */
463 560 if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
464 561 objset_t *os;
465 562 static char *setsl_tag = "setsl_tag";
466 563
467 564 /*
468 565 * Try to own the dataset; abort if there is any error,
469 566 * (e.g., already mounted, in use, or other error).
470 567 */
471 568 error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE,
472 569 setsl_tag, &os);
473 570 if (error)
474 571 return (EPERM);
475 572
476 573 dmu_objset_disown(os, setsl_tag);
477 574
478 575 if (new_default) {
479 576 needed_priv = PRIV_FILE_DOWNGRADE_SL;
480 577 goto out_check;
481 578 }
482 579
483 580 if (hexstr_to_label(strval, &new_sl) != 0)
484 581 return (EPERM);
485 582
486 583 if (blstrictdom(&ds_sl, &new_sl))
487 584 needed_priv = PRIV_FILE_DOWNGRADE_SL;
488 585 else if (blstrictdom(&new_sl, &ds_sl))
489 586 needed_priv = PRIV_FILE_UPGRADE_SL;
490 587 } else {
491 588 /* dataset currently has a default label */
492 589 if (!new_default)
493 590 needed_priv = PRIV_FILE_UPGRADE_SL;
494 591 }
495 592
496 593 out_check:
497 594 if (needed_priv != -1)
498 595 return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
499 596 return (0);
500 597 }
501 598
502 599 static int
503 600 zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
504 601 cred_t *cr)
505 602 {
506 603 char *strval;
507 604
508 605 /*
509 606 * Check permissions for special properties.
510 607 */
511 608 switch (prop) {
512 609 case ZFS_PROP_ZONED:
513 610 /*
514 611 * Disallow setting of 'zoned' from within a local zone.
515 612 */
516 613 if (!INGLOBALZONE(curproc))
517 614 return (EPERM);
518 615 break;
519 616
520 617 case ZFS_PROP_QUOTA:
521 618 if (!INGLOBALZONE(curproc)) {
522 619 uint64_t zoned;
523 620 char setpoint[MAXNAMELEN];
524 621 /*
525 622 * Unprivileged users are allowed to modify the
526 623 * quota on things *under* (ie. contained by)
527 624 * the thing they own.
528 625 */
529 626 if (dsl_prop_get_integer(dsname, "zoned", &zoned,
530 627 setpoint))
531 628 return (EPERM);
532 629 if (!zoned || strlen(dsname) <= strlen(setpoint))
533 630 return (EPERM);
534 631 }
535 632 break;
536 633
537 634 case ZFS_PROP_MLSLABEL:
538 635 if (!is_system_labeled())
539 636 return (EPERM);
540 637
541 638 if (nvpair_value_string(propval, &strval) == 0) {
542 639 int err;
543 640
↓ open down ↓ |
133 lines elided |
↑ open up ↑ |
544 641 err = zfs_set_slabel_policy(dsname, strval, CRED());
545 642 if (err != 0)
546 643 return (err);
547 644 }
548 645 break;
549 646 }
550 647
551 648 return (zfs_secpolicy_write_perms(dsname, zfs_prop_to_name(prop), cr));
552 649 }
553 650
554 -int
555 -zfs_secpolicy_fsacl(zfs_cmd_t *zc, cred_t *cr)
651 +/* ARGSUSED */
652 +static int
653 +zfs_secpolicy_set_fsacl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
556 654 {
557 655 int error;
558 656
559 657 error = zfs_dozonecheck(zc->zc_name, cr);
560 658 if (error)
561 659 return (error);
562 660
563 661 /*
564 662 * permission to set permissions will be evaluated later in
565 663 * dsl_deleg_can_allow()
566 664 */
567 665 return (0);
568 666 }
569 667
570 -int
571 -zfs_secpolicy_rollback(zfs_cmd_t *zc, cred_t *cr)
668 +/* ARGSUSED */
669 +static int
670 +zfs_secpolicy_rollback(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
572 671 {
573 672 return (zfs_secpolicy_write_perms(zc->zc_name,
574 673 ZFS_DELEG_PERM_ROLLBACK, cr));
575 674 }
576 675
577 -int
578 -zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr)
676 +/* ARGSUSED */
677 +static int
678 +zfs_secpolicy_send(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
579 679 {
580 680 spa_t *spa;
581 681 dsl_pool_t *dp;
582 682 dsl_dataset_t *ds;
583 683 char *cp;
584 684 int error;
585 685
586 686 /*
587 687 * Generate the current snapshot name from the given objsetid, then
588 688 * use that name for the secpolicy/zone checks.
589 689 */
590 690 cp = strchr(zc->zc_name, '@');
591 691 if (cp == NULL)
592 692 return (EINVAL);
593 693 error = spa_open(zc->zc_name, &spa, FTAG);
594 694 if (error)
595 695 return (error);
596 696
597 697 dp = spa_get_dsl(spa);
598 698 rw_enter(&dp->dp_config_rwlock, RW_READER);
599 699 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
600 700 rw_exit(&dp->dp_config_rwlock);
601 701 spa_close(spa, FTAG);
602 702 if (error)
603 703 return (error);
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
604 704
605 705 dsl_dataset_name(ds, zc->zc_name);
606 706
607 707 error = zfs_secpolicy_write_perms_ds(zc->zc_name, ds,
608 708 ZFS_DELEG_PERM_SEND, cr);
609 709 dsl_dataset_rele(ds, FTAG);
610 710
611 711 return (error);
612 712 }
613 713
714 +/* ARGSUSED */
715 +static int
716 +zfs_secpolicy_send_new(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
717 +{
718 + return (zfs_secpolicy_write_perms(zc->zc_name,
719 + ZFS_DELEG_PERM_SEND, cr));
720 +}
721 +
722 +/* ARGSUSED */
614 723 static int
615 -zfs_secpolicy_deleg_share(zfs_cmd_t *zc, cred_t *cr)
724 +zfs_secpolicy_deleg_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
616 725 {
617 726 vnode_t *vp;
618 727 int error;
619 728
620 729 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
621 730 NO_FOLLOW, NULL, &vp)) != 0)
622 731 return (error);
623 732
624 733 /* Now make sure mntpnt and dataset are ZFS */
625 734
626 735 if (vp->v_vfsp->vfs_fstype != zfsfstype ||
627 736 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
628 737 zc->zc_name) != 0)) {
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
629 738 VN_RELE(vp);
630 739 return (EPERM);
631 740 }
632 741
633 742 VN_RELE(vp);
634 743 return (dsl_deleg_access(zc->zc_name,
635 744 ZFS_DELEG_PERM_SHARE, cr));
636 745 }
637 746
638 747 int
639 -zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr)
748 +zfs_secpolicy_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
640 749 {
641 750 if (!INGLOBALZONE(curproc))
642 751 return (EPERM);
643 752
644 753 if (secpolicy_nfs(cr) == 0) {
645 754 return (0);
646 755 } else {
647 - return (zfs_secpolicy_deleg_share(zc, cr));
756 + return (zfs_secpolicy_deleg_share(zc, innvl, cr));
648 757 }
649 758 }
650 759
651 760 int
652 -zfs_secpolicy_smb_acl(zfs_cmd_t *zc, cred_t *cr)
761 +zfs_secpolicy_smb_acl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
653 762 {
654 763 if (!INGLOBALZONE(curproc))
655 764 return (EPERM);
656 765
657 766 if (secpolicy_smb(cr) == 0) {
658 767 return (0);
659 768 } else {
660 - return (zfs_secpolicy_deleg_share(zc, cr));
769 + return (zfs_secpolicy_deleg_share(zc, innvl, cr));
661 770 }
662 771 }
663 772
664 773 static int
665 774 zfs_get_parent(const char *datasetname, char *parent, int parentsize)
666 775 {
667 776 char *cp;
668 777
669 778 /*
670 779 * Remove the @bla or /bla from the end of the name to get the parent.
671 780 */
672 781 (void) strncpy(parent, datasetname, parentsize);
673 782 cp = strrchr(parent, '@');
674 783 if (cp != NULL) {
675 784 cp[0] = '\0';
676 785 } else {
677 786 cp = strrchr(parent, '/');
678 787 if (cp == NULL)
679 788 return (ENOENT);
680 789 cp[0] = '\0';
681 790 }
682 791
683 792 return (0);
684 793 }
685 794
686 795 int
687 796 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
688 797 {
689 798 int error;
690 799
691 800 if ((error = zfs_secpolicy_write_perms(name,
692 801 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
693 802 return (error);
694 803
695 804 return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr));
696 805 }
697 806
807 +/* ARGSUSED */
698 808 static int
699 -zfs_secpolicy_destroy(zfs_cmd_t *zc, cred_t *cr)
809 +zfs_secpolicy_destroy(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
700 810 {
701 811 return (zfs_secpolicy_destroy_perms(zc->zc_name, cr));
702 812 }
703 813
704 814 /*
705 815 * Destroying snapshots with delegated permissions requires
706 - * descendent mount and destroy permissions.
816 + * descendant mount and destroy permissions.
707 817 */
818 +/* ARGSUSED */
708 819 static int
709 -zfs_secpolicy_destroy_recursive(zfs_cmd_t *zc, cred_t *cr)
820 +zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
710 821 {
711 - int error;
712 - char *dsname;
822 + nvlist_t *snaps;
823 + nvpair_t *pair, *nextpair;
824 + int error = 0;
713 825
714 - dsname = kmem_asprintf("%s@", zc->zc_name);
826 + if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
827 + return (EINVAL);
828 + for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
829 + pair = nextpair) {
830 + dsl_dataset_t *ds;
715 831
716 - error = zfs_secpolicy_destroy_perms(dsname, cr);
832 + nextpair = nvlist_next_nvpair(snaps, pair);
833 + error = dsl_dataset_hold(nvpair_name(pair), FTAG, &ds);
834 + if (error == 0) {
835 + dsl_dataset_rele(ds, FTAG);
836 + } else if (error == ENOENT) {
837 + /*
838 + * Ignore any snapshots that don't exist (we consider
839 + * them "already destroyed"). Remove the name from the
840 + * nvl here in case the snapshot is created between
841 + * now and when we try to destroy it (in which case
842 + * we don't want to destroy it since we haven't
843 + * checked for permission).
844 + */
845 + fnvlist_remove_nvpair(snaps, pair);
846 + error = 0;
847 + continue;
848 + } else {
849 + break;
850 + }
851 + error = zfs_secpolicy_destroy_perms(nvpair_name(pair), cr);
852 + if (error != 0)
853 + break;
854 + }
717 855
718 - strfree(dsname);
719 856 return (error);
720 857 }
721 858
722 859 int
723 860 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
724 861 {
725 862 char parentname[MAXNAMELEN];
726 863 int error;
727 864
728 865 if ((error = zfs_secpolicy_write_perms(from,
729 866 ZFS_DELEG_PERM_RENAME, cr)) != 0)
730 867 return (error);
731 868
732 869 if ((error = zfs_secpolicy_write_perms(from,
733 870 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
734 871 return (error);
735 872
736 873 if ((error = zfs_get_parent(to, parentname,
737 874 sizeof (parentname))) != 0)
738 875 return (error);
739 876
740 877 if ((error = zfs_secpolicy_write_perms(parentname,
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
741 878 ZFS_DELEG_PERM_CREATE, cr)) != 0)
742 879 return (error);
743 880
744 881 if ((error = zfs_secpolicy_write_perms(parentname,
745 882 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
746 883 return (error);
747 884
748 885 return (error);
749 886 }
750 887
888 +/* ARGSUSED */
751 889 static int
752 -zfs_secpolicy_rename(zfs_cmd_t *zc, cred_t *cr)
890 +zfs_secpolicy_rename(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
753 891 {
754 892 return (zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr));
755 893 }
756 894
895 +/* ARGSUSED */
757 896 static int
758 -zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr)
897 +zfs_secpolicy_promote(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
759 898 {
760 899 char parentname[MAXNAMELEN];
761 900 objset_t *clone;
762 901 int error;
763 902
764 903 error = zfs_secpolicy_write_perms(zc->zc_name,
765 904 ZFS_DELEG_PERM_PROMOTE, cr);
766 905 if (error)
767 906 return (error);
768 907
769 908 error = dmu_objset_hold(zc->zc_name, FTAG, &clone);
770 909
771 910 if (error == 0) {
772 911 dsl_dataset_t *pclone = NULL;
773 912 dsl_dir_t *dd;
774 913 dd = clone->os_dsl_dataset->ds_dir;
775 914
776 915 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
777 916 error = dsl_dataset_hold_obj(dd->dd_pool,
778 917 dd->dd_phys->dd_origin_obj, FTAG, &pclone);
779 918 rw_exit(&dd->dd_pool->dp_config_rwlock);
780 919 if (error) {
781 920 dmu_objset_rele(clone, FTAG);
782 921 return (error);
783 922 }
784 923
785 924 error = zfs_secpolicy_write_perms(zc->zc_name,
786 925 ZFS_DELEG_PERM_MOUNT, cr);
787 926
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
788 927 dsl_dataset_name(pclone, parentname);
789 928 dmu_objset_rele(clone, FTAG);
790 929 dsl_dataset_rele(pclone, FTAG);
791 930 if (error == 0)
792 931 error = zfs_secpolicy_write_perms(parentname,
793 932 ZFS_DELEG_PERM_PROMOTE, cr);
794 933 }
795 934 return (error);
796 935 }
797 936
937 +/* ARGSUSED */
798 938 static int
799 -zfs_secpolicy_receive(zfs_cmd_t *zc, cred_t *cr)
939 +zfs_secpolicy_recv(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
800 940 {
801 941 int error;
802 942
803 943 if ((error = zfs_secpolicy_write_perms(zc->zc_name,
804 944 ZFS_DELEG_PERM_RECEIVE, cr)) != 0)
805 945 return (error);
806 946
807 947 if ((error = zfs_secpolicy_write_perms(zc->zc_name,
808 948 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
809 949 return (error);
810 950
811 951 return (zfs_secpolicy_write_perms(zc->zc_name,
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
812 952 ZFS_DELEG_PERM_CREATE, cr));
813 953 }
814 954
815 955 int
816 956 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
817 957 {
818 958 return (zfs_secpolicy_write_perms(name,
819 959 ZFS_DELEG_PERM_SNAPSHOT, cr));
820 960 }
821 961
962 +/*
963 + * Check for permission to create each snapshot in the nvlist.
964 + */
965 +/* ARGSUSED */
822 966 static int
823 -zfs_secpolicy_snapshot(zfs_cmd_t *zc, cred_t *cr)
967 +zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
824 968 {
969 + nvlist_t *snaps;
970 + int error;
971 + nvpair_t *pair;
825 972
826 - return (zfs_secpolicy_snapshot_perms(zc->zc_name, cr));
973 + if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
974 + return (EINVAL);
975 + for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
976 + pair = nvlist_next_nvpair(snaps, pair)) {
977 + char *name = nvpair_name(pair);
978 + char *atp = strchr(name, '@');
979 +
980 + if (atp == NULL) {
981 + error = EINVAL;
982 + break;
983 + }
984 + *atp = '\0';
985 + error = zfs_secpolicy_snapshot_perms(name, cr);
986 + *atp = '@';
987 + if (error != 0)
988 + break;
989 + }
990 + return (error);
991 +}
992 +
993 +/* ARGSUSED */
994 +static int
995 +zfs_secpolicy_log_history(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
996 +{
997 + /*
998 + * Even root must have a proper TSD so that we know what pool
999 + * to log to.
1000 + */
1001 + if (tsd_get(zfs_allow_log_key) == NULL)
1002 + return (EPERM);
1003 + return (0);
827 1004 }
828 1005
829 1006 static int
830 -zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr)
1007 +zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
831 1008 {
832 1009 char parentname[MAXNAMELEN];
833 1010 int error;
1011 + char *origin;
834 1012
835 1013 if ((error = zfs_get_parent(zc->zc_name, parentname,
836 1014 sizeof (parentname))) != 0)
837 1015 return (error);
838 1016
839 - if (zc->zc_value[0] != '\0') {
840 - if ((error = zfs_secpolicy_write_perms(zc->zc_value,
841 - ZFS_DELEG_PERM_CLONE, cr)) != 0)
842 - return (error);
843 - }
1017 + if (nvlist_lookup_string(innvl, "origin", &origin) == 0 &&
1018 + (error = zfs_secpolicy_write_perms(origin,
1019 + ZFS_DELEG_PERM_CLONE, cr)) != 0)
1020 + return (error);
844 1021
845 1022 if ((error = zfs_secpolicy_write_perms(parentname,
846 1023 ZFS_DELEG_PERM_CREATE, cr)) != 0)
847 1024 return (error);
848 1025
849 - error = zfs_secpolicy_write_perms(parentname,
850 - ZFS_DELEG_PERM_MOUNT, cr);
851 -
852 - return (error);
853 -}
854 -
855 -static int
856 -zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr)
857 -{
858 - int error;
859 -
860 - error = secpolicy_fs_unmount(cr, NULL);
861 - if (error) {
862 - error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr);
863 - }
864 - return (error);
1026 + return (zfs_secpolicy_write_perms(parentname,
1027 + ZFS_DELEG_PERM_MOUNT, cr));
865 1028 }
866 1029
867 1030 /*
868 1031 * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires
869 1032 * SYS_CONFIG privilege, which is not available in a local zone.
870 1033 */
871 1034 /* ARGSUSED */
872 1035 static int
873 -zfs_secpolicy_config(zfs_cmd_t *zc, cred_t *cr)
1036 +zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
874 1037 {
875 1038 if (secpolicy_sys_config(cr, B_FALSE) != 0)
876 1039 return (EPERM);
877 1040
878 1041 return (0);
879 1042 }
880 1043
881 1044 /*
882 1045 * Policy for object to name lookups.
883 1046 */
884 1047 /* ARGSUSED */
885 1048 static int
886 -zfs_secpolicy_diff(zfs_cmd_t *zc, cred_t *cr)
1049 +zfs_secpolicy_diff(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
887 1050 {
888 1051 int error;
889 1052
890 1053 if ((error = secpolicy_sys_config(cr, B_FALSE)) == 0)
891 1054 return (0);
892 1055
893 1056 error = zfs_secpolicy_write_perms(zc->zc_name, ZFS_DELEG_PERM_DIFF, cr);
894 1057 return (error);
895 1058 }
896 1059
897 1060 /*
898 1061 * Policy for fault injection. Requires all privileges.
899 1062 */
900 1063 /* ARGSUSED */
901 1064 static int
902 -zfs_secpolicy_inject(zfs_cmd_t *zc, cred_t *cr)
1065 +zfs_secpolicy_inject(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
903 1066 {
904 1067 return (secpolicy_zinject(cr));
905 1068 }
906 1069
1070 +/* ARGSUSED */
907 1071 static int
908 -zfs_secpolicy_inherit(zfs_cmd_t *zc, cred_t *cr)
1072 +zfs_secpolicy_inherit_prop(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
909 1073 {
910 1074 zfs_prop_t prop = zfs_name_to_prop(zc->zc_value);
911 1075
912 1076 if (prop == ZPROP_INVAL) {
913 1077 if (!zfs_prop_user(zc->zc_value))
914 1078 return (EINVAL);
915 1079 return (zfs_secpolicy_write_perms(zc->zc_name,
916 1080 ZFS_DELEG_PERM_USERPROP, cr));
917 1081 } else {
918 1082 return (zfs_secpolicy_setprop(zc->zc_name, prop,
919 1083 NULL, cr));
920 1084 }
921 1085 }
922 1086
923 1087 static int
924 -zfs_secpolicy_userspace_one(zfs_cmd_t *zc, cred_t *cr)
1088 +zfs_secpolicy_userspace_one(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
925 1089 {
926 - int err = zfs_secpolicy_read(zc, cr);
1090 + int err = zfs_secpolicy_read(zc, innvl, cr);
927 1091 if (err)
928 1092 return (err);
929 1093
930 1094 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
931 1095 return (EINVAL);
932 1096
933 1097 if (zc->zc_value[0] == 0) {
934 1098 /*
935 1099 * They are asking about a posix uid/gid. If it's
936 1100 * themself, allow it.
937 1101 */
938 1102 if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
939 1103 zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
940 1104 if (zc->zc_guid == crgetuid(cr))
941 1105 return (0);
942 1106 } else {
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
943 1107 if (groupmember(zc->zc_guid, cr))
944 1108 return (0);
945 1109 }
946 1110 }
947 1111
948 1112 return (zfs_secpolicy_write_perms(zc->zc_name,
949 1113 userquota_perms[zc->zc_objset_type], cr));
950 1114 }
951 1115
952 1116 static int
953 -zfs_secpolicy_userspace_many(zfs_cmd_t *zc, cred_t *cr)
1117 +zfs_secpolicy_userspace_many(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
954 1118 {
955 - int err = zfs_secpolicy_read(zc, cr);
1119 + int err = zfs_secpolicy_read(zc, innvl, cr);
956 1120 if (err)
957 1121 return (err);
958 1122
959 1123 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
960 1124 return (EINVAL);
961 1125
962 1126 return (zfs_secpolicy_write_perms(zc->zc_name,
963 1127 userquota_perms[zc->zc_objset_type], cr));
964 1128 }
965 1129
1130 +/* ARGSUSED */
966 1131 static int
967 -zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, cred_t *cr)
1132 +zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
968 1133 {
969 1134 return (zfs_secpolicy_setprop(zc->zc_name, ZFS_PROP_VERSION,
970 1135 NULL, cr));
971 1136 }
972 1137
1138 +/* ARGSUSED */
973 1139 static int
974 -zfs_secpolicy_hold(zfs_cmd_t *zc, cred_t *cr)
1140 +zfs_secpolicy_hold(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
975 1141 {
976 1142 return (zfs_secpolicy_write_perms(zc->zc_name,
977 1143 ZFS_DELEG_PERM_HOLD, cr));
978 1144 }
979 1145
1146 +/* ARGSUSED */
980 1147 static int
981 -zfs_secpolicy_release(zfs_cmd_t *zc, cred_t *cr)
1148 +zfs_secpolicy_release(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
982 1149 {
983 1150 return (zfs_secpolicy_write_perms(zc->zc_name,
984 1151 ZFS_DELEG_PERM_RELEASE, cr));
985 1152 }
986 1153
987 1154 /*
988 1155 * Policy for allowing temporary snapshots to be taken or released
989 1156 */
990 1157 static int
991 -zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, cred_t *cr)
1158 +zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
992 1159 {
993 1160 /*
994 1161 * A temporary snapshot is the same as a snapshot,
995 1162 * hold, destroy and release all rolled into one.
996 1163 * Delegated diff alone is sufficient that we allow this.
997 1164 */
998 1165 int error;
999 1166
1000 1167 if ((error = zfs_secpolicy_write_perms(zc->zc_name,
1001 1168 ZFS_DELEG_PERM_DIFF, cr)) == 0)
1002 1169 return (0);
1003 1170
1004 - error = zfs_secpolicy_snapshot(zc, cr);
1171 + error = zfs_secpolicy_snapshot_perms(zc->zc_name, cr);
1005 1172 if (!error)
1006 - error = zfs_secpolicy_hold(zc, cr);
1173 + error = zfs_secpolicy_hold(zc, innvl, cr);
1007 1174 if (!error)
1008 - error = zfs_secpolicy_release(zc, cr);
1175 + error = zfs_secpolicy_release(zc, innvl, cr);
1009 1176 if (!error)
1010 - error = zfs_secpolicy_destroy(zc, cr);
1177 + error = zfs_secpolicy_destroy(zc, innvl, cr);
1011 1178 return (error);
1012 1179 }
1013 1180
1014 1181 /*
1015 1182 * Returns the nvlist as specified by the user in the zfs_cmd_t.
1016 1183 */
1017 1184 static int
1018 1185 get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp)
1019 1186 {
1020 1187 char *packed;
1021 1188 int error;
1022 1189 nvlist_t *list = NULL;
1023 1190
1024 1191 /*
1025 1192 * Read in and unpack the user-supplied nvlist.
1026 1193 */
1027 1194 if (size == 0)
1028 1195 return (EINVAL);
1029 1196
1030 1197 packed = kmem_alloc(size, KM_SLEEP);
1031 1198
1032 1199 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
1033 1200 iflag)) != 0) {
1034 1201 kmem_free(packed, size);
1035 1202 return (error);
1036 1203 }
1037 1204
1038 1205 if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) {
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
1039 1206 kmem_free(packed, size);
1040 1207 return (error);
1041 1208 }
1042 1209
1043 1210 kmem_free(packed, size);
1044 1211
1045 1212 *nvp = list;
1046 1213 return (0);
1047 1214 }
1048 1215
1216 +/*
1217 + * Reduce the size of this nvlist until it can be serialized in 'max' bytes.
1218 + * Entries will be removed from the end of the nvlist, and one int32 entry
1219 + * named "N_MORE_ERRORS" will be added indicating how many entries were
1220 + * removed.
1221 + */
1049 1222 static int
1050 -fit_error_list(zfs_cmd_t *zc, nvlist_t **errors)
1223 +nvlist_smush(nvlist_t *errors, size_t max)
1051 1224 {
1052 1225 size_t size;
1053 1226
1054 - VERIFY(nvlist_size(*errors, &size, NV_ENCODE_NATIVE) == 0);
1227 + size = fnvlist_size(errors);
1055 1228
1056 - if (size > zc->zc_nvlist_dst_size) {
1229 + if (size > max) {
1057 1230 nvpair_t *more_errors;
1058 1231 int n = 0;
1059 1232
1060 - if (zc->zc_nvlist_dst_size < 1024)
1233 + if (max < 1024)
1061 1234 return (ENOMEM);
1062 1235
1063 - VERIFY(nvlist_add_int32(*errors, ZPROP_N_MORE_ERRORS, 0) == 0);
1064 - more_errors = nvlist_prev_nvpair(*errors, NULL);
1236 + fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0);
1237 + more_errors = nvlist_prev_nvpair(errors, NULL);
1065 1238
1066 1239 do {
1067 - nvpair_t *pair = nvlist_prev_nvpair(*errors,
1240 + nvpair_t *pair = nvlist_prev_nvpair(errors,
1068 1241 more_errors);
1069 - VERIFY(nvlist_remove_nvpair(*errors, pair) == 0);
1242 + fnvlist_remove_nvpair(errors, pair);
1070 1243 n++;
1071 - VERIFY(nvlist_size(*errors, &size,
1072 - NV_ENCODE_NATIVE) == 0);
1073 - } while (size > zc->zc_nvlist_dst_size);
1074 -
1075 - VERIFY(nvlist_remove_nvpair(*errors, more_errors) == 0);
1076 - VERIFY(nvlist_add_int32(*errors, ZPROP_N_MORE_ERRORS, n) == 0);
1077 - ASSERT(nvlist_size(*errors, &size, NV_ENCODE_NATIVE) == 0);
1078 - ASSERT(size <= zc->zc_nvlist_dst_size);
1244 + size = fnvlist_size(errors);
1245 + } while (size > max);
1246 +
1247 + fnvlist_remove_nvpair(errors, more_errors);
1248 + fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, n);
1249 + ASSERT3U(fnvlist_size(errors), <=, max);
1079 1250 }
1080 1251
1081 1252 return (0);
1082 1253 }
1083 1254
1084 1255 static int
1085 1256 put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
1086 1257 {
1087 1258 char *packed = NULL;
1088 1259 int error = 0;
1089 1260 size_t size;
1090 1261
1091 - VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0);
1262 + size = fnvlist_size(nvl);
1092 1263
1093 1264 if (size > zc->zc_nvlist_dst_size) {
1094 1265 error = ENOMEM;
1095 1266 } else {
1096 - packed = kmem_alloc(size, KM_SLEEP);
1097 - VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE,
1098 - KM_SLEEP) == 0);
1267 + packed = fnvlist_pack(nvl, &size);
1099 1268 if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst,
1100 1269 size, zc->zc_iflags) != 0)
1101 1270 error = EFAULT;
1102 - kmem_free(packed, size);
1271 + fnvlist_pack_free(packed, size);
1103 1272 }
1104 1273
1105 1274 zc->zc_nvlist_dst_size = size;
1275 + zc->zc_nvlist_dst_filled = B_TRUE;
1106 1276 return (error);
1107 1277 }
1108 1278
1109 1279 static int
1110 1280 getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
1111 1281 {
1112 1282 objset_t *os;
1113 1283 int error;
1114 1284
1115 1285 error = dmu_objset_hold(dsname, FTAG, &os);
1116 1286 if (error)
1117 1287 return (error);
1118 1288 if (dmu_objset_type(os) != DMU_OST_ZFS) {
1119 1289 dmu_objset_rele(os, FTAG);
1120 1290 return (EINVAL);
1121 1291 }
1122 1292
1123 1293 mutex_enter(&os->os_user_ptr_lock);
1124 1294 *zfvp = dmu_objset_get_user(os);
1125 1295 if (*zfvp) {
1126 1296 VFS_HOLD((*zfvp)->z_vfs);
1127 1297 } else {
1128 1298 error = ESRCH;
1129 1299 }
1130 1300 mutex_exit(&os->os_user_ptr_lock);
1131 1301 dmu_objset_rele(os, FTAG);
1132 1302 return (error);
1133 1303 }
1134 1304
1135 1305 /*
1136 1306 * Find a zfsvfs_t for a mounted filesystem, or create our own, in which
1137 1307 * case its z_vfs will be NULL, and it will be opened as the owner.
1138 1308 * If 'writer' is set, the z_teardown_lock will be held for RW_WRITER,
1139 1309 * which prevents all vnode ops from running.
1140 1310 */
1141 1311 static int
1142 1312 zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
1143 1313 {
1144 1314 int error = 0;
1145 1315
1146 1316 if (getzfsvfs(name, zfvp) != 0)
1147 1317 error = zfsvfs_create(name, zfvp);
1148 1318 if (error == 0) {
1149 1319 rrw_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
1150 1320 RW_READER, tag);
1151 1321 if ((*zfvp)->z_unmounted) {
1152 1322 /*
1153 1323 * XXX we could probably try again, since the unmounting
1154 1324 * thread should be just about to disassociate the
1155 1325 * objset from the zfsvfs.
1156 1326 */
1157 1327 rrw_exit(&(*zfvp)->z_teardown_lock, tag);
1158 1328 return (EBUSY);
1159 1329 }
1160 1330 }
1161 1331 return (error);
1162 1332 }
1163 1333
1164 1334 static void
1165 1335 zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
1166 1336 {
1167 1337 rrw_exit(&zfsvfs->z_teardown_lock, tag);
1168 1338
1169 1339 if (zfsvfs->z_vfs) {
1170 1340 VFS_RELE(zfsvfs->z_vfs);
1171 1341 } else {
1172 1342 dmu_objset_disown(zfsvfs->z_os, zfsvfs);
1173 1343 zfsvfs_free(zfsvfs);
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
1174 1344 }
1175 1345 }
1176 1346
1177 1347 static int
1178 1348 zfs_ioc_pool_create(zfs_cmd_t *zc)
1179 1349 {
1180 1350 int error;
1181 1351 nvlist_t *config, *props = NULL;
1182 1352 nvlist_t *rootprops = NULL;
1183 1353 nvlist_t *zplprops = NULL;
1184 - char *buf;
1185 1354
1186 1355 if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1187 1356 zc->zc_iflags, &config))
1188 1357 return (error);
1189 1358
1190 1359 if (zc->zc_nvlist_src_size != 0 && (error =
1191 1360 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1192 1361 zc->zc_iflags, &props))) {
1193 1362 nvlist_free(config);
1194 1363 return (error);
1195 1364 }
1196 1365
1197 1366 if (props) {
1198 1367 nvlist_t *nvl = NULL;
1199 1368 uint64_t version = SPA_VERSION;
1200 1369
1201 1370 (void) nvlist_lookup_uint64(props,
1202 1371 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
1203 1372 if (!SPA_VERSION_IS_SUPPORTED(version)) {
1204 1373 error = EINVAL;
1205 1374 goto pool_props_bad;
1206 1375 }
1207 1376 (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
1208 1377 if (nvl) {
1209 1378 error = nvlist_dup(nvl, &rootprops, KM_SLEEP);
1210 1379 if (error != 0) {
1211 1380 nvlist_free(config);
1212 1381 nvlist_free(props);
1213 1382 return (error);
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
1214 1383 }
1215 1384 (void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS);
1216 1385 }
1217 1386 VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1218 1387 error = zfs_fill_zplprops_root(version, rootprops,
1219 1388 zplprops, NULL);
1220 1389 if (error)
1221 1390 goto pool_props_bad;
1222 1391 }
1223 1392
1224 - buf = history_str_get(zc);
1225 -
1226 - error = spa_create(zc->zc_name, config, props, buf, zplprops);
1393 + error = spa_create(zc->zc_name, config, props, zplprops);
1227 1394
1228 1395 /*
1229 1396 * Set the remaining root properties
1230 1397 */
1231 1398 if (!error && (error = zfs_set_prop_nvlist(zc->zc_name,
1232 1399 ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
1233 1400 (void) spa_destroy(zc->zc_name);
1234 1401
1235 - if (buf != NULL)
1236 - history_str_free(buf);
1237 -
1238 1402 pool_props_bad:
1239 1403 nvlist_free(rootprops);
1240 1404 nvlist_free(zplprops);
1241 1405 nvlist_free(config);
1242 1406 nvlist_free(props);
1243 1407
1244 1408 return (error);
1245 1409 }
1246 1410
1247 1411 static int
1248 1412 zfs_ioc_pool_destroy(zfs_cmd_t *zc)
1249 1413 {
1250 1414 int error;
1251 1415 zfs_log_history(zc);
1252 1416 error = spa_destroy(zc->zc_name);
1253 1417 if (error == 0)
1254 1418 zvol_remove_minors(zc->zc_name);
1255 1419 return (error);
1256 1420 }
1257 1421
1258 1422 static int
1259 1423 zfs_ioc_pool_import(zfs_cmd_t *zc)
1260 1424 {
1261 1425 nvlist_t *config, *props = NULL;
1262 1426 uint64_t guid;
1263 1427 int error;
1264 1428
1265 1429 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1266 1430 zc->zc_iflags, &config)) != 0)
1267 1431 return (error);
1268 1432
1269 1433 if (zc->zc_nvlist_src_size != 0 && (error =
1270 1434 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1271 1435 zc->zc_iflags, &props))) {
1272 1436 nvlist_free(config);
1273 1437 return (error);
1274 1438 }
1275 1439
1276 1440 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
1277 1441 guid != zc->zc_guid)
1278 1442 error = EINVAL;
1279 1443 else
1280 1444 error = spa_import(zc->zc_name, config, props, zc->zc_cookie);
1281 1445
1282 1446 if (zc->zc_nvlist_dst != 0) {
1283 1447 int err;
1284 1448
1285 1449 if ((err = put_nvlist(zc, config)) != 0)
1286 1450 error = err;
1287 1451 }
1288 1452
1289 1453 nvlist_free(config);
1290 1454
1291 1455 if (props)
1292 1456 nvlist_free(props);
1293 1457
1294 1458 return (error);
1295 1459 }
1296 1460
1297 1461 static int
1298 1462 zfs_ioc_pool_export(zfs_cmd_t *zc)
1299 1463 {
1300 1464 int error;
1301 1465 boolean_t force = (boolean_t)zc->zc_cookie;
1302 1466 boolean_t hardforce = (boolean_t)zc->zc_guid;
1303 1467
1304 1468 zfs_log_history(zc);
1305 1469 error = spa_export(zc->zc_name, NULL, force, hardforce);
1306 1470 if (error == 0)
1307 1471 zvol_remove_minors(zc->zc_name);
1308 1472 return (error);
1309 1473 }
1310 1474
1311 1475 static int
1312 1476 zfs_ioc_pool_configs(zfs_cmd_t *zc)
1313 1477 {
1314 1478 nvlist_t *configs;
1315 1479 int error;
1316 1480
1317 1481 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
1318 1482 return (EEXIST);
1319 1483
1320 1484 error = put_nvlist(zc, configs);
1321 1485
1322 1486 nvlist_free(configs);
1323 1487
1324 1488 return (error);
1325 1489 }
1326 1490
1327 1491 /*
1328 1492 * inputs:
1329 1493 * zc_name name of the pool
1330 1494 *
1331 1495 * outputs:
1332 1496 * zc_cookie real errno
1333 1497 * zc_nvlist_dst config nvlist
1334 1498 * zc_nvlist_dst_size size of config nvlist
1335 1499 */
1336 1500 static int
1337 1501 zfs_ioc_pool_stats(zfs_cmd_t *zc)
1338 1502 {
1339 1503 nvlist_t *config;
1340 1504 int error;
1341 1505 int ret = 0;
1342 1506
1343 1507 error = spa_get_stats(zc->zc_name, &config, zc->zc_value,
1344 1508 sizeof (zc->zc_value));
1345 1509
1346 1510 if (config != NULL) {
1347 1511 ret = put_nvlist(zc, config);
1348 1512 nvlist_free(config);
1349 1513
1350 1514 /*
1351 1515 * The config may be present even if 'error' is non-zero.
1352 1516 * In this case we return success, and preserve the real errno
1353 1517 * in 'zc_cookie'.
1354 1518 */
1355 1519 zc->zc_cookie = error;
1356 1520 } else {
1357 1521 ret = error;
1358 1522 }
1359 1523
1360 1524 return (ret);
1361 1525 }
1362 1526
1363 1527 /*
1364 1528 * Try to import the given pool, returning pool stats as appropriate so that
1365 1529 * user land knows which devices are available and overall pool health.
1366 1530 */
1367 1531 static int
1368 1532 zfs_ioc_pool_tryimport(zfs_cmd_t *zc)
1369 1533 {
1370 1534 nvlist_t *tryconfig, *config;
1371 1535 int error;
1372 1536
1373 1537 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1374 1538 zc->zc_iflags, &tryconfig)) != 0)
1375 1539 return (error);
1376 1540
1377 1541 config = spa_tryimport(tryconfig);
1378 1542
1379 1543 nvlist_free(tryconfig);
1380 1544
1381 1545 if (config == NULL)
1382 1546 return (EINVAL);
1383 1547
1384 1548 error = put_nvlist(zc, config);
1385 1549 nvlist_free(config);
1386 1550
1387 1551 return (error);
1388 1552 }
1389 1553
1390 1554 /*
1391 1555 * inputs:
1392 1556 * zc_name name of the pool
1393 1557 * zc_cookie scan func (pool_scan_func_t)
1394 1558 */
1395 1559 static int
1396 1560 zfs_ioc_pool_scan(zfs_cmd_t *zc)
1397 1561 {
1398 1562 spa_t *spa;
1399 1563 int error;
1400 1564
1401 1565 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1402 1566 return (error);
1403 1567
1404 1568 if (zc->zc_cookie == POOL_SCAN_NONE)
1405 1569 error = spa_scan_stop(spa);
1406 1570 else
1407 1571 error = spa_scan(spa, zc->zc_cookie);
1408 1572
1409 1573 spa_close(spa, FTAG);
1410 1574
1411 1575 return (error);
1412 1576 }
1413 1577
1414 1578 static int
1415 1579 zfs_ioc_pool_freeze(zfs_cmd_t *zc)
1416 1580 {
1417 1581 spa_t *spa;
1418 1582 int error;
1419 1583
1420 1584 error = spa_open(zc->zc_name, &spa, FTAG);
1421 1585 if (error == 0) {
1422 1586 spa_freeze(spa);
1423 1587 spa_close(spa, FTAG);
1424 1588 }
1425 1589 return (error);
1426 1590 }
1427 1591
1428 1592 static int
1429 1593 zfs_ioc_pool_upgrade(zfs_cmd_t *zc)
1430 1594 {
1431 1595 spa_t *spa;
1432 1596 int error;
1433 1597
1434 1598 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1435 1599 return (error);
1436 1600
1437 1601 if (zc->zc_cookie < spa_version(spa) ||
1438 1602 !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
1439 1603 spa_close(spa, FTAG);
1440 1604 return (EINVAL);
1441 1605 }
1442 1606
1443 1607 spa_upgrade(spa, zc->zc_cookie);
1444 1608 spa_close(spa, FTAG);
1445 1609
1446 1610 return (error);
1447 1611 }
1448 1612
1449 1613 static int
1450 1614 zfs_ioc_pool_get_history(zfs_cmd_t *zc)
1451 1615 {
1452 1616 spa_t *spa;
1453 1617 char *hist_buf;
1454 1618 uint64_t size;
1455 1619 int error;
1456 1620
1457 1621 if ((size = zc->zc_history_len) == 0)
1458 1622 return (EINVAL);
1459 1623
1460 1624 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1461 1625 return (error);
1462 1626
1463 1627 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
1464 1628 spa_close(spa, FTAG);
1465 1629 return (ENOTSUP);
1466 1630 }
1467 1631
1468 1632 hist_buf = kmem_alloc(size, KM_SLEEP);
1469 1633 if ((error = spa_history_get(spa, &zc->zc_history_offset,
1470 1634 &zc->zc_history_len, hist_buf)) == 0) {
1471 1635 error = ddi_copyout(hist_buf,
1472 1636 (void *)(uintptr_t)zc->zc_history,
1473 1637 zc->zc_history_len, zc->zc_iflags);
1474 1638 }
1475 1639
1476 1640 spa_close(spa, FTAG);
1477 1641 kmem_free(hist_buf, size);
1478 1642 return (error);
1479 1643 }
1480 1644
1481 1645 static int
1482 1646 zfs_ioc_pool_reguid(zfs_cmd_t *zc)
1483 1647 {
1484 1648 spa_t *spa;
1485 1649 int error;
1486 1650
1487 1651 error = spa_open(zc->zc_name, &spa, FTAG);
1488 1652 if (error == 0) {
1489 1653 error = spa_change_guid(spa);
1490 1654 spa_close(spa, FTAG);
1491 1655 }
1492 1656 return (error);
1493 1657 }
1494 1658
1495 1659 static int
1496 1660 zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
1497 1661 {
1498 1662 int error;
1499 1663
1500 1664 if (error = dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value))
1501 1665 return (error);
1502 1666
1503 1667 return (0);
1504 1668 }
1505 1669
1506 1670 /*
1507 1671 * inputs:
1508 1672 * zc_name name of filesystem
1509 1673 * zc_obj object to find
1510 1674 *
1511 1675 * outputs:
1512 1676 * zc_value name of object
1513 1677 */
1514 1678 static int
1515 1679 zfs_ioc_obj_to_path(zfs_cmd_t *zc)
1516 1680 {
1517 1681 objset_t *os;
1518 1682 int error;
1519 1683
1520 1684 /* XXX reading from objset not owned */
1521 1685 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
1522 1686 return (error);
1523 1687 if (dmu_objset_type(os) != DMU_OST_ZFS) {
1524 1688 dmu_objset_rele(os, FTAG);
1525 1689 return (EINVAL);
1526 1690 }
1527 1691 error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value,
1528 1692 sizeof (zc->zc_value));
1529 1693 dmu_objset_rele(os, FTAG);
1530 1694
1531 1695 return (error);
1532 1696 }
1533 1697
1534 1698 /*
1535 1699 * inputs:
1536 1700 * zc_name name of filesystem
1537 1701 * zc_obj object to find
1538 1702 *
1539 1703 * outputs:
1540 1704 * zc_stat stats on object
1541 1705 * zc_value path to object
1542 1706 */
1543 1707 static int
1544 1708 zfs_ioc_obj_to_stats(zfs_cmd_t *zc)
1545 1709 {
1546 1710 objset_t *os;
1547 1711 int error;
1548 1712
1549 1713 /* XXX reading from objset not owned */
1550 1714 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
1551 1715 return (error);
1552 1716 if (dmu_objset_type(os) != DMU_OST_ZFS) {
1553 1717 dmu_objset_rele(os, FTAG);
1554 1718 return (EINVAL);
1555 1719 }
1556 1720 error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value,
1557 1721 sizeof (zc->zc_value));
1558 1722 dmu_objset_rele(os, FTAG);
1559 1723
1560 1724 return (error);
1561 1725 }
1562 1726
1563 1727 static int
1564 1728 zfs_ioc_vdev_add(zfs_cmd_t *zc)
1565 1729 {
1566 1730 spa_t *spa;
1567 1731 int error;
1568 1732 nvlist_t *config, **l2cache, **spares;
1569 1733 uint_t nl2cache = 0, nspares = 0;
1570 1734
1571 1735 error = spa_open(zc->zc_name, &spa, FTAG);
1572 1736 if (error != 0)
1573 1737 return (error);
1574 1738
1575 1739 error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1576 1740 zc->zc_iflags, &config);
1577 1741 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE,
1578 1742 &l2cache, &nl2cache);
1579 1743
1580 1744 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES,
1581 1745 &spares, &nspares);
1582 1746
1583 1747 /*
1584 1748 * A root pool with concatenated devices is not supported.
1585 1749 * Thus, can not add a device to a root pool.
1586 1750 *
1587 1751 * Intent log device can not be added to a rootpool because
1588 1752 * during mountroot, zil is replayed, a seperated log device
1589 1753 * can not be accessed during the mountroot time.
1590 1754 *
1591 1755 * l2cache and spare devices are ok to be added to a rootpool.
1592 1756 */
1593 1757 if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) {
1594 1758 nvlist_free(config);
1595 1759 spa_close(spa, FTAG);
1596 1760 return (EDOM);
1597 1761 }
1598 1762
1599 1763 if (error == 0) {
1600 1764 error = spa_vdev_add(spa, config);
1601 1765 nvlist_free(config);
1602 1766 }
1603 1767 spa_close(spa, FTAG);
1604 1768 return (error);
1605 1769 }
1606 1770
1607 1771 /*
1608 1772 * inputs:
1609 1773 * zc_name name of the pool
1610 1774 * zc_nvlist_conf nvlist of devices to remove
1611 1775 * zc_cookie to stop the remove?
1612 1776 */
1613 1777 static int
1614 1778 zfs_ioc_vdev_remove(zfs_cmd_t *zc)
1615 1779 {
1616 1780 spa_t *spa;
1617 1781 int error;
1618 1782
1619 1783 error = spa_open(zc->zc_name, &spa, FTAG);
1620 1784 if (error != 0)
1621 1785 return (error);
1622 1786 error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE);
1623 1787 spa_close(spa, FTAG);
1624 1788 return (error);
1625 1789 }
1626 1790
1627 1791 static int
1628 1792 zfs_ioc_vdev_set_state(zfs_cmd_t *zc)
1629 1793 {
1630 1794 spa_t *spa;
1631 1795 int error;
1632 1796 vdev_state_t newstate = VDEV_STATE_UNKNOWN;
1633 1797
1634 1798 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1635 1799 return (error);
1636 1800 switch (zc->zc_cookie) {
1637 1801 case VDEV_STATE_ONLINE:
1638 1802 error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate);
1639 1803 break;
1640 1804
1641 1805 case VDEV_STATE_OFFLINE:
1642 1806 error = vdev_offline(spa, zc->zc_guid, zc->zc_obj);
1643 1807 break;
1644 1808
1645 1809 case VDEV_STATE_FAULTED:
1646 1810 if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
1647 1811 zc->zc_obj != VDEV_AUX_EXTERNAL)
1648 1812 zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
1649 1813
1650 1814 error = vdev_fault(spa, zc->zc_guid, zc->zc_obj);
1651 1815 break;
1652 1816
1653 1817 case VDEV_STATE_DEGRADED:
1654 1818 if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
1655 1819 zc->zc_obj != VDEV_AUX_EXTERNAL)
1656 1820 zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
1657 1821
1658 1822 error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj);
1659 1823 break;
1660 1824
1661 1825 default:
1662 1826 error = EINVAL;
1663 1827 }
1664 1828 zc->zc_cookie = newstate;
1665 1829 spa_close(spa, FTAG);
1666 1830 return (error);
1667 1831 }
1668 1832
1669 1833 static int
1670 1834 zfs_ioc_vdev_attach(zfs_cmd_t *zc)
1671 1835 {
1672 1836 spa_t *spa;
1673 1837 int replacing = zc->zc_cookie;
1674 1838 nvlist_t *config;
1675 1839 int error;
1676 1840
1677 1841 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1678 1842 return (error);
1679 1843
1680 1844 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1681 1845 zc->zc_iflags, &config)) == 0) {
1682 1846 error = spa_vdev_attach(spa, zc->zc_guid, config, replacing);
1683 1847 nvlist_free(config);
1684 1848 }
1685 1849
1686 1850 spa_close(spa, FTAG);
1687 1851 return (error);
1688 1852 }
1689 1853
1690 1854 static int
1691 1855 zfs_ioc_vdev_detach(zfs_cmd_t *zc)
1692 1856 {
1693 1857 spa_t *spa;
1694 1858 int error;
1695 1859
1696 1860 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1697 1861 return (error);
1698 1862
1699 1863 error = spa_vdev_detach(spa, zc->zc_guid, 0, B_FALSE);
1700 1864
1701 1865 spa_close(spa, FTAG);
1702 1866 return (error);
1703 1867 }
1704 1868
1705 1869 static int
1706 1870 zfs_ioc_vdev_split(zfs_cmd_t *zc)
1707 1871 {
1708 1872 spa_t *spa;
1709 1873 nvlist_t *config, *props = NULL;
1710 1874 int error;
1711 1875 boolean_t exp = !!(zc->zc_cookie & ZPOOL_EXPORT_AFTER_SPLIT);
1712 1876
1713 1877 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1714 1878 return (error);
1715 1879
1716 1880 if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1717 1881 zc->zc_iflags, &config)) {
1718 1882 spa_close(spa, FTAG);
1719 1883 return (error);
1720 1884 }
1721 1885
1722 1886 if (zc->zc_nvlist_src_size != 0 && (error =
1723 1887 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1724 1888 zc->zc_iflags, &props))) {
1725 1889 spa_close(spa, FTAG);
1726 1890 nvlist_free(config);
1727 1891 return (error);
1728 1892 }
1729 1893
1730 1894 error = spa_vdev_split_mirror(spa, zc->zc_string, config, props, exp);
1731 1895
1732 1896 spa_close(spa, FTAG);
1733 1897
1734 1898 nvlist_free(config);
1735 1899 nvlist_free(props);
1736 1900
1737 1901 return (error);
1738 1902 }
1739 1903
1740 1904 static int
1741 1905 zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
1742 1906 {
1743 1907 spa_t *spa;
1744 1908 char *path = zc->zc_value;
1745 1909 uint64_t guid = zc->zc_guid;
1746 1910 int error;
1747 1911
1748 1912 error = spa_open(zc->zc_name, &spa, FTAG);
1749 1913 if (error != 0)
1750 1914 return (error);
1751 1915
1752 1916 error = spa_vdev_setpath(spa, guid, path);
1753 1917 spa_close(spa, FTAG);
1754 1918 return (error);
1755 1919 }
1756 1920
1757 1921 static int
1758 1922 zfs_ioc_vdev_setfru(zfs_cmd_t *zc)
1759 1923 {
1760 1924 spa_t *spa;
1761 1925 char *fru = zc->zc_value;
1762 1926 uint64_t guid = zc->zc_guid;
1763 1927 int error;
1764 1928
1765 1929 error = spa_open(zc->zc_name, &spa, FTAG);
1766 1930 if (error != 0)
1767 1931 return (error);
1768 1932
1769 1933 error = spa_vdev_setfru(spa, guid, fru);
1770 1934 spa_close(spa, FTAG);
1771 1935 return (error);
1772 1936 }
1773 1937
1774 1938 static int
1775 1939 zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
1776 1940 {
1777 1941 int error = 0;
1778 1942 nvlist_t *nv;
1779 1943
1780 1944 dmu_objset_fast_stat(os, &zc->zc_objset_stats);
1781 1945
1782 1946 if (zc->zc_nvlist_dst != 0 &&
1783 1947 (error = dsl_prop_get_all(os, &nv)) == 0) {
1784 1948 dmu_objset_stats(os, nv);
1785 1949 /*
1786 1950 * NB: zvol_get_stats() will read the objset contents,
1787 1951 * which we aren't supposed to do with a
1788 1952 * DS_MODE_USER hold, because it could be
1789 1953 * inconsistent. So this is a bit of a workaround...
1790 1954 * XXX reading with out owning
1791 1955 */
1792 1956 if (!zc->zc_objset_stats.dds_inconsistent &&
1793 1957 dmu_objset_type(os) == DMU_OST_ZVOL) {
1794 1958 error = zvol_get_stats(os, nv);
1795 1959 if (error == EIO)
1796 1960 return (error);
1797 1961 VERIFY3S(error, ==, 0);
1798 1962 }
1799 1963 error = put_nvlist(zc, nv);
1800 1964 nvlist_free(nv);
1801 1965 }
1802 1966
1803 1967 return (error);
1804 1968 }
1805 1969
1806 1970 /*
1807 1971 * inputs:
1808 1972 * zc_name name of filesystem
1809 1973 * zc_nvlist_dst_size size of buffer for property nvlist
1810 1974 *
1811 1975 * outputs:
1812 1976 * zc_objset_stats stats
1813 1977 * zc_nvlist_dst property nvlist
1814 1978 * zc_nvlist_dst_size size of property nvlist
1815 1979 */
1816 1980 static int
1817 1981 zfs_ioc_objset_stats(zfs_cmd_t *zc)
1818 1982 {
1819 1983 objset_t *os = NULL;
1820 1984 int error;
1821 1985
1822 1986 if (error = dmu_objset_hold(zc->zc_name, FTAG, &os))
1823 1987 return (error);
1824 1988
1825 1989 error = zfs_ioc_objset_stats_impl(zc, os);
1826 1990
1827 1991 dmu_objset_rele(os, FTAG);
1828 1992
1829 1993 return (error);
1830 1994 }
1831 1995
1832 1996 /*
1833 1997 * inputs:
1834 1998 * zc_name name of filesystem
1835 1999 * zc_nvlist_dst_size size of buffer for property nvlist
1836 2000 *
1837 2001 * outputs:
1838 2002 * zc_nvlist_dst received property nvlist
1839 2003 * zc_nvlist_dst_size size of received property nvlist
1840 2004 *
1841 2005 * Gets received properties (distinct from local properties on or after
1842 2006 * SPA_VERSION_RECVD_PROPS) for callers who want to differentiate received from
1843 2007 * local property values.
1844 2008 */
1845 2009 static int
1846 2010 zfs_ioc_objset_recvd_props(zfs_cmd_t *zc)
1847 2011 {
1848 2012 objset_t *os = NULL;
1849 2013 int error;
1850 2014 nvlist_t *nv;
1851 2015
1852 2016 if (error = dmu_objset_hold(zc->zc_name, FTAG, &os))
1853 2017 return (error);
1854 2018
1855 2019 /*
1856 2020 * Without this check, we would return local property values if the
1857 2021 * caller has not already received properties on or after
1858 2022 * SPA_VERSION_RECVD_PROPS.
1859 2023 */
1860 2024 if (!dsl_prop_get_hasrecvd(os)) {
1861 2025 dmu_objset_rele(os, FTAG);
1862 2026 return (ENOTSUP);
1863 2027 }
1864 2028
1865 2029 if (zc->zc_nvlist_dst != 0 &&
1866 2030 (error = dsl_prop_get_received(os, &nv)) == 0) {
1867 2031 error = put_nvlist(zc, nv);
1868 2032 nvlist_free(nv);
1869 2033 }
1870 2034
1871 2035 dmu_objset_rele(os, FTAG);
1872 2036 return (error);
1873 2037 }
1874 2038
1875 2039 static int
1876 2040 nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop)
1877 2041 {
1878 2042 uint64_t value;
1879 2043 int error;
1880 2044
1881 2045 /*
1882 2046 * zfs_get_zplprop() will either find a value or give us
1883 2047 * the default value (if there is one).
1884 2048 */
1885 2049 if ((error = zfs_get_zplprop(os, prop, &value)) != 0)
1886 2050 return (error);
1887 2051 VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0);
1888 2052 return (0);
1889 2053 }
1890 2054
1891 2055 /*
1892 2056 * inputs:
1893 2057 * zc_name name of filesystem
1894 2058 * zc_nvlist_dst_size size of buffer for zpl property nvlist
1895 2059 *
1896 2060 * outputs:
1897 2061 * zc_nvlist_dst zpl property nvlist
1898 2062 * zc_nvlist_dst_size size of zpl property nvlist
1899 2063 */
1900 2064 static int
1901 2065 zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
1902 2066 {
1903 2067 objset_t *os;
1904 2068 int err;
1905 2069
1906 2070 /* XXX reading without owning */
1907 2071 if (err = dmu_objset_hold(zc->zc_name, FTAG, &os))
1908 2072 return (err);
1909 2073
1910 2074 dmu_objset_fast_stat(os, &zc->zc_objset_stats);
1911 2075
1912 2076 /*
1913 2077 * NB: nvl_add_zplprop() will read the objset contents,
1914 2078 * which we aren't supposed to do with a DS_MODE_USER
1915 2079 * hold, because it could be inconsistent.
1916 2080 */
1917 2081 if (zc->zc_nvlist_dst != NULL &&
1918 2082 !zc->zc_objset_stats.dds_inconsistent &&
1919 2083 dmu_objset_type(os) == DMU_OST_ZFS) {
1920 2084 nvlist_t *nv;
1921 2085
1922 2086 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1923 2087 if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 &&
1924 2088 (err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 &&
1925 2089 (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 &&
1926 2090 (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0)
1927 2091 err = put_nvlist(zc, nv);
1928 2092 nvlist_free(nv);
1929 2093 } else {
1930 2094 err = ENOENT;
1931 2095 }
1932 2096 dmu_objset_rele(os, FTAG);
1933 2097 return (err);
1934 2098 }
1935 2099
1936 2100 static boolean_t
1937 2101 dataset_name_hidden(const char *name)
1938 2102 {
1939 2103 /*
1940 2104 * Skip over datasets that are not visible in this zone,
1941 2105 * internal datasets (which have a $ in their name), and
1942 2106 * temporary datasets (which have a % in their name).
1943 2107 */
1944 2108 if (strchr(name, '$') != NULL)
1945 2109 return (B_TRUE);
1946 2110 if (strchr(name, '%') != NULL)
1947 2111 return (B_TRUE);
1948 2112 if (!INGLOBALZONE(curproc) && !zone_dataset_visible(name, NULL))
1949 2113 return (B_TRUE);
1950 2114 return (B_FALSE);
1951 2115 }
1952 2116
1953 2117 /*
1954 2118 * inputs:
1955 2119 * zc_name name of filesystem
1956 2120 * zc_cookie zap cursor
1957 2121 * zc_nvlist_dst_size size of buffer for property nvlist
1958 2122 *
1959 2123 * outputs:
1960 2124 * zc_name name of next filesystem
1961 2125 * zc_cookie zap cursor
1962 2126 * zc_objset_stats stats
1963 2127 * zc_nvlist_dst property nvlist
1964 2128 * zc_nvlist_dst_size size of property nvlist
1965 2129 */
1966 2130 static int
1967 2131 zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
1968 2132 {
1969 2133 objset_t *os;
1970 2134 int error;
1971 2135 char *p;
1972 2136 size_t orig_len = strlen(zc->zc_name);
1973 2137
1974 2138 top:
1975 2139 if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) {
1976 2140 if (error == ENOENT)
1977 2141 error = ESRCH;
1978 2142 return (error);
1979 2143 }
1980 2144
1981 2145 p = strrchr(zc->zc_name, '/');
1982 2146 if (p == NULL || p[1] != '\0')
1983 2147 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
1984 2148 p = zc->zc_name + strlen(zc->zc_name);
1985 2149
1986 2150 /*
1987 2151 * Pre-fetch the datasets. dmu_objset_prefetch() always returns 0
1988 2152 * but is not declared void because its called by dmu_objset_find().
1989 2153 */
1990 2154 if (zc->zc_cookie == 0) {
1991 2155 uint64_t cookie = 0;
1992 2156 int len = sizeof (zc->zc_name) - (p - zc->zc_name);
1993 2157
1994 2158 while (dmu_dir_list_next(os, len, p, NULL, &cookie) == 0) {
1995 2159 if (!dataset_name_hidden(zc->zc_name))
1996 2160 (void) dmu_objset_prefetch(zc->zc_name, NULL);
1997 2161 }
1998 2162 }
1999 2163
2000 2164 do {
2001 2165 error = dmu_dir_list_next(os,
2002 2166 sizeof (zc->zc_name) - (p - zc->zc_name), p,
2003 2167 NULL, &zc->zc_cookie);
2004 2168 if (error == ENOENT)
2005 2169 error = ESRCH;
2006 2170 } while (error == 0 && dataset_name_hidden(zc->zc_name));
2007 2171 dmu_objset_rele(os, FTAG);
2008 2172
2009 2173 /*
2010 2174 * If it's an internal dataset (ie. with a '$' in its name),
2011 2175 * don't try to get stats for it, otherwise we'll return ENOENT.
2012 2176 */
2013 2177 if (error == 0 && strchr(zc->zc_name, '$') == NULL) {
2014 2178 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
2015 2179 if (error == ENOENT) {
2016 2180 /* We lost a race with destroy, get the next one. */
2017 2181 zc->zc_name[orig_len] = '\0';
2018 2182 goto top;
2019 2183 }
2020 2184 }
2021 2185 return (error);
2022 2186 }
2023 2187
2024 2188 /*
2025 2189 * inputs:
2026 2190 * zc_name name of filesystem
2027 2191 * zc_cookie zap cursor
2028 2192 * zc_nvlist_dst_size size of buffer for property nvlist
2029 2193 *
2030 2194 * outputs:
2031 2195 * zc_name name of next snapshot
2032 2196 * zc_objset_stats stats
2033 2197 * zc_nvlist_dst property nvlist
2034 2198 * zc_nvlist_dst_size size of property nvlist
2035 2199 */
2036 2200 static int
2037 2201 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
2038 2202 {
2039 2203 objset_t *os;
2040 2204 int error;
2041 2205
2042 2206 top:
2043 2207 if (zc->zc_cookie == 0)
2044 2208 (void) dmu_objset_find(zc->zc_name, dmu_objset_prefetch,
2045 2209 NULL, DS_FIND_SNAPSHOTS);
2046 2210
2047 2211 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
2048 2212 if (error)
2049 2213 return (error == ENOENT ? ESRCH : error);
2050 2214
2051 2215 /*
2052 2216 * A dataset name of maximum length cannot have any snapshots,
2053 2217 * so exit immediately.
2054 2218 */
2055 2219 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
2056 2220 dmu_objset_rele(os, FTAG);
2057 2221 return (ESRCH);
2058 2222 }
2059 2223
2060 2224 error = dmu_snapshot_list_next(os,
2061 2225 sizeof (zc->zc_name) - strlen(zc->zc_name),
2062 2226 zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie,
2063 2227 NULL);
2064 2228
2065 2229 if (error == 0) {
2066 2230 dsl_dataset_t *ds;
2067 2231 dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
2068 2232
2069 2233 /*
2070 2234 * Since we probably don't have a hold on this snapshot,
2071 2235 * it's possible that the objsetid could have been destroyed
2072 2236 * and reused for a new objset. It's OK if this happens during
2073 2237 * a zfs send operation, since the new createtxg will be
2074 2238 * beyond the range we're interested in.
2075 2239 */
2076 2240 rw_enter(&dp->dp_config_rwlock, RW_READER);
2077 2241 error = dsl_dataset_hold_obj(dp, zc->zc_obj, FTAG, &ds);
2078 2242 rw_exit(&dp->dp_config_rwlock);
2079 2243 if (error) {
2080 2244 if (error == ENOENT) {
2081 2245 /* Racing with destroy, get the next one. */
2082 2246 *strchr(zc->zc_name, '@') = '\0';
2083 2247 dmu_objset_rele(os, FTAG);
2084 2248 goto top;
2085 2249 }
2086 2250 } else {
2087 2251 objset_t *ossnap;
2088 2252
2089 2253 error = dmu_objset_from_ds(ds, &ossnap);
2090 2254 if (error == 0)
2091 2255 error = zfs_ioc_objset_stats_impl(zc, ossnap);
2092 2256 dsl_dataset_rele(ds, FTAG);
2093 2257 }
2094 2258 } else if (error == ENOENT) {
2095 2259 error = ESRCH;
2096 2260 }
2097 2261
2098 2262 dmu_objset_rele(os, FTAG);
2099 2263 /* if we failed, undo the @ that we tacked on to zc_name */
2100 2264 if (error)
2101 2265 *strchr(zc->zc_name, '@') = '\0';
2102 2266 return (error);
2103 2267 }
2104 2268
2105 2269 static int
2106 2270 zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
2107 2271 {
2108 2272 const char *propname = nvpair_name(pair);
2109 2273 uint64_t *valary;
2110 2274 unsigned int vallen;
2111 2275 const char *domain;
2112 2276 char *dash;
2113 2277 zfs_userquota_prop_t type;
2114 2278 uint64_t rid;
2115 2279 uint64_t quota;
2116 2280 zfsvfs_t *zfsvfs;
2117 2281 int err;
2118 2282
2119 2283 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2120 2284 nvlist_t *attrs;
2121 2285 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
2122 2286 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2123 2287 &pair) != 0)
2124 2288 return (EINVAL);
2125 2289 }
2126 2290
2127 2291 /*
2128 2292 * A correctly constructed propname is encoded as
2129 2293 * userquota@<rid>-<domain>.
2130 2294 */
2131 2295 if ((dash = strchr(propname, '-')) == NULL ||
2132 2296 nvpair_value_uint64_array(pair, &valary, &vallen) != 0 ||
2133 2297 vallen != 3)
2134 2298 return (EINVAL);
2135 2299
2136 2300 domain = dash + 1;
2137 2301 type = valary[0];
2138 2302 rid = valary[1];
2139 2303 quota = valary[2];
2140 2304
2141 2305 err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE);
2142 2306 if (err == 0) {
2143 2307 err = zfs_set_userquota(zfsvfs, type, domain, rid, quota);
2144 2308 zfsvfs_rele(zfsvfs, FTAG);
2145 2309 }
2146 2310
2147 2311 return (err);
2148 2312 }
2149 2313
2150 2314 /*
2151 2315 * If the named property is one that has a special function to set its value,
2152 2316 * return 0 on success and a positive error code on failure; otherwise if it is
2153 2317 * not one of the special properties handled by this function, return -1.
2154 2318 *
2155 2319 * XXX: It would be better for callers of the property interface if we handled
2156 2320 * these special cases in dsl_prop.c (in the dsl layer).
2157 2321 */
2158 2322 static int
2159 2323 zfs_prop_set_special(const char *dsname, zprop_source_t source,
2160 2324 nvpair_t *pair)
2161 2325 {
2162 2326 const char *propname = nvpair_name(pair);
2163 2327 zfs_prop_t prop = zfs_name_to_prop(propname);
2164 2328 uint64_t intval;
2165 2329 int err;
2166 2330
2167 2331 if (prop == ZPROP_INVAL) {
2168 2332 if (zfs_prop_userquota(propname))
2169 2333 return (zfs_prop_set_userquota(dsname, pair));
2170 2334 return (-1);
2171 2335 }
2172 2336
2173 2337 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2174 2338 nvlist_t *attrs;
2175 2339 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
2176 2340 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2177 2341 &pair) == 0);
2178 2342 }
2179 2343
2180 2344 if (zfs_prop_get_type(prop) == PROP_TYPE_STRING)
2181 2345 return (-1);
2182 2346
2183 2347 VERIFY(0 == nvpair_value_uint64(pair, &intval));
2184 2348
2185 2349 switch (prop) {
2186 2350 case ZFS_PROP_QUOTA:
2187 2351 err = dsl_dir_set_quota(dsname, source, intval);
2188 2352 break;
2189 2353 case ZFS_PROP_REFQUOTA:
2190 2354 err = dsl_dataset_set_quota(dsname, source, intval);
2191 2355 break;
2192 2356 case ZFS_PROP_RESERVATION:
2193 2357 err = dsl_dir_set_reservation(dsname, source, intval);
2194 2358 break;
2195 2359 case ZFS_PROP_REFRESERVATION:
2196 2360 err = dsl_dataset_set_reservation(dsname, source, intval);
2197 2361 break;
2198 2362 case ZFS_PROP_VOLSIZE:
2199 2363 err = zvol_set_volsize(dsname, ddi_driver_major(zfs_dip),
2200 2364 intval);
2201 2365 break;
2202 2366 case ZFS_PROP_VERSION:
2203 2367 {
2204 2368 zfsvfs_t *zfsvfs;
2205 2369
2206 2370 if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
2207 2371 break;
2208 2372
2209 2373 err = zfs_set_version(zfsvfs, intval);
2210 2374 zfsvfs_rele(zfsvfs, FTAG);
2211 2375
2212 2376 if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
2213 2377 zfs_cmd_t *zc;
2214 2378
2215 2379 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
2216 2380 (void) strcpy(zc->zc_name, dsname);
2217 2381 (void) zfs_ioc_userspace_upgrade(zc);
2218 2382 kmem_free(zc, sizeof (zfs_cmd_t));
2219 2383 }
2220 2384 break;
2221 2385 }
↓ open down ↓ |
974 lines elided |
↑ open up ↑ |
2222 2386
2223 2387 default:
2224 2388 err = -1;
2225 2389 }
2226 2390
2227 2391 return (err);
2228 2392 }
2229 2393
2230 2394 /*
2231 2395 * This function is best effort. If it fails to set any of the given properties,
2232 - * it continues to set as many as it can and returns the first error
2233 - * encountered. If the caller provides a non-NULL errlist, it also gives the
2234 - * complete list of names of all the properties it failed to set along with the
2235 - * corresponding error numbers. The caller is responsible for freeing the
2236 - * returned errlist.
2396 + * it continues to set as many as it can and returns the last error
2397 + * encountered. If the caller provides a non-NULL errlist, it will be filled in
2398 + * with the list of names of all the properties that failed along with the
2399 + * corresponding error numbers.
2237 2400 *
2238 - * If every property is set successfully, zero is returned and the list pointed
2239 - * at by errlist is NULL.
2401 + * If every property is set successfully, zero is returned and errlist is not
2402 + * modified.
2240 2403 */
2241 2404 int
2242 2405 zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl,
2243 - nvlist_t **errlist)
2406 + nvlist_t *errlist)
2244 2407 {
2245 2408 nvpair_t *pair;
2246 2409 nvpair_t *propval;
2247 2410 int rv = 0;
2248 2411 uint64_t intval;
2249 2412 char *strval;
2250 - nvlist_t *genericnvl;
2251 - nvlist_t *errors;
2252 - nvlist_t *retrynvl;
2253 -
2254 - VERIFY(nvlist_alloc(&genericnvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2255 - VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2256 - VERIFY(nvlist_alloc(&retrynvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2413 + nvlist_t *genericnvl = fnvlist_alloc();
2414 + nvlist_t *retrynvl = fnvlist_alloc();
2257 2415
2258 2416 retry:
2259 2417 pair = NULL;
2260 2418 while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
2261 2419 const char *propname = nvpair_name(pair);
2262 2420 zfs_prop_t prop = zfs_name_to_prop(propname);
2263 2421 int err = 0;
2264 2422
2265 2423 /* decode the property value */
2266 2424 propval = pair;
2267 2425 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2268 2426 nvlist_t *attrs;
2269 - VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
2427 + attrs = fnvpair_value_nvlist(pair);
2270 2428 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2271 2429 &propval) != 0)
2272 2430 err = EINVAL;
2273 2431 }
2274 2432
2275 2433 /* Validate value type */
2276 2434 if (err == 0 && prop == ZPROP_INVAL) {
2277 2435 if (zfs_prop_user(propname)) {
2278 2436 if (nvpair_type(propval) != DATA_TYPE_STRING)
2279 2437 err = EINVAL;
2280 2438 } else if (zfs_prop_userquota(propname)) {
2281 2439 if (nvpair_type(propval) !=
2282 2440 DATA_TYPE_UINT64_ARRAY)
2283 2441 err = EINVAL;
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
2284 2442 } else {
2285 2443 err = EINVAL;
2286 2444 }
2287 2445 } else if (err == 0) {
2288 2446 if (nvpair_type(propval) == DATA_TYPE_STRING) {
2289 2447 if (zfs_prop_get_type(prop) != PROP_TYPE_STRING)
2290 2448 err = EINVAL;
2291 2449 } else if (nvpair_type(propval) == DATA_TYPE_UINT64) {
2292 2450 const char *unused;
2293 2451
2294 - VERIFY(nvpair_value_uint64(propval,
2295 - &intval) == 0);
2452 + intval = fnvpair_value_uint64(propval);
2296 2453
2297 2454 switch (zfs_prop_get_type(prop)) {
2298 2455 case PROP_TYPE_NUMBER:
2299 2456 break;
2300 2457 case PROP_TYPE_STRING:
2301 2458 err = EINVAL;
2302 2459 break;
2303 2460 case PROP_TYPE_INDEX:
2304 2461 if (zfs_prop_index_to_string(prop,
2305 2462 intval, &unused) != 0)
2306 2463 err = EINVAL;
2307 2464 break;
2308 2465 default:
2309 2466 cmn_err(CE_PANIC,
2310 2467 "unknown property type");
2311 2468 }
2312 2469 } else {
2313 2470 err = EINVAL;
2314 2471 }
2315 2472 }
2316 2473
2317 2474 /* Validate permissions */
2318 2475 if (err == 0)
2319 2476 err = zfs_check_settable(dsname, pair, CRED());
2320 2477
2321 2478 if (err == 0) {
2322 2479 err = zfs_prop_set_special(dsname, source, pair);
2323 2480 if (err == -1) {
2324 2481 /*
2325 2482 * For better performance we build up a list of
2326 2483 * properties to set in a single transaction.
2327 2484 */
2328 2485 err = nvlist_add_nvpair(genericnvl, pair);
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
2329 2486 } else if (err != 0 && nvl != retrynvl) {
2330 2487 /*
2331 2488 * This may be a spurious error caused by
2332 2489 * receiving quota and reservation out of order.
2333 2490 * Try again in a second pass.
2334 2491 */
2335 2492 err = nvlist_add_nvpair(retrynvl, pair);
2336 2493 }
2337 2494 }
2338 2495
2339 - if (err != 0)
2340 - VERIFY(nvlist_add_int32(errors, propname, err) == 0);
2496 + if (err != 0) {
2497 + if (errlist != NULL)
2498 + fnvlist_add_int32(errlist, propname, err);
2499 + rv = err;
2500 + }
2341 2501 }
2342 2502
2343 2503 if (nvl != retrynvl && !nvlist_empty(retrynvl)) {
2344 2504 nvl = retrynvl;
2345 2505 goto retry;
2346 2506 }
2347 2507
2348 2508 if (!nvlist_empty(genericnvl) &&
2349 2509 dsl_props_set(dsname, source, genericnvl) != 0) {
2350 2510 /*
2351 2511 * If this fails, we still want to set as many properties as we
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
2352 2512 * can, so try setting them individually.
2353 2513 */
2354 2514 pair = NULL;
2355 2515 while ((pair = nvlist_next_nvpair(genericnvl, pair)) != NULL) {
2356 2516 const char *propname = nvpair_name(pair);
2357 2517 int err = 0;
2358 2518
2359 2519 propval = pair;
2360 2520 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2361 2521 nvlist_t *attrs;
2362 - VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
2363 - VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2364 - &propval) == 0);
2522 + attrs = fnvpair_value_nvlist(pair);
2523 + propval = fnvlist_lookup_nvpair(attrs,
2524 + ZPROP_VALUE);
2365 2525 }
2366 2526
2367 2527 if (nvpair_type(propval) == DATA_TYPE_STRING) {
2368 - VERIFY(nvpair_value_string(propval,
2369 - &strval) == 0);
2528 + strval = fnvpair_value_string(propval);
2370 2529 err = dsl_prop_set(dsname, propname, source, 1,
2371 2530 strlen(strval) + 1, strval);
2372 2531 } else {
2373 - VERIFY(nvpair_value_uint64(propval,
2374 - &intval) == 0);
2532 + intval = fnvpair_value_uint64(propval);
2375 2533 err = dsl_prop_set(dsname, propname, source, 8,
2376 2534 1, &intval);
2377 2535 }
2378 2536
2379 2537 if (err != 0) {
2380 - VERIFY(nvlist_add_int32(errors, propname,
2381 - err) == 0);
2538 + if (errlist != NULL) {
2539 + fnvlist_add_int32(errlist, propname,
2540 + err);
2541 + }
2542 + rv = err;
2382 2543 }
2383 2544 }
2384 2545 }
2385 2546 nvlist_free(genericnvl);
2386 2547 nvlist_free(retrynvl);
2387 2548
2388 - if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
2389 - nvlist_free(errors);
2390 - errors = NULL;
2391 - } else {
2392 - VERIFY(nvpair_value_int32(pair, &rv) == 0);
2393 - }
2394 -
2395 - if (errlist == NULL)
2396 - nvlist_free(errors);
2397 - else
2398 - *errlist = errors;
2399 -
2400 2549 return (rv);
2401 2550 }
2402 2551
2403 2552 /*
2404 2553 * Check that all the properties are valid user properties.
2405 2554 */
2406 2555 static int
2407 -zfs_check_userprops(char *fsname, nvlist_t *nvl)
2556 +zfs_check_userprops(const char *fsname, nvlist_t *nvl)
2408 2557 {
2409 2558 nvpair_t *pair = NULL;
2410 2559 int error = 0;
2411 2560
2412 2561 while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
2413 2562 const char *propname = nvpair_name(pair);
2414 2563 char *valstr;
2415 2564
2416 2565 if (!zfs_prop_user(propname) ||
2417 2566 nvpair_type(pair) != DATA_TYPE_STRING)
2418 2567 return (EINVAL);
2419 2568
2420 2569 if (error = zfs_secpolicy_write_perms(fsname,
2421 2570 ZFS_DELEG_PERM_USERPROP, CRED()))
2422 2571 return (error);
2423 2572
2424 2573 if (strlen(propname) >= ZAP_MAXNAMELEN)
2425 2574 return (ENAMETOOLONG);
2426 2575
2427 2576 VERIFY(nvpair_value_string(pair, &valstr) == 0);
2428 2577 if (strlen(valstr) >= ZAP_MAXVALUELEN)
2429 2578 return (E2BIG);
2430 2579 }
2431 2580 return (0);
2432 2581 }
2433 2582
2434 2583 static void
2435 2584 props_skip(nvlist_t *props, nvlist_t *skipped, nvlist_t **newprops)
2436 2585 {
2437 2586 nvpair_t *pair;
2438 2587
2439 2588 VERIFY(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2440 2589
2441 2590 pair = NULL;
2442 2591 while ((pair = nvlist_next_nvpair(props, pair)) != NULL) {
2443 2592 if (nvlist_exists(skipped, nvpair_name(pair)))
2444 2593 continue;
2445 2594
2446 2595 VERIFY(nvlist_add_nvpair(*newprops, pair) == 0);
2447 2596 }
2448 2597 }
2449 2598
2450 2599 static int
2451 2600 clear_received_props(objset_t *os, const char *fs, nvlist_t *props,
2452 2601 nvlist_t *skipped)
2453 2602 {
2454 2603 int err = 0;
2455 2604 nvlist_t *cleared_props = NULL;
2456 2605 props_skip(props, skipped, &cleared_props);
2457 2606 if (!nvlist_empty(cleared_props)) {
2458 2607 /*
2459 2608 * Acts on local properties until the dataset has received
2460 2609 * properties at least once on or after SPA_VERSION_RECVD_PROPS.
2461 2610 */
2462 2611 zprop_source_t flags = (ZPROP_SRC_NONE |
2463 2612 (dsl_prop_get_hasrecvd(os) ? ZPROP_SRC_RECEIVED : 0));
2464 2613 err = zfs_set_prop_nvlist(fs, flags, cleared_props, NULL);
2465 2614 }
2466 2615 nvlist_free(cleared_props);
2467 2616 return (err);
2468 2617 }
2469 2618
2470 2619 /*
2471 2620 * inputs:
2472 2621 * zc_name name of filesystem
2473 2622 * zc_value name of property to set
2474 2623 * zc_nvlist_src{_size} nvlist of properties to apply
2475 2624 * zc_cookie received properties flag
2476 2625 *
↓ open down ↓ |
59 lines elided |
↑ open up ↑ |
2477 2626 * outputs:
2478 2627 * zc_nvlist_dst{_size} error for each unapplied received property
2479 2628 */
2480 2629 static int
2481 2630 zfs_ioc_set_prop(zfs_cmd_t *zc)
2482 2631 {
2483 2632 nvlist_t *nvl;
2484 2633 boolean_t received = zc->zc_cookie;
2485 2634 zprop_source_t source = (received ? ZPROP_SRC_RECEIVED :
2486 2635 ZPROP_SRC_LOCAL);
2487 - nvlist_t *errors = NULL;
2636 + nvlist_t *errors;
2488 2637 int error;
2489 2638
2490 2639 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2491 2640 zc->zc_iflags, &nvl)) != 0)
2492 2641 return (error);
2493 2642
2494 2643 if (received) {
2495 2644 nvlist_t *origprops;
2496 2645 objset_t *os;
2497 2646
2498 2647 if (dmu_objset_hold(zc->zc_name, FTAG, &os) == 0) {
2499 2648 if (dsl_prop_get_received(os, &origprops) == 0) {
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
2500 2649 (void) clear_received_props(os,
2501 2650 zc->zc_name, origprops, nvl);
2502 2651 nvlist_free(origprops);
2503 2652 }
2504 2653
2505 2654 dsl_prop_set_hasrecvd(os);
2506 2655 dmu_objset_rele(os, FTAG);
2507 2656 }
2508 2657 }
2509 2658
2510 - error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, &errors);
2659 + errors = fnvlist_alloc();
2660 + error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, errors);
2511 2661
2512 2662 if (zc->zc_nvlist_dst != NULL && errors != NULL) {
2513 2663 (void) put_nvlist(zc, errors);
2514 2664 }
2515 2665
2516 2666 nvlist_free(errors);
2517 2667 nvlist_free(nvl);
2518 2668 return (error);
2519 2669 }
2520 2670
2521 2671 /*
2522 2672 * inputs:
2523 2673 * zc_name name of filesystem
2524 2674 * zc_value name of property to inherit
2525 2675 * zc_cookie revert to received value if TRUE
2526 2676 *
2527 2677 * outputs: none
2528 2678 */
2529 2679 static int
2530 2680 zfs_ioc_inherit_prop(zfs_cmd_t *zc)
2531 2681 {
2532 2682 const char *propname = zc->zc_value;
2533 2683 zfs_prop_t prop = zfs_name_to_prop(propname);
2534 2684 boolean_t received = zc->zc_cookie;
2535 2685 zprop_source_t source = (received
2536 2686 ? ZPROP_SRC_NONE /* revert to received value, if any */
2537 2687 : ZPROP_SRC_INHERITED); /* explicitly inherit */
2538 2688
2539 2689 if (received) {
2540 2690 nvlist_t *dummy;
2541 2691 nvpair_t *pair;
2542 2692 zprop_type_t type;
2543 2693 int err;
2544 2694
2545 2695 /*
2546 2696 * zfs_prop_set_special() expects properties in the form of an
2547 2697 * nvpair with type info.
2548 2698 */
2549 2699 if (prop == ZPROP_INVAL) {
2550 2700 if (!zfs_prop_user(propname))
2551 2701 return (EINVAL);
2552 2702
2553 2703 type = PROP_TYPE_STRING;
2554 2704 } else if (prop == ZFS_PROP_VOLSIZE ||
2555 2705 prop == ZFS_PROP_VERSION) {
2556 2706 return (EINVAL);
2557 2707 } else {
2558 2708 type = zfs_prop_get_type(prop);
2559 2709 }
2560 2710
2561 2711 VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2562 2712
2563 2713 switch (type) {
2564 2714 case PROP_TYPE_STRING:
2565 2715 VERIFY(0 == nvlist_add_string(dummy, propname, ""));
2566 2716 break;
2567 2717 case PROP_TYPE_NUMBER:
2568 2718 case PROP_TYPE_INDEX:
2569 2719 VERIFY(0 == nvlist_add_uint64(dummy, propname, 0));
2570 2720 break;
2571 2721 default:
2572 2722 nvlist_free(dummy);
2573 2723 return (EINVAL);
2574 2724 }
2575 2725
2576 2726 pair = nvlist_next_nvpair(dummy, NULL);
2577 2727 err = zfs_prop_set_special(zc->zc_name, source, pair);
2578 2728 nvlist_free(dummy);
2579 2729 if (err != -1)
2580 2730 return (err); /* special property already handled */
2581 2731 } else {
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
2582 2732 /*
2583 2733 * Only check this in the non-received case. We want to allow
2584 2734 * 'inherit -S' to revert non-inheritable properties like quota
2585 2735 * and reservation to the received or default values even though
2586 2736 * they are not considered inheritable.
2587 2737 */
2588 2738 if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop))
2589 2739 return (EINVAL);
2590 2740 }
2591 2741
2592 - /* the property name has been validated by zfs_secpolicy_inherit() */
2742 + /* property name has been validated by zfs_secpolicy_inherit_prop() */
2593 2743 return (dsl_prop_set(zc->zc_name, zc->zc_value, source, 0, 0, NULL));
2594 2744 }
2595 2745
2596 2746 static int
2597 2747 zfs_ioc_pool_set_props(zfs_cmd_t *zc)
2598 2748 {
2599 2749 nvlist_t *props;
2600 2750 spa_t *spa;
2601 2751 int error;
2602 2752 nvpair_t *pair;
2603 2753
2604 2754 if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2605 2755 zc->zc_iflags, &props))
2606 2756 return (error);
2607 2757
2608 2758 /*
2609 2759 * If the only property is the configfile, then just do a spa_lookup()
2610 2760 * to handle the faulted case.
2611 2761 */
2612 2762 pair = nvlist_next_nvpair(props, NULL);
2613 2763 if (pair != NULL && strcmp(nvpair_name(pair),
2614 2764 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
2615 2765 nvlist_next_nvpair(props, pair) == NULL) {
2616 2766 mutex_enter(&spa_namespace_lock);
2617 2767 if ((spa = spa_lookup(zc->zc_name)) != NULL) {
2618 2768 spa_configfile_set(spa, props, B_FALSE);
2619 2769 spa_config_sync(spa, B_FALSE, B_TRUE);
2620 2770 }
2621 2771 mutex_exit(&spa_namespace_lock);
2622 2772 if (spa != NULL) {
2623 2773 nvlist_free(props);
2624 2774 return (0);
2625 2775 }
2626 2776 }
2627 2777
2628 2778 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
2629 2779 nvlist_free(props);
2630 2780 return (error);
2631 2781 }
2632 2782
2633 2783 error = spa_prop_set(spa, props);
2634 2784
2635 2785 nvlist_free(props);
2636 2786 spa_close(spa, FTAG);
2637 2787
2638 2788 return (error);
2639 2789 }
2640 2790
2641 2791 static int
2642 2792 zfs_ioc_pool_get_props(zfs_cmd_t *zc)
2643 2793 {
2644 2794 spa_t *spa;
2645 2795 int error;
2646 2796 nvlist_t *nvp = NULL;
2647 2797
2648 2798 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
2649 2799 /*
2650 2800 * If the pool is faulted, there may be properties we can still
2651 2801 * get (such as altroot and cachefile), so attempt to get them
2652 2802 * anyway.
2653 2803 */
2654 2804 mutex_enter(&spa_namespace_lock);
2655 2805 if ((spa = spa_lookup(zc->zc_name)) != NULL)
2656 2806 error = spa_prop_get(spa, &nvp);
2657 2807 mutex_exit(&spa_namespace_lock);
2658 2808 } else {
2659 2809 error = spa_prop_get(spa, &nvp);
2660 2810 spa_close(spa, FTAG);
2661 2811 }
2662 2812
2663 2813 if (error == 0 && zc->zc_nvlist_dst != NULL)
2664 2814 error = put_nvlist(zc, nvp);
2665 2815 else
2666 2816 error = EFAULT;
2667 2817
2668 2818 nvlist_free(nvp);
2669 2819 return (error);
2670 2820 }
2671 2821
2672 2822 /*
2673 2823 * inputs:
2674 2824 * zc_name name of filesystem
2675 2825 * zc_nvlist_src{_size} nvlist of delegated permissions
2676 2826 * zc_perm_action allow/unallow flag
2677 2827 *
2678 2828 * outputs: none
2679 2829 */
2680 2830 static int
2681 2831 zfs_ioc_set_fsacl(zfs_cmd_t *zc)
2682 2832 {
2683 2833 int error;
2684 2834 nvlist_t *fsaclnv = NULL;
2685 2835
2686 2836 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2687 2837 zc->zc_iflags, &fsaclnv)) != 0)
2688 2838 return (error);
2689 2839
2690 2840 /*
2691 2841 * Verify nvlist is constructed correctly
2692 2842 */
2693 2843 if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
2694 2844 nvlist_free(fsaclnv);
2695 2845 return (EINVAL);
2696 2846 }
2697 2847
2698 2848 /*
2699 2849 * If we don't have PRIV_SYS_MOUNT, then validate
2700 2850 * that user is allowed to hand out each permission in
2701 2851 * the nvlist(s)
2702 2852 */
2703 2853
2704 2854 error = secpolicy_zfs(CRED());
2705 2855 if (error) {
2706 2856 if (zc->zc_perm_action == B_FALSE) {
2707 2857 error = dsl_deleg_can_allow(zc->zc_name,
2708 2858 fsaclnv, CRED());
2709 2859 } else {
2710 2860 error = dsl_deleg_can_unallow(zc->zc_name,
2711 2861 fsaclnv, CRED());
2712 2862 }
2713 2863 }
2714 2864
2715 2865 if (error == 0)
2716 2866 error = dsl_deleg_set(zc->zc_name, fsaclnv, zc->zc_perm_action);
2717 2867
2718 2868 nvlist_free(fsaclnv);
2719 2869 return (error);
2720 2870 }
2721 2871
2722 2872 /*
2723 2873 * inputs:
2724 2874 * zc_name name of filesystem
2725 2875 *
2726 2876 * outputs:
2727 2877 * zc_nvlist_src{_size} nvlist of delegated permissions
2728 2878 */
2729 2879 static int
2730 2880 zfs_ioc_get_fsacl(zfs_cmd_t *zc)
2731 2881 {
2732 2882 nvlist_t *nvp;
2733 2883 int error;
2734 2884
2735 2885 if ((error = dsl_deleg_get(zc->zc_name, &nvp)) == 0) {
2736 2886 error = put_nvlist(zc, nvp);
2737 2887 nvlist_free(nvp);
2738 2888 }
2739 2889
2740 2890 return (error);
2741 2891 }
2742 2892
2743 2893 /*
2744 2894 * Search the vfs list for a specified resource. Returns a pointer to it
2745 2895 * or NULL if no suitable entry is found. The caller of this routine
2746 2896 * is responsible for releasing the returned vfs pointer.
2747 2897 */
2748 2898 static vfs_t *
2749 2899 zfs_get_vfs(const char *resource)
2750 2900 {
2751 2901 struct vfs *vfsp;
2752 2902 struct vfs *vfs_found = NULL;
2753 2903
2754 2904 vfs_list_read_lock();
2755 2905 vfsp = rootvfs;
2756 2906 do {
2757 2907 if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
2758 2908 VFS_HOLD(vfsp);
2759 2909 vfs_found = vfsp;
2760 2910 break;
2761 2911 }
2762 2912 vfsp = vfsp->vfs_next;
2763 2913 } while (vfsp != rootvfs);
2764 2914 vfs_list_unlock();
2765 2915 return (vfs_found);
2766 2916 }
2767 2917
2768 2918 /* ARGSUSED */
2769 2919 static void
2770 2920 zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
2771 2921 {
2772 2922 zfs_creat_t *zct = arg;
2773 2923
2774 2924 zfs_create_fs(os, cr, zct->zct_zplprops, tx);
2775 2925 }
2776 2926
2777 2927 #define ZFS_PROP_UNDEFINED ((uint64_t)-1)
2778 2928
2779 2929 /*
2780 2930 * inputs:
2781 2931 * createprops list of properties requested by creator
2782 2932 * default_zplver zpl version to use if unspecified in createprops
2783 2933 * fuids_ok fuids allowed in this version of the spa?
2784 2934 * os parent objset pointer (NULL if root fs)
2785 2935 *
2786 2936 * outputs:
2787 2937 * zplprops values for the zplprops we attach to the master node object
2788 2938 * is_ci true if requested file system will be purely case-insensitive
2789 2939 *
2790 2940 * Determine the settings for utf8only, normalization and
2791 2941 * casesensitivity. Specific values may have been requested by the
2792 2942 * creator and/or we can inherit values from the parent dataset. If
2793 2943 * the file system is of too early a vintage, a creator can not
2794 2944 * request settings for these properties, even if the requested
2795 2945 * setting is the default value. We don't actually want to create dsl
2796 2946 * properties for these, so remove them from the source nvlist after
2797 2947 * processing.
2798 2948 */
2799 2949 static int
2800 2950 zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
2801 2951 boolean_t fuids_ok, boolean_t sa_ok, nvlist_t *createprops,
2802 2952 nvlist_t *zplprops, boolean_t *is_ci)
2803 2953 {
2804 2954 uint64_t sense = ZFS_PROP_UNDEFINED;
2805 2955 uint64_t norm = ZFS_PROP_UNDEFINED;
2806 2956 uint64_t u8 = ZFS_PROP_UNDEFINED;
2807 2957
2808 2958 ASSERT(zplprops != NULL);
2809 2959
2810 2960 /*
2811 2961 * Pull out creator prop choices, if any.
2812 2962 */
2813 2963 if (createprops) {
2814 2964 (void) nvlist_lookup_uint64(createprops,
2815 2965 zfs_prop_to_name(ZFS_PROP_VERSION), &zplver);
2816 2966 (void) nvlist_lookup_uint64(createprops,
2817 2967 zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm);
2818 2968 (void) nvlist_remove_all(createprops,
2819 2969 zfs_prop_to_name(ZFS_PROP_NORMALIZE));
2820 2970 (void) nvlist_lookup_uint64(createprops,
2821 2971 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), &u8);
2822 2972 (void) nvlist_remove_all(createprops,
2823 2973 zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
2824 2974 (void) nvlist_lookup_uint64(createprops,
2825 2975 zfs_prop_to_name(ZFS_PROP_CASE), &sense);
2826 2976 (void) nvlist_remove_all(createprops,
2827 2977 zfs_prop_to_name(ZFS_PROP_CASE));
2828 2978 }
2829 2979
2830 2980 /*
2831 2981 * If the zpl version requested is whacky or the file system
2832 2982 * or pool is version is too "young" to support normalization
2833 2983 * and the creator tried to set a value for one of the props,
2834 2984 * error out.
2835 2985 */
2836 2986 if ((zplver < ZPL_VERSION_INITIAL || zplver > ZPL_VERSION) ||
2837 2987 (zplver >= ZPL_VERSION_FUID && !fuids_ok) ||
2838 2988 (zplver >= ZPL_VERSION_SA && !sa_ok) ||
2839 2989 (zplver < ZPL_VERSION_NORMALIZATION &&
2840 2990 (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED ||
2841 2991 sense != ZFS_PROP_UNDEFINED)))
2842 2992 return (ENOTSUP);
2843 2993
2844 2994 /*
2845 2995 * Put the version in the zplprops
2846 2996 */
2847 2997 VERIFY(nvlist_add_uint64(zplprops,
2848 2998 zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0);
2849 2999
2850 3000 if (norm == ZFS_PROP_UNDEFINED)
2851 3001 VERIFY(zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm) == 0);
2852 3002 VERIFY(nvlist_add_uint64(zplprops,
2853 3003 zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0);
2854 3004
2855 3005 /*
2856 3006 * If we're normalizing, names must always be valid UTF-8 strings.
2857 3007 */
2858 3008 if (norm)
2859 3009 u8 = 1;
2860 3010 if (u8 == ZFS_PROP_UNDEFINED)
2861 3011 VERIFY(zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8) == 0);
2862 3012 VERIFY(nvlist_add_uint64(zplprops,
2863 3013 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0);
2864 3014
2865 3015 if (sense == ZFS_PROP_UNDEFINED)
2866 3016 VERIFY(zfs_get_zplprop(os, ZFS_PROP_CASE, &sense) == 0);
2867 3017 VERIFY(nvlist_add_uint64(zplprops,
2868 3018 zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0);
2869 3019
2870 3020 if (is_ci)
2871 3021 *is_ci = (sense == ZFS_CASE_INSENSITIVE);
2872 3022
2873 3023 return (0);
2874 3024 }
2875 3025
2876 3026 static int
2877 3027 zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
2878 3028 nvlist_t *zplprops, boolean_t *is_ci)
2879 3029 {
2880 3030 boolean_t fuids_ok, sa_ok;
2881 3031 uint64_t zplver = ZPL_VERSION;
2882 3032 objset_t *os = NULL;
2883 3033 char parentname[MAXNAMELEN];
2884 3034 char *cp;
2885 3035 spa_t *spa;
2886 3036 uint64_t spa_vers;
2887 3037 int error;
2888 3038
2889 3039 (void) strlcpy(parentname, dataset, sizeof (parentname));
2890 3040 cp = strrchr(parentname, '/');
2891 3041 ASSERT(cp != NULL);
2892 3042 cp[0] = '\0';
2893 3043
2894 3044 if ((error = spa_open(dataset, &spa, FTAG)) != 0)
2895 3045 return (error);
2896 3046
2897 3047 spa_vers = spa_version(spa);
2898 3048 spa_close(spa, FTAG);
2899 3049
2900 3050 zplver = zfs_zpl_version_map(spa_vers);
2901 3051 fuids_ok = (zplver >= ZPL_VERSION_FUID);
2902 3052 sa_ok = (zplver >= ZPL_VERSION_SA);
2903 3053
2904 3054 /*
2905 3055 * Open parent object set so we can inherit zplprop values.
2906 3056 */
2907 3057 if ((error = dmu_objset_hold(parentname, FTAG, &os)) != 0)
2908 3058 return (error);
2909 3059
2910 3060 error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, sa_ok, createprops,
2911 3061 zplprops, is_ci);
2912 3062 dmu_objset_rele(os, FTAG);
2913 3063 return (error);
2914 3064 }
2915 3065
2916 3066 static int
2917 3067 zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t *createprops,
2918 3068 nvlist_t *zplprops, boolean_t *is_ci)
2919 3069 {
2920 3070 boolean_t fuids_ok;
2921 3071 boolean_t sa_ok;
2922 3072 uint64_t zplver = ZPL_VERSION;
2923 3073 int error;
2924 3074
↓ open down ↓ |
322 lines elided |
↑ open up ↑ |
2925 3075 zplver = zfs_zpl_version_map(spa_vers);
2926 3076 fuids_ok = (zplver >= ZPL_VERSION_FUID);
2927 3077 sa_ok = (zplver >= ZPL_VERSION_SA);
2928 3078
2929 3079 error = zfs_fill_zplprops_impl(NULL, zplver, fuids_ok, sa_ok,
2930 3080 createprops, zplprops, is_ci);
2931 3081 return (error);
2932 3082 }
2933 3083
2934 3084 /*
2935 - * inputs:
2936 - * zc_objset_type type of objset to create (fs vs zvol)
2937 - * zc_name name of new objset
2938 - * zc_value name of snapshot to clone from (may be empty)
2939 - * zc_nvlist_src{_size} nvlist of properties to apply
3085 + * innvl: {
3086 + * "type" -> dmu_objset_type_t (int32)
3087 + * (optional) "props" -> { prop -> value }
3088 + * }
2940 3089 *
2941 - * outputs: none
3090 + * outnvl: propname -> error code (int32)
2942 3091 */
2943 3092 static int
2944 -zfs_ioc_create(zfs_cmd_t *zc)
3093 +zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
2945 3094 {
2946 - objset_t *clone;
2947 3095 int error = 0;
2948 - zfs_creat_t zct;
3096 + zfs_creat_t zct = { 0 };
2949 3097 nvlist_t *nvprops = NULL;
2950 3098 void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
2951 - dmu_objset_type_t type = zc->zc_objset_type;
3099 + int32_t type32;
3100 + dmu_objset_type_t type;
3101 + boolean_t is_insensitive = B_FALSE;
2952 3102
2953 - switch (type) {
3103 + if (nvlist_lookup_int32(innvl, "type", &type32) != 0)
3104 + return (EINVAL);
3105 + type = type32;
3106 + (void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
2954 3107
3108 + switch (type) {
2955 3109 case DMU_OST_ZFS:
2956 3110 cbfunc = zfs_create_cb;
2957 3111 break;
2958 3112
2959 3113 case DMU_OST_ZVOL:
2960 3114 cbfunc = zvol_create_cb;
2961 3115 break;
2962 3116
2963 3117 default:
2964 3118 cbfunc = NULL;
2965 3119 break;
2966 3120 }
2967 - if (strchr(zc->zc_name, '@') ||
2968 - strchr(zc->zc_name, '%'))
3121 + if (strchr(fsname, '@') ||
3122 + strchr(fsname, '%'))
2969 3123 return (EINVAL);
2970 3124
2971 - if (zc->zc_nvlist_src != NULL &&
2972 - (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2973 - zc->zc_iflags, &nvprops)) != 0)
2974 - return (error);
2975 -
2976 - zct.zct_zplprops = NULL;
2977 3125 zct.zct_props = nvprops;
2978 3126
2979 - if (zc->zc_value[0] != '\0') {
2980 - /*
2981 - * We're creating a clone of an existing snapshot.
2982 - */
2983 - zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
2984 - if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) {
2985 - nvlist_free(nvprops);
2986 - return (EINVAL);
2987 - }
2988 -
2989 - error = dmu_objset_hold(zc->zc_value, FTAG, &clone);
2990 - if (error) {
2991 - nvlist_free(nvprops);
2992 - return (error);
2993 - }
3127 + if (cbfunc == NULL)
3128 + return (EINVAL);
2994 3129
2995 - error = dmu_objset_clone(zc->zc_name, dmu_objset_ds(clone), 0);
2996 - dmu_objset_rele(clone, FTAG);
2997 - if (error) {
2998 - nvlist_free(nvprops);
2999 - return (error);
3000 - }
3001 - } else {
3002 - boolean_t is_insensitive = B_FALSE;
3130 + if (type == DMU_OST_ZVOL) {
3131 + uint64_t volsize, volblocksize;
3003 3132
3004 - if (cbfunc == NULL) {
3005 - nvlist_free(nvprops);
3133 + if (nvprops == NULL)
3134 + return (EINVAL);
3135 + if (nvlist_lookup_uint64(nvprops,
3136 + zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
3006 3137 return (EINVAL);
3007 - }
3008 -
3009 - if (type == DMU_OST_ZVOL) {
3010 - uint64_t volsize, volblocksize;
3011 3138
3012 - if (nvprops == NULL ||
3013 - nvlist_lookup_uint64(nvprops,
3014 - zfs_prop_to_name(ZFS_PROP_VOLSIZE),
3015 - &volsize) != 0) {
3016 - nvlist_free(nvprops);
3017 - return (EINVAL);
3018 - }
3139 + if ((error = nvlist_lookup_uint64(nvprops,
3140 + zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3141 + &volblocksize)) != 0 && error != ENOENT)
3142 + return (EINVAL);
3019 3143
3020 - if ((error = nvlist_lookup_uint64(nvprops,
3021 - zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3022 - &volblocksize)) != 0 && error != ENOENT) {
3023 - nvlist_free(nvprops);
3024 - return (EINVAL);
3025 - }
3144 + if (error != 0)
3145 + volblocksize = zfs_prop_default_numeric(
3146 + ZFS_PROP_VOLBLOCKSIZE);
3026 3147
3027 - if (error != 0)
3028 - volblocksize = zfs_prop_default_numeric(
3029 - ZFS_PROP_VOLBLOCKSIZE);
3030 -
3031 - if ((error = zvol_check_volblocksize(
3032 - volblocksize)) != 0 ||
3033 - (error = zvol_check_volsize(volsize,
3034 - volblocksize)) != 0) {
3035 - nvlist_free(nvprops);
3036 - return (error);
3037 - }
3038 - } else if (type == DMU_OST_ZFS) {
3039 - int error;
3148 + if ((error = zvol_check_volblocksize(
3149 + volblocksize)) != 0 ||
3150 + (error = zvol_check_volsize(volsize,
3151 + volblocksize)) != 0)
3152 + return (error);
3153 + } else if (type == DMU_OST_ZFS) {
3154 + int error;
3040 3155
3041 - /*
3042 - * We have to have normalization and
3043 - * case-folding flags correct when we do the
3044 - * file system creation, so go figure them out
3045 - * now.
3046 - */
3047 - VERIFY(nvlist_alloc(&zct.zct_zplprops,
3048 - NV_UNIQUE_NAME, KM_SLEEP) == 0);
3049 - error = zfs_fill_zplprops(zc->zc_name, nvprops,
3050 - zct.zct_zplprops, &is_insensitive);
3051 - if (error != 0) {
3052 - nvlist_free(nvprops);
3053 - nvlist_free(zct.zct_zplprops);
3054 - return (error);
3055 - }
3156 + /*
3157 + * We have to have normalization and
3158 + * case-folding flags correct when we do the
3159 + * file system creation, so go figure them out
3160 + * now.
3161 + */
3162 + VERIFY(nvlist_alloc(&zct.zct_zplprops,
3163 + NV_UNIQUE_NAME, KM_SLEEP) == 0);
3164 + error = zfs_fill_zplprops(fsname, nvprops,
3165 + zct.zct_zplprops, &is_insensitive);
3166 + if (error != 0) {
3167 + nvlist_free(zct.zct_zplprops);
3168 + return (error);
3056 3169 }
3057 - error = dmu_objset_create(zc->zc_name, type,
3058 - is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct);
3059 - nvlist_free(zct.zct_zplprops);
3060 3170 }
3061 3171
3172 + error = dmu_objset_create(fsname, type,
3173 + is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct);
3174 + nvlist_free(zct.zct_zplprops);
3175 +
3062 3176 /*
3063 3177 * It would be nice to do this atomically.
3064 3178 */
3065 3179 if (error == 0) {
3066 - error = zfs_set_prop_nvlist(zc->zc_name, ZPROP_SRC_LOCAL,
3067 - nvprops, NULL);
3180 + error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
3181 + nvprops, outnvl);
3068 3182 if (error != 0)
3069 - (void) dmu_objset_destroy(zc->zc_name, B_FALSE);
3183 + (void) dmu_objset_destroy(fsname, B_FALSE);
3070 3184 }
3071 - nvlist_free(nvprops);
3072 3185 return (error);
3073 3186 }
3074 3187
3075 3188 /*
3076 - * inputs:
3077 - * zc_name name of filesystem
3078 - * zc_value short name of snapshot
3079 - * zc_cookie recursive flag
3080 - * zc_nvlist_src[_size] property list
3189 + * innvl: {
3190 + * "origin" -> name of origin snapshot
3191 + * (optional) "props" -> { prop -> value }
3192 + * }
3081 3193 *
3082 - * outputs:
3083 - * zc_value short snapname (i.e. part after the '@')
3194 + * outnvl: propname -> error code (int32)
3084 3195 */
3085 3196 static int
3086 -zfs_ioc_snapshot(zfs_cmd_t *zc)
3197 +zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
3087 3198 {
3199 + int error = 0;
3088 3200 nvlist_t *nvprops = NULL;
3089 - int error;
3090 - boolean_t recursive = zc->zc_cookie;
3201 + char *origin_name;
3202 + dsl_dataset_t *origin;
3091 3203
3092 - if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
3204 + if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0)
3093 3205 return (EINVAL);
3206 + (void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
3094 3207
3095 - if (zc->zc_nvlist_src != NULL &&
3096 - (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
3097 - zc->zc_iflags, &nvprops)) != 0)
3208 + if (strchr(fsname, '@') ||
3209 + strchr(fsname, '%'))
3210 + return (EINVAL);
3211 +
3212 + if (dataset_namecheck(origin_name, NULL, NULL) != 0)
3213 + return (EINVAL);
3214 +
3215 + error = dsl_dataset_hold(origin_name, FTAG, &origin);
3216 + if (error)
3098 3217 return (error);
3099 3218
3100 - error = zfs_check_userprops(zc->zc_name, nvprops);
3219 + error = dmu_objset_clone(fsname, origin, 0);
3220 + dsl_dataset_rele(origin, FTAG);
3101 3221 if (error)
3102 - goto out;
3222 + return (error);
3103 3223
3104 - if (!nvlist_empty(nvprops) &&
3105 - zfs_earlier_version(zc->zc_name, SPA_VERSION_SNAP_PROPS)) {
3106 - error = ENOTSUP;
3107 - goto out;
3224 + /*
3225 + * It would be nice to do this atomically.
3226 + */
3227 + if (error == 0) {
3228 + error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
3229 + nvprops, outnvl);
3230 + if (error != 0)
3231 + (void) dmu_objset_destroy(fsname, B_FALSE);
3108 3232 }
3233 + return (error);
3234 +}
3109 3235
3110 - error = dmu_objset_snapshot(zc->zc_name, zc->zc_value, NULL,
3111 - nvprops, recursive, B_FALSE, -1);
3236 +/*
3237 + * innvl: {
3238 + * "snaps" -> { snapshot1, snapshot2 }
3239 + * (optional) "props" -> { prop -> value (string) }
3240 + * }
3241 + *
3242 + * outnvl: snapshot -> error code (int32)
3243 + *
3244 + */
3245 +static int
3246 +zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
3247 +{
3248 + nvlist_t *snaps;
3249 + nvlist_t *props = NULL;
3250 + int error, poollen;
3251 + nvpair_t *pair;
3112 3252
3113 -out:
3114 - nvlist_free(nvprops);
3253 + (void) nvlist_lookup_nvlist(innvl, "props", &props);
3254 + if ((error = zfs_check_userprops(poolname, props)) != 0)
3255 + return (error);
3256 +
3257 + if (!nvlist_empty(props) &&
3258 + zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
3259 + return (ENOTSUP);
3260 +
3261 + if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
3262 + return (EINVAL);
3263 + poollen = strlen(poolname);
3264 + for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
3265 + pair = nvlist_next_nvpair(snaps, pair)) {
3266 + const char *name = nvpair_name(pair);
3267 + const char *cp = strchr(name, '@');
3268 +
3269 + /*
3270 + * The snap name must contain an @, and the part after it must
3271 + * contain only valid characters.
3272 + */
3273 + if (cp == NULL || snapshot_namecheck(cp + 1, NULL, NULL) != 0)
3274 + return (EINVAL);
3275 +
3276 + /*
3277 + * The snap must be in the specified pool.
3278 + */
3279 + if (strncmp(name, poolname, poollen) != 0 ||
3280 + (name[poollen] != '/' && name[poollen] != '@'))
3281 + return (EXDEV);
3282 +
3283 + /* This must be the only snap of this fs. */
3284 + for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair);
3285 + pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
3286 + if (strncmp(name, nvpair_name(pair2), cp - name + 1)
3287 + == 0) {
3288 + return (EXDEV);
3289 + }
3290 + }
3291 + }
3292 +
3293 + error = dmu_objset_snapshot(snaps, props, outnvl);
3294 + return (error);
3295 +}
3296 +
3297 +/*
3298 + * innvl: "message" -> string
3299 + */
3300 +/* ARGSUSED */
3301 +static int
3302 +zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
3303 +{
3304 + char *message;
3305 + spa_t *spa;
3306 + int error;
3307 + char *poolname;
3308 +
3309 + /*
3310 + * The poolname in the ioctl is not set, we get it from the TSD,
3311 + * which was set at the end of the last successful ioctl that allows
3312 + * logging. The secpolicy func already checked that it is set.
3313 + * Only one log ioctl is allowed after each successful ioctl, so
3314 + * we clear the TSD here.
3315 + */
3316 + poolname = tsd_get(zfs_allow_log_key);
3317 + (void) tsd_set(zfs_allow_log_key, NULL);
3318 + error = spa_open(poolname, &spa, FTAG);
3319 + strfree(poolname);
3320 + if (error != 0)
3321 + return (error);
3322 +
3323 + if (nvlist_lookup_string(innvl, "message", &message) != 0) {
3324 + spa_close(spa, FTAG);
3325 + return (EINVAL);
3326 + }
3327 +
3328 + if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
3329 + spa_close(spa, FTAG);
3330 + return (ENOTSUP);
3331 + }
3332 +
3333 + error = spa_history_log(spa, message);
3334 + spa_close(spa, FTAG);
3115 3335 return (error);
3116 3336 }
3117 3337
3338 +/* ARGSUSED */
3118 3339 int
3119 3340 zfs_unmount_snap(const char *name, void *arg)
3120 3341 {
3121 - vfs_t *vfsp = NULL;
3342 + vfs_t *vfsp;
3343 + int err;
3122 3344
3123 - if (arg) {
3124 - char *snapname = arg;
3125 - char *fullname = kmem_asprintf("%s@%s", name, snapname);
3126 - vfsp = zfs_get_vfs(fullname);
3127 - strfree(fullname);
3128 - } else if (strchr(name, '@')) {
3129 - vfsp = zfs_get_vfs(name);
3130 - }
3345 + if (strchr(name, '@') == NULL)
3346 + return (0);
3131 3347
3132 - if (vfsp) {
3133 - /*
3134 - * Always force the unmount for snapshots.
3135 - */
3136 - int flag = MS_FORCE;
3137 - int err;
3348 + vfsp = zfs_get_vfs(name);
3349 + if (vfsp == NULL)
3350 + return (0);
3138 3351
3139 - if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
3140 - VFS_RELE(vfsp);
3141 - return (err);
3142 - }
3352 + if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
3143 3353 VFS_RELE(vfsp);
3144 - if ((err = dounmount(vfsp, flag, kcred)) != 0)
3145 - return (err);
3354 + return (err);
3146 3355 }
3147 - return (0);
3356 + VFS_RELE(vfsp);
3357 +
3358 + /*
3359 + * Always force the unmount for snapshots.
3360 + */
3361 + return (dounmount(vfsp, MS_FORCE, kcred));
3148 3362 }
3149 3363
3150 3364 /*
3151 - * inputs:
3152 - * zc_name name of filesystem, snaps must be under it
3153 - * zc_nvlist_src[_size] full names of snapshots to destroy
3154 - * zc_defer_destroy mark for deferred destroy
3365 + * innvl: {
3366 + * "snaps" -> { snapshot1, snapshot2 }
3367 + * (optional boolean) "defer"
3368 + * }
3369 + *
3370 + * outnvl: snapshot -> error code (int32)
3155 3371 *
3156 - * outputs:
3157 - * zc_name on failure, name of failed snapshot
3158 3372 */
3159 3373 static int
3160 -zfs_ioc_destroy_snaps_nvl(zfs_cmd_t *zc)
3374 +zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
3161 3375 {
3162 - int err, len;
3163 - nvlist_t *nvl;
3376 + int poollen;
3377 + nvlist_t *snaps;
3164 3378 nvpair_t *pair;
3379 + boolean_t defer;
3165 3380
3166 - if ((err = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
3167 - zc->zc_iflags, &nvl)) != 0)
3168 - return (err);
3381 + if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
3382 + return (EINVAL);
3383 + defer = nvlist_exists(innvl, "defer");
3169 3384
3170 - len = strlen(zc->zc_name);
3171 - for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
3172 - pair = nvlist_next_nvpair(nvl, pair)) {
3385 + poollen = strlen(poolname);
3386 + for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
3387 + pair = nvlist_next_nvpair(snaps, pair)) {
3173 3388 const char *name = nvpair_name(pair);
3389 +
3174 3390 /*
3175 - * The snap name must be underneath the zc_name. This ensures
3176 - * that our permission checks were legitimate.
3391 + * The snap must be in the specified pool.
3177 3392 */
3178 - if (strncmp(zc->zc_name, name, len) != 0 ||
3179 - (name[len] != '@' && name[len] != '/')) {
3180 - nvlist_free(nvl);
3181 - return (EINVAL);
3182 - }
3393 + if (strncmp(name, poolname, poollen) != 0 ||
3394 + (name[poollen] != '/' && name[poollen] != '@'))
3395 + return (EXDEV);
3183 3396
3397 + /*
3398 + * Ignore failures to unmount; dmu_snapshots_destroy_nvl()
3399 + * will deal with this gracefully (by filling in outnvl).
3400 + */
3184 3401 (void) zfs_unmount_snap(name, NULL);
3185 3402 }
3186 3403
3187 - err = dmu_snapshots_destroy_nvl(nvl, zc->zc_defer_destroy,
3188 - zc->zc_name);
3189 - nvlist_free(nvl);
3190 - return (err);
3404 + return (dmu_snapshots_destroy_nvl(snaps, defer, outnvl));
3191 3405 }
3192 3406
3193 3407 /*
3194 3408 * inputs:
3195 3409 * zc_name name of dataset to destroy
3196 3410 * zc_objset_type type of objset
3197 3411 * zc_defer_destroy mark for deferred destroy
3198 3412 *
3199 3413 * outputs: none
3200 3414 */
3201 3415 static int
3202 3416 zfs_ioc_destroy(zfs_cmd_t *zc)
3203 3417 {
3204 3418 int err;
3205 3419 if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS) {
3206 3420 err = zfs_unmount_snap(zc->zc_name, NULL);
3207 3421 if (err)
3208 3422 return (err);
3209 3423 }
3210 3424
3211 3425 err = dmu_objset_destroy(zc->zc_name, zc->zc_defer_destroy);
3212 3426 if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
3213 3427 (void) zvol_remove_minor(zc->zc_name);
3214 3428 return (err);
3215 3429 }
3216 3430
3217 3431 /*
3218 3432 * inputs:
3219 3433 * zc_name name of dataset to rollback (to most recent snapshot)
3220 3434 *
3221 3435 * outputs: none
3222 3436 */
3223 3437 static int
3224 3438 zfs_ioc_rollback(zfs_cmd_t *zc)
3225 3439 {
3226 3440 dsl_dataset_t *ds, *clone;
3227 3441 int error;
3228 3442 zfsvfs_t *zfsvfs;
3229 3443 char *clone_name;
3230 3444
3231 3445 error = dsl_dataset_hold(zc->zc_name, FTAG, &ds);
3232 3446 if (error)
3233 3447 return (error);
3234 3448
3235 3449 /* must not be a snapshot */
3236 3450 if (dsl_dataset_is_snapshot(ds)) {
3237 3451 dsl_dataset_rele(ds, FTAG);
3238 3452 return (EINVAL);
3239 3453 }
3240 3454
3241 3455 /* must have a most recent snapshot */
3242 3456 if (ds->ds_phys->ds_prev_snap_txg < TXG_INITIAL) {
3243 3457 dsl_dataset_rele(ds, FTAG);
3244 3458 return (EINVAL);
3245 3459 }
3246 3460
3247 3461 /*
3248 3462 * Create clone of most recent snapshot.
3249 3463 */
3250 3464 clone_name = kmem_asprintf("%s/%%rollback", zc->zc_name);
3251 3465 error = dmu_objset_clone(clone_name, ds->ds_prev, DS_FLAG_INCONSISTENT);
3252 3466 if (error)
3253 3467 goto out;
3254 3468
3255 3469 error = dsl_dataset_own(clone_name, B_TRUE, FTAG, &clone);
3256 3470 if (error)
3257 3471 goto out;
3258 3472
3259 3473 /*
3260 3474 * Do clone swap.
3261 3475 */
3262 3476 if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
3263 3477 error = zfs_suspend_fs(zfsvfs);
3264 3478 if (error == 0) {
3265 3479 int resume_err;
3266 3480
3267 3481 if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
3268 3482 error = dsl_dataset_clone_swap(clone, ds,
3269 3483 B_TRUE);
3270 3484 dsl_dataset_disown(ds, FTAG);
3271 3485 ds = NULL;
3272 3486 } else {
3273 3487 error = EBUSY;
3274 3488 }
3275 3489 resume_err = zfs_resume_fs(zfsvfs, zc->zc_name);
3276 3490 error = error ? error : resume_err;
3277 3491 }
3278 3492 VFS_RELE(zfsvfs->z_vfs);
3279 3493 } else {
3280 3494 if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
3281 3495 error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
3282 3496 dsl_dataset_disown(ds, FTAG);
3283 3497 ds = NULL;
3284 3498 } else {
3285 3499 error = EBUSY;
3286 3500 }
3287 3501 }
3288 3502
3289 3503 /*
3290 3504 * Destroy clone (which also closes it).
3291 3505 */
3292 3506 (void) dsl_dataset_destroy(clone, FTAG, B_FALSE);
3293 3507
3294 3508 out:
3295 3509 strfree(clone_name);
3296 3510 if (ds)
3297 3511 dsl_dataset_rele(ds, FTAG);
3298 3512 return (error);
3299 3513 }
3300 3514
3301 3515 /*
3302 3516 * inputs:
3303 3517 * zc_name old name of dataset
3304 3518 * zc_value new name of dataset
3305 3519 * zc_cookie recursive flag (only valid for snapshots)
3306 3520 *
3307 3521 * outputs: none
3308 3522 */
3309 3523 static int
3310 3524 zfs_ioc_rename(zfs_cmd_t *zc)
3311 3525 {
3312 3526 boolean_t recursive = zc->zc_cookie & 1;
3313 3527
3314 3528 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
3315 3529 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
3316 3530 strchr(zc->zc_value, '%'))
3317 3531 return (EINVAL);
3318 3532
3319 3533 /*
3320 3534 * Unmount snapshot unless we're doing a recursive rename,
3321 3535 * in which case the dataset code figures out which snapshots
3322 3536 * to unmount.
3323 3537 */
3324 3538 if (!recursive && strchr(zc->zc_name, '@') != NULL &&
3325 3539 zc->zc_objset_type == DMU_OST_ZFS) {
3326 3540 int err = zfs_unmount_snap(zc->zc_name, NULL);
3327 3541 if (err)
3328 3542 return (err);
3329 3543 }
3330 3544 if (zc->zc_objset_type == DMU_OST_ZVOL)
3331 3545 (void) zvol_remove_minor(zc->zc_name);
3332 3546 return (dmu_objset_rename(zc->zc_name, zc->zc_value, recursive));
3333 3547 }
3334 3548
3335 3549 static int
3336 3550 zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
3337 3551 {
3338 3552 const char *propname = nvpair_name(pair);
3339 3553 boolean_t issnap = (strchr(dsname, '@') != NULL);
3340 3554 zfs_prop_t prop = zfs_name_to_prop(propname);
3341 3555 uint64_t intval;
3342 3556 int err;
3343 3557
3344 3558 if (prop == ZPROP_INVAL) {
3345 3559 if (zfs_prop_user(propname)) {
3346 3560 if (err = zfs_secpolicy_write_perms(dsname,
3347 3561 ZFS_DELEG_PERM_USERPROP, cr))
3348 3562 return (err);
3349 3563 return (0);
3350 3564 }
3351 3565
3352 3566 if (!issnap && zfs_prop_userquota(propname)) {
3353 3567 const char *perm = NULL;
3354 3568 const char *uq_prefix =
3355 3569 zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA];
3356 3570 const char *gq_prefix =
3357 3571 zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA];
3358 3572
3359 3573 if (strncmp(propname, uq_prefix,
3360 3574 strlen(uq_prefix)) == 0) {
3361 3575 perm = ZFS_DELEG_PERM_USERQUOTA;
3362 3576 } else if (strncmp(propname, gq_prefix,
3363 3577 strlen(gq_prefix)) == 0) {
3364 3578 perm = ZFS_DELEG_PERM_GROUPQUOTA;
3365 3579 } else {
3366 3580 /* USERUSED and GROUPUSED are read-only */
3367 3581 return (EINVAL);
3368 3582 }
3369 3583
3370 3584 if (err = zfs_secpolicy_write_perms(dsname, perm, cr))
3371 3585 return (err);
3372 3586 return (0);
3373 3587 }
3374 3588
3375 3589 return (EINVAL);
3376 3590 }
3377 3591
3378 3592 if (issnap)
3379 3593 return (EINVAL);
3380 3594
3381 3595 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
3382 3596 /*
3383 3597 * dsl_prop_get_all_impl() returns properties in this
3384 3598 * format.
3385 3599 */
3386 3600 nvlist_t *attrs;
3387 3601 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
3388 3602 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
3389 3603 &pair) == 0);
3390 3604 }
3391 3605
3392 3606 /*
3393 3607 * Check that this value is valid for this pool version
3394 3608 */
3395 3609 switch (prop) {
3396 3610 case ZFS_PROP_COMPRESSION:
3397 3611 /*
3398 3612 * If the user specified gzip compression, make sure
3399 3613 * the SPA supports it. We ignore any errors here since
3400 3614 * we'll catch them later.
3401 3615 */
3402 3616 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
3403 3617 nvpair_value_uint64(pair, &intval) == 0) {
3404 3618 if (intval >= ZIO_COMPRESS_GZIP_1 &&
3405 3619 intval <= ZIO_COMPRESS_GZIP_9 &&
3406 3620 zfs_earlier_version(dsname,
3407 3621 SPA_VERSION_GZIP_COMPRESSION)) {
3408 3622 return (ENOTSUP);
3409 3623 }
3410 3624
3411 3625 if (intval == ZIO_COMPRESS_ZLE &&
3412 3626 zfs_earlier_version(dsname,
3413 3627 SPA_VERSION_ZLE_COMPRESSION))
3414 3628 return (ENOTSUP);
3415 3629
3416 3630 /*
3417 3631 * If this is a bootable dataset then
3418 3632 * verify that the compression algorithm
3419 3633 * is supported for booting. We must return
3420 3634 * something other than ENOTSUP since it
3421 3635 * implies a downrev pool version.
3422 3636 */
3423 3637 if (zfs_is_bootfs(dsname) &&
3424 3638 !BOOTFS_COMPRESS_VALID(intval)) {
3425 3639 return (ERANGE);
3426 3640 }
3427 3641 }
3428 3642 break;
3429 3643
3430 3644 case ZFS_PROP_COPIES:
3431 3645 if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS))
3432 3646 return (ENOTSUP);
3433 3647 break;
3434 3648
3435 3649 case ZFS_PROP_DEDUP:
3436 3650 if (zfs_earlier_version(dsname, SPA_VERSION_DEDUP))
3437 3651 return (ENOTSUP);
3438 3652 break;
3439 3653
3440 3654 case ZFS_PROP_SHARESMB:
3441 3655 if (zpl_earlier_version(dsname, ZPL_VERSION_FUID))
3442 3656 return (ENOTSUP);
3443 3657 break;
3444 3658
3445 3659 case ZFS_PROP_ACLINHERIT:
3446 3660 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
3447 3661 nvpair_value_uint64(pair, &intval) == 0) {
3448 3662 if (intval == ZFS_ACL_PASSTHROUGH_X &&
3449 3663 zfs_earlier_version(dsname,
3450 3664 SPA_VERSION_PASSTHROUGH_X))
3451 3665 return (ENOTSUP);
3452 3666 }
3453 3667 break;
3454 3668 }
3455 3669
3456 3670 return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
3457 3671 }
3458 3672
3459 3673 /*
3460 3674 * Removes properties from the given props list that fail permission checks
3461 3675 * needed to clear them and to restore them in case of a receive error. For each
3462 3676 * property, make sure we have both set and inherit permissions.
3463 3677 *
3464 3678 * Returns the first error encountered if any permission checks fail. If the
3465 3679 * caller provides a non-NULL errlist, it also gives the complete list of names
3466 3680 * of all the properties that failed a permission check along with the
3467 3681 * corresponding error numbers. The caller is responsible for freeing the
3468 3682 * returned errlist.
3469 3683 *
3470 3684 * If every property checks out successfully, zero is returned and the list
3471 3685 * pointed at by errlist is NULL.
3472 3686 */
3473 3687 static int
3474 3688 zfs_check_clearable(char *dataset, nvlist_t *props, nvlist_t **errlist)
3475 3689 {
3476 3690 zfs_cmd_t *zc;
3477 3691 nvpair_t *pair, *next_pair;
3478 3692 nvlist_t *errors;
3479 3693 int err, rv = 0;
3480 3694
3481 3695 if (props == NULL)
3482 3696 return (0);
3483 3697
↓ open down ↓ |
283 lines elided |
↑ open up ↑ |
3484 3698 VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
3485 3699
3486 3700 zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
3487 3701 (void) strcpy(zc->zc_name, dataset);
3488 3702 pair = nvlist_next_nvpair(props, NULL);
3489 3703 while (pair != NULL) {
3490 3704 next_pair = nvlist_next_nvpair(props, pair);
3491 3705
3492 3706 (void) strcpy(zc->zc_value, nvpair_name(pair));
3493 3707 if ((err = zfs_check_settable(dataset, pair, CRED())) != 0 ||
3494 - (err = zfs_secpolicy_inherit(zc, CRED())) != 0) {
3708 + (err = zfs_secpolicy_inherit_prop(zc, NULL, CRED())) != 0) {
3495 3709 VERIFY(nvlist_remove_nvpair(props, pair) == 0);
3496 3710 VERIFY(nvlist_add_int32(errors,
3497 3711 zc->zc_value, err) == 0);
3498 3712 }
3499 3713 pair = next_pair;
3500 3714 }
3501 3715 kmem_free(zc, sizeof (zfs_cmd_t));
3502 3716
3503 3717 if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
3504 3718 nvlist_free(errors);
3505 3719 errors = NULL;
3506 3720 } else {
3507 3721 VERIFY(nvpair_value_int32(pair, &rv) == 0);
3508 3722 }
3509 3723
3510 3724 if (errlist == NULL)
3511 3725 nvlist_free(errors);
3512 3726 else
3513 3727 *errlist = errors;
3514 3728
3515 3729 return (rv);
3516 3730 }
3517 3731
3518 3732 static boolean_t
3519 3733 propval_equals(nvpair_t *p1, nvpair_t *p2)
3520 3734 {
3521 3735 if (nvpair_type(p1) == DATA_TYPE_NVLIST) {
3522 3736 /* dsl_prop_get_all_impl() format */
3523 3737 nvlist_t *attrs;
3524 3738 VERIFY(nvpair_value_nvlist(p1, &attrs) == 0);
3525 3739 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
3526 3740 &p1) == 0);
3527 3741 }
3528 3742
3529 3743 if (nvpair_type(p2) == DATA_TYPE_NVLIST) {
3530 3744 nvlist_t *attrs;
3531 3745 VERIFY(nvpair_value_nvlist(p2, &attrs) == 0);
3532 3746 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
3533 3747 &p2) == 0);
3534 3748 }
3535 3749
3536 3750 if (nvpair_type(p1) != nvpair_type(p2))
3537 3751 return (B_FALSE);
3538 3752
3539 3753 if (nvpair_type(p1) == DATA_TYPE_STRING) {
3540 3754 char *valstr1, *valstr2;
3541 3755
3542 3756 VERIFY(nvpair_value_string(p1, (char **)&valstr1) == 0);
3543 3757 VERIFY(nvpair_value_string(p2, (char **)&valstr2) == 0);
3544 3758 return (strcmp(valstr1, valstr2) == 0);
3545 3759 } else {
3546 3760 uint64_t intval1, intval2;
3547 3761
3548 3762 VERIFY(nvpair_value_uint64(p1, &intval1) == 0);
3549 3763 VERIFY(nvpair_value_uint64(p2, &intval2) == 0);
3550 3764 return (intval1 == intval2);
3551 3765 }
3552 3766 }
3553 3767
3554 3768 /*
3555 3769 * Remove properties from props if they are not going to change (as determined
3556 3770 * by comparison with origprops). Remove them from origprops as well, since we
3557 3771 * do not need to clear or restore properties that won't change.
3558 3772 */
3559 3773 static void
3560 3774 props_reduce(nvlist_t *props, nvlist_t *origprops)
3561 3775 {
3562 3776 nvpair_t *pair, *next_pair;
3563 3777
3564 3778 if (origprops == NULL)
3565 3779 return; /* all props need to be received */
3566 3780
3567 3781 pair = nvlist_next_nvpair(props, NULL);
3568 3782 while (pair != NULL) {
3569 3783 const char *propname = nvpair_name(pair);
3570 3784 nvpair_t *match;
3571 3785
3572 3786 next_pair = nvlist_next_nvpair(props, pair);
3573 3787
3574 3788 if ((nvlist_lookup_nvpair(origprops, propname,
3575 3789 &match) != 0) || !propval_equals(pair, match))
3576 3790 goto next; /* need to set received value */
3577 3791
3578 3792 /* don't clear the existing received value */
3579 3793 (void) nvlist_remove_nvpair(origprops, match);
3580 3794 /* don't bother receiving the property */
3581 3795 (void) nvlist_remove_nvpair(props, pair);
3582 3796 next:
3583 3797 pair = next_pair;
3584 3798 }
3585 3799 }
3586 3800
3587 3801 #ifdef DEBUG
3588 3802 static boolean_t zfs_ioc_recv_inject_err;
3589 3803 #endif
3590 3804
3591 3805 /*
3592 3806 * inputs:
3593 3807 * zc_name name of containing filesystem
3594 3808 * zc_nvlist_src{_size} nvlist of properties to apply
3595 3809 * zc_value name of snapshot to create
3596 3810 * zc_string name of clone origin (if DRR_FLAG_CLONE)
3597 3811 * zc_cookie file descriptor to recv from
3598 3812 * zc_begin_record the BEGIN record of the stream (not byteswapped)
3599 3813 * zc_guid force flag
3600 3814 * zc_cleanup_fd cleanup-on-exit file descriptor
3601 3815 * zc_action_handle handle for this guid/ds mapping (or zero on first call)
3602 3816 *
3603 3817 * outputs:
3604 3818 * zc_cookie number of bytes read
3605 3819 * zc_nvlist_dst{_size} error for each unapplied received property
3606 3820 * zc_obj zprop_errflags_t
3607 3821 * zc_action_handle handle for this guid/ds mapping
3608 3822 */
3609 3823 static int
3610 3824 zfs_ioc_recv(zfs_cmd_t *zc)
3611 3825 {
3612 3826 file_t *fp;
3613 3827 objset_t *os;
3614 3828 dmu_recv_cookie_t drc;
3615 3829 boolean_t force = (boolean_t)zc->zc_guid;
3616 3830 int fd;
3617 3831 int error = 0;
3618 3832 int props_error = 0;
3619 3833 nvlist_t *errors;
3620 3834 offset_t off;
3621 3835 nvlist_t *props = NULL; /* sent properties */
3622 3836 nvlist_t *origprops = NULL; /* existing properties */
3623 3837 objset_t *origin = NULL;
3624 3838 char *tosnap;
3625 3839 char tofs[ZFS_MAXNAMELEN];
3626 3840 boolean_t first_recvd_props = B_FALSE;
3627 3841
3628 3842 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
3629 3843 strchr(zc->zc_value, '@') == NULL ||
3630 3844 strchr(zc->zc_value, '%'))
3631 3845 return (EINVAL);
3632 3846
3633 3847 (void) strcpy(tofs, zc->zc_value);
3634 3848 tosnap = strchr(tofs, '@');
3635 3849 *tosnap++ = '\0';
3636 3850
3637 3851 if (zc->zc_nvlist_src != NULL &&
3638 3852 (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
3639 3853 zc->zc_iflags, &props)) != 0)
3640 3854 return (error);
3641 3855
3642 3856 fd = zc->zc_cookie;
3643 3857 fp = getf(fd);
3644 3858 if (fp == NULL) {
3645 3859 nvlist_free(props);
3646 3860 return (EBADF);
3647 3861 }
3648 3862
3649 3863 VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
3650 3864
3651 3865 if (props && dmu_objset_hold(tofs, FTAG, &os) == 0) {
3652 3866 if ((spa_version(os->os_spa) >= SPA_VERSION_RECVD_PROPS) &&
3653 3867 !dsl_prop_get_hasrecvd(os)) {
3654 3868 first_recvd_props = B_TRUE;
3655 3869 }
3656 3870
3657 3871 /*
3658 3872 * If new received properties are supplied, they are to
3659 3873 * completely replace the existing received properties, so stash
3660 3874 * away the existing ones.
3661 3875 */
3662 3876 if (dsl_prop_get_received(os, &origprops) == 0) {
3663 3877 nvlist_t *errlist = NULL;
3664 3878 /*
3665 3879 * Don't bother writing a property if its value won't
3666 3880 * change (and avoid the unnecessary security checks).
3667 3881 *
3668 3882 * The first receive after SPA_VERSION_RECVD_PROPS is a
3669 3883 * special case where we blow away all local properties
3670 3884 * regardless.
3671 3885 */
3672 3886 if (!first_recvd_props)
3673 3887 props_reduce(props, origprops);
3674 3888 if (zfs_check_clearable(tofs, origprops,
3675 3889 &errlist) != 0)
3676 3890 (void) nvlist_merge(errors, errlist, 0);
3677 3891 nvlist_free(errlist);
3678 3892 }
3679 3893
3680 3894 dmu_objset_rele(os, FTAG);
3681 3895 }
3682 3896
3683 3897 if (zc->zc_string[0]) {
3684 3898 error = dmu_objset_hold(zc->zc_string, FTAG, &origin);
3685 3899 if (error)
3686 3900 goto out;
3687 3901 }
3688 3902
3689 3903 error = dmu_recv_begin(tofs, tosnap, zc->zc_top_ds,
3690 3904 &zc->zc_begin_record, force, origin, &drc);
3691 3905 if (origin)
↓ open down ↓ |
187 lines elided |
↑ open up ↑ |
3692 3906 dmu_objset_rele(origin, FTAG);
3693 3907 if (error)
3694 3908 goto out;
3695 3909
3696 3910 /*
3697 3911 * Set properties before we receive the stream so that they are applied
3698 3912 * to the new data. Note that we must call dmu_recv_stream() if
3699 3913 * dmu_recv_begin() succeeds.
3700 3914 */
3701 3915 if (props) {
3702 - nvlist_t *errlist;
3703 -
3704 3916 if (dmu_objset_from_ds(drc.drc_logical_ds, &os) == 0) {
3705 3917 if (drc.drc_newfs) {
3706 3918 if (spa_version(os->os_spa) >=
3707 3919 SPA_VERSION_RECVD_PROPS)
3708 3920 first_recvd_props = B_TRUE;
3709 3921 } else if (origprops != NULL) {
3710 3922 if (clear_received_props(os, tofs, origprops,
3711 3923 first_recvd_props ? NULL : props) != 0)
3712 3924 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
3713 3925 } else {
3714 3926 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
3715 3927 }
3716 3928 dsl_prop_set_hasrecvd(os);
3717 3929 } else if (!drc.drc_newfs) {
3718 3930 zc->zc_obj |= ZPROP_ERR_NOCLEAR;
3719 3931 }
3720 3932
3721 3933 (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
3722 - props, &errlist);
3723 - (void) nvlist_merge(errors, errlist, 0);
3724 - nvlist_free(errlist);
3934 + props, errors);
3725 3935 }
3726 3936
3727 - if (fit_error_list(zc, &errors) != 0 || put_nvlist(zc, errors) != 0) {
3937 + if (zc->zc_nvlist_dst_size != 0 &&
3938 + (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
3939 + put_nvlist(zc, errors) != 0)) {
3728 3940 /*
3729 3941 * Caller made zc->zc_nvlist_dst less than the minimum expected
3730 3942 * size or supplied an invalid address.
3731 3943 */
3732 3944 props_error = EINVAL;
3733 3945 }
3734 3946
3735 3947 off = fp->f_offset;
3736 3948 error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
3737 3949 &zc->zc_action_handle);
3738 3950
3739 3951 if (error == 0) {
3740 3952 zfsvfs_t *zfsvfs = NULL;
3741 3953
3742 3954 if (getzfsvfs(tofs, &zfsvfs) == 0) {
3743 3955 /* online recv */
3744 3956 int end_err;
3745 3957
3746 3958 error = zfs_suspend_fs(zfsvfs);
3747 3959 /*
3748 3960 * If the suspend fails, then the recv_end will
3749 3961 * likely also fail, and clean up after itself.
3750 3962 */
3751 3963 end_err = dmu_recv_end(&drc);
3752 3964 if (error == 0)
3753 3965 error = zfs_resume_fs(zfsvfs, tofs);
3754 3966 error = error ? error : end_err;
3755 3967 VFS_RELE(zfsvfs->z_vfs);
3756 3968 } else {
3757 3969 error = dmu_recv_end(&drc);
3758 3970 }
3759 3971 }
3760 3972
3761 3973 zc->zc_cookie = off - fp->f_offset;
3762 3974 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
3763 3975 fp->f_offset = off;
3764 3976
3765 3977 #ifdef DEBUG
3766 3978 if (zfs_ioc_recv_inject_err) {
3767 3979 zfs_ioc_recv_inject_err = B_FALSE;
3768 3980 error = 1;
3769 3981 }
3770 3982 #endif
3771 3983 /*
3772 3984 * On error, restore the original props.
3773 3985 */
3774 3986 if (error && props) {
3775 3987 if (dmu_objset_hold(tofs, FTAG, &os) == 0) {
3776 3988 if (clear_received_props(os, tofs, props, NULL) != 0) {
3777 3989 /*
3778 3990 * We failed to clear the received properties.
3779 3991 * Since we may have left a $recvd value on the
3780 3992 * system, we can't clear the $hasrecvd flag.
3781 3993 */
3782 3994 zc->zc_obj |= ZPROP_ERR_NORESTORE;
3783 3995 } else if (first_recvd_props) {
3784 3996 dsl_prop_unset_hasrecvd(os);
3785 3997 }
3786 3998 dmu_objset_rele(os, FTAG);
3787 3999 } else if (!drc.drc_newfs) {
3788 4000 /* We failed to clear the received properties. */
3789 4001 zc->zc_obj |= ZPROP_ERR_NORESTORE;
3790 4002 }
3791 4003
3792 4004 if (origprops == NULL && !drc.drc_newfs) {
3793 4005 /* We failed to stash the original properties. */
3794 4006 zc->zc_obj |= ZPROP_ERR_NORESTORE;
3795 4007 }
3796 4008
3797 4009 /*
3798 4010 * dsl_props_set() will not convert RECEIVED to LOCAL on or
3799 4011 * after SPA_VERSION_RECVD_PROPS, so we need to specify LOCAL
3800 4012 * explictly if we're restoring local properties cleared in the
3801 4013 * first new-style receive.
3802 4014 */
3803 4015 if (origprops != NULL &&
3804 4016 zfs_set_prop_nvlist(tofs, (first_recvd_props ?
3805 4017 ZPROP_SRC_LOCAL : ZPROP_SRC_RECEIVED),
3806 4018 origprops, NULL) != 0) {
3807 4019 /*
3808 4020 * We stashed the original properties but failed to
3809 4021 * restore them.
3810 4022 */
3811 4023 zc->zc_obj |= ZPROP_ERR_NORESTORE;
3812 4024 }
3813 4025 }
3814 4026 out:
3815 4027 nvlist_free(props);
3816 4028 nvlist_free(origprops);
3817 4029 nvlist_free(errors);
3818 4030 releasef(fd);
3819 4031
3820 4032 if (error == 0)
3821 4033 error = props_error;
3822 4034
3823 4035 return (error);
3824 4036 }
3825 4037
3826 4038 /*
3827 4039 * inputs:
3828 4040 * zc_name name of snapshot to send
3829 4041 * zc_cookie file descriptor to send stream to
3830 4042 * zc_obj fromorigin flag (mutually exclusive with zc_fromobj)
3831 4043 * zc_sendobj objsetid of snapshot to send
3832 4044 * zc_fromobj objsetid of incremental fromsnap (may be zero)
3833 4045 * zc_guid if set, estimate size of stream only. zc_cookie is ignored.
3834 4046 * output size in zc_objset_type.
3835 4047 *
3836 4048 * outputs: none
3837 4049 */
3838 4050 static int
3839 4051 zfs_ioc_send(zfs_cmd_t *zc)
3840 4052 {
3841 4053 objset_t *fromsnap = NULL;
3842 4054 objset_t *tosnap;
3843 4055 int error;
3844 4056 offset_t off;
3845 4057 dsl_dataset_t *ds;
3846 4058 dsl_dataset_t *dsfrom = NULL;
3847 4059 spa_t *spa;
3848 4060 dsl_pool_t *dp;
↓ open down ↓ |
111 lines elided |
↑ open up ↑ |
3849 4061 boolean_t estimate = (zc->zc_guid != 0);
3850 4062
3851 4063 error = spa_open(zc->zc_name, &spa, FTAG);
3852 4064 if (error)
3853 4065 return (error);
3854 4066
3855 4067 dp = spa_get_dsl(spa);
3856 4068 rw_enter(&dp->dp_config_rwlock, RW_READER);
3857 4069 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
3858 4070 rw_exit(&dp->dp_config_rwlock);
3859 - if (error) {
3860 - spa_close(spa, FTAG);
4071 + spa_close(spa, FTAG);
4072 + if (error)
3861 4073 return (error);
3862 - }
3863 4074
3864 4075 error = dmu_objset_from_ds(ds, &tosnap);
3865 4076 if (error) {
3866 4077 dsl_dataset_rele(ds, FTAG);
3867 - spa_close(spa, FTAG);
3868 4078 return (error);
3869 4079 }
3870 4080
3871 4081 if (zc->zc_fromobj != 0) {
3872 4082 rw_enter(&dp->dp_config_rwlock, RW_READER);
3873 4083 error = dsl_dataset_hold_obj(dp, zc->zc_fromobj, FTAG, &dsfrom);
3874 4084 rw_exit(&dp->dp_config_rwlock);
3875 - spa_close(spa, FTAG);
3876 4085 if (error) {
3877 4086 dsl_dataset_rele(ds, FTAG);
3878 4087 return (error);
3879 4088 }
3880 4089 error = dmu_objset_from_ds(dsfrom, &fromsnap);
3881 4090 if (error) {
3882 4091 dsl_dataset_rele(dsfrom, FTAG);
3883 4092 dsl_dataset_rele(ds, FTAG);
3884 4093 return (error);
3885 4094 }
3886 - } else {
3887 - spa_close(spa, FTAG);
4095 + }
4096 +
4097 + if (zc->zc_obj) {
4098 + dsl_pool_t *dp = ds->ds_dir->dd_pool;
4099 +
4100 + if (fromsnap != NULL) {
4101 + dsl_dataset_rele(dsfrom, FTAG);
4102 + dsl_dataset_rele(ds, FTAG);
4103 + return (EINVAL);
4104 + }
4105 +
4106 + if (dsl_dir_is_clone(ds->ds_dir)) {
4107 + rw_enter(&dp->dp_config_rwlock, RW_READER);
4108 + error = dsl_dataset_hold_obj(dp,
4109 + ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &dsfrom);
4110 + rw_exit(&dp->dp_config_rwlock);
4111 + if (error) {
4112 + dsl_dataset_rele(ds, FTAG);
4113 + return (error);
4114 + }
4115 + error = dmu_objset_from_ds(dsfrom, &fromsnap);
4116 + if (error) {
4117 + dsl_dataset_rele(dsfrom, FTAG);
4118 + dsl_dataset_rele(ds, FTAG);
4119 + return (error);
4120 + }
4121 + }
3888 4122 }
3889 4123
3890 4124 if (estimate) {
3891 - error = dmu_send_estimate(tosnap, fromsnap, zc->zc_obj,
4125 + error = dmu_send_estimate(tosnap, fromsnap,
3892 4126 &zc->zc_objset_type);
3893 4127 } else {
3894 4128 file_t *fp = getf(zc->zc_cookie);
3895 4129 if (fp == NULL) {
3896 4130 dsl_dataset_rele(ds, FTAG);
3897 4131 if (dsfrom)
3898 4132 dsl_dataset_rele(dsfrom, FTAG);
3899 4133 return (EBADF);
3900 4134 }
3901 4135
3902 4136 off = fp->f_offset;
3903 - error = dmu_send(tosnap, fromsnap, zc->zc_obj,
4137 + error = dmu_send(tosnap, fromsnap,
3904 4138 zc->zc_cookie, fp->f_vnode, &off);
3905 4139
3906 4140 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
3907 4141 fp->f_offset = off;
3908 4142 releasef(zc->zc_cookie);
3909 4143 }
3910 4144 if (dsfrom)
3911 4145 dsl_dataset_rele(dsfrom, FTAG);
3912 4146 dsl_dataset_rele(ds, FTAG);
3913 4147 return (error);
3914 4148 }
3915 4149
3916 4150 /*
3917 4151 * inputs:
3918 4152 * zc_name name of snapshot on which to report progress
3919 4153 * zc_cookie file descriptor of send stream
3920 4154 *
3921 4155 * outputs:
3922 4156 * zc_cookie number of bytes written in send stream thus far
3923 4157 */
3924 4158 static int
3925 4159 zfs_ioc_send_progress(zfs_cmd_t *zc)
3926 4160 {
3927 4161 dsl_dataset_t *ds;
3928 4162 dmu_sendarg_t *dsp = NULL;
3929 4163 int error;
3930 4164
3931 4165 if ((error = dsl_dataset_hold(zc->zc_name, FTAG, &ds)) != 0)
3932 4166 return (error);
3933 4167
3934 4168 mutex_enter(&ds->ds_sendstream_lock);
3935 4169
3936 4170 /*
3937 4171 * Iterate over all the send streams currently active on this dataset.
3938 4172 * If there's one which matches the specified file descriptor _and_ the
3939 4173 * stream was started by the current process, return the progress of
3940 4174 * that stream.
3941 4175 */
3942 4176 for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
3943 4177 dsp = list_next(&ds->ds_sendstreams, dsp)) {
3944 4178 if (dsp->dsa_outfd == zc->zc_cookie &&
3945 4179 dsp->dsa_proc == curproc)
3946 4180 break;
3947 4181 }
3948 4182
3949 4183 if (dsp != NULL)
3950 4184 zc->zc_cookie = *(dsp->dsa_off);
3951 4185 else
3952 4186 error = ENOENT;
3953 4187
3954 4188 mutex_exit(&ds->ds_sendstream_lock);
3955 4189 dsl_dataset_rele(ds, FTAG);
3956 4190 return (error);
3957 4191 }
3958 4192
3959 4193 static int
3960 4194 zfs_ioc_inject_fault(zfs_cmd_t *zc)
3961 4195 {
3962 4196 int id, error;
3963 4197
3964 4198 error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id,
3965 4199 &zc->zc_inject_record);
3966 4200
3967 4201 if (error == 0)
3968 4202 zc->zc_guid = (uint64_t)id;
3969 4203
3970 4204 return (error);
3971 4205 }
3972 4206
3973 4207 static int
3974 4208 zfs_ioc_clear_fault(zfs_cmd_t *zc)
3975 4209 {
3976 4210 return (zio_clear_fault((int)zc->zc_guid));
3977 4211 }
3978 4212
3979 4213 static int
3980 4214 zfs_ioc_inject_list_next(zfs_cmd_t *zc)
3981 4215 {
3982 4216 int id = (int)zc->zc_guid;
3983 4217 int error;
3984 4218
3985 4219 error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name),
3986 4220 &zc->zc_inject_record);
3987 4221
3988 4222 zc->zc_guid = id;
3989 4223
3990 4224 return (error);
3991 4225 }
3992 4226
3993 4227 static int
3994 4228 zfs_ioc_error_log(zfs_cmd_t *zc)
3995 4229 {
3996 4230 spa_t *spa;
3997 4231 int error;
3998 4232 size_t count = (size_t)zc->zc_nvlist_dst_size;
3999 4233
4000 4234 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
4001 4235 return (error);
4002 4236
4003 4237 error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
4004 4238 &count);
4005 4239 if (error == 0)
4006 4240 zc->zc_nvlist_dst_size = count;
4007 4241 else
4008 4242 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
4009 4243
4010 4244 spa_close(spa, FTAG);
4011 4245
4012 4246 return (error);
4013 4247 }
4014 4248
4015 4249 static int
4016 4250 zfs_ioc_clear(zfs_cmd_t *zc)
4017 4251 {
4018 4252 spa_t *spa;
4019 4253 vdev_t *vd;
4020 4254 int error;
4021 4255
4022 4256 /*
4023 4257 * On zpool clear we also fix up missing slogs
4024 4258 */
4025 4259 mutex_enter(&spa_namespace_lock);
4026 4260 spa = spa_lookup(zc->zc_name);
4027 4261 if (spa == NULL) {
4028 4262 mutex_exit(&spa_namespace_lock);
4029 4263 return (EIO);
4030 4264 }
4031 4265 if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
4032 4266 /* we need to let spa_open/spa_load clear the chains */
4033 4267 spa_set_log_state(spa, SPA_LOG_CLEAR);
4034 4268 }
4035 4269 spa->spa_last_open_failed = 0;
4036 4270 mutex_exit(&spa_namespace_lock);
4037 4271
4038 4272 if (zc->zc_cookie & ZPOOL_NO_REWIND) {
4039 4273 error = spa_open(zc->zc_name, &spa, FTAG);
4040 4274 } else {
4041 4275 nvlist_t *policy;
4042 4276 nvlist_t *config = NULL;
4043 4277
4044 4278 if (zc->zc_nvlist_src == NULL)
4045 4279 return (EINVAL);
4046 4280
4047 4281 if ((error = get_nvlist(zc->zc_nvlist_src,
4048 4282 zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
4049 4283 error = spa_open_rewind(zc->zc_name, &spa, FTAG,
4050 4284 policy, &config);
4051 4285 if (config != NULL) {
4052 4286 int err;
4053 4287
4054 4288 if ((err = put_nvlist(zc, config)) != 0)
4055 4289 error = err;
4056 4290 nvlist_free(config);
4057 4291 }
4058 4292 nvlist_free(policy);
4059 4293 }
4060 4294 }
4061 4295
4062 4296 if (error)
4063 4297 return (error);
4064 4298
4065 4299 spa_vdev_state_enter(spa, SCL_NONE);
4066 4300
4067 4301 if (zc->zc_guid == 0) {
4068 4302 vd = NULL;
4069 4303 } else {
4070 4304 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE);
4071 4305 if (vd == NULL) {
4072 4306 (void) spa_vdev_state_exit(spa, NULL, ENODEV);
4073 4307 spa_close(spa, FTAG);
4074 4308 return (ENODEV);
4075 4309 }
4076 4310 }
4077 4311
4078 4312 vdev_clear(spa, vd);
4079 4313
4080 4314 (void) spa_vdev_state_exit(spa, NULL, 0);
4081 4315
4082 4316 /*
4083 4317 * Resume any suspended I/Os.
4084 4318 */
4085 4319 if (zio_resume(spa) != 0)
4086 4320 error = EIO;
4087 4321
4088 4322 spa_close(spa, FTAG);
4089 4323
4090 4324 return (error);
4091 4325 }
4092 4326
4093 4327 static int
4094 4328 zfs_ioc_pool_reopen(zfs_cmd_t *zc)
4095 4329 {
4096 4330 spa_t *spa;
4097 4331 int error;
4098 4332
4099 4333 error = spa_open(zc->zc_name, &spa, FTAG);
4100 4334 if (error)
4101 4335 return (error);
4102 4336
4103 4337 spa_vdev_state_enter(spa, SCL_NONE);
4104 4338 vdev_reopen(spa->spa_root_vdev);
4105 4339 (void) spa_vdev_state_exit(spa, NULL, 0);
4106 4340 spa_close(spa, FTAG);
4107 4341 return (0);
4108 4342 }
4109 4343 /*
4110 4344 * inputs:
4111 4345 * zc_name name of filesystem
4112 4346 * zc_value name of origin snapshot
4113 4347 *
4114 4348 * outputs:
4115 4349 * zc_string name of conflicting snapshot, if there is one
4116 4350 */
4117 4351 static int
4118 4352 zfs_ioc_promote(zfs_cmd_t *zc)
4119 4353 {
4120 4354 char *cp;
4121 4355
4122 4356 /*
4123 4357 * We don't need to unmount *all* the origin fs's snapshots, but
4124 4358 * it's easier.
4125 4359 */
4126 4360 cp = strchr(zc->zc_value, '@');
4127 4361 if (cp)
4128 4362 *cp = '\0';
4129 4363 (void) dmu_objset_find(zc->zc_value,
4130 4364 zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS);
4131 4365 return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
4132 4366 }
4133 4367
4134 4368 /*
4135 4369 * Retrieve a single {user|group}{used|quota}@... property.
4136 4370 *
4137 4371 * inputs:
4138 4372 * zc_name name of filesystem
4139 4373 * zc_objset_type zfs_userquota_prop_t
4140 4374 * zc_value domain name (eg. "S-1-234-567-89")
4141 4375 * zc_guid RID/UID/GID
4142 4376 *
4143 4377 * outputs:
4144 4378 * zc_cookie property value
4145 4379 */
4146 4380 static int
4147 4381 zfs_ioc_userspace_one(zfs_cmd_t *zc)
4148 4382 {
4149 4383 zfsvfs_t *zfsvfs;
4150 4384 int error;
4151 4385
4152 4386 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
4153 4387 return (EINVAL);
4154 4388
4155 4389 error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
4156 4390 if (error)
4157 4391 return (error);
4158 4392
4159 4393 error = zfs_userspace_one(zfsvfs,
4160 4394 zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
4161 4395 zfsvfs_rele(zfsvfs, FTAG);
4162 4396
4163 4397 return (error);
4164 4398 }
4165 4399
4166 4400 /*
4167 4401 * inputs:
4168 4402 * zc_name name of filesystem
4169 4403 * zc_cookie zap cursor
4170 4404 * zc_objset_type zfs_userquota_prop_t
4171 4405 * zc_nvlist_dst[_size] buffer to fill (not really an nvlist)
4172 4406 *
4173 4407 * outputs:
4174 4408 * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t)
4175 4409 * zc_cookie zap cursor
4176 4410 */
4177 4411 static int
4178 4412 zfs_ioc_userspace_many(zfs_cmd_t *zc)
4179 4413 {
4180 4414 zfsvfs_t *zfsvfs;
4181 4415 int bufsize = zc->zc_nvlist_dst_size;
4182 4416
4183 4417 if (bufsize <= 0)
4184 4418 return (ENOMEM);
4185 4419
4186 4420 int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
4187 4421 if (error)
4188 4422 return (error);
4189 4423
4190 4424 void *buf = kmem_alloc(bufsize, KM_SLEEP);
4191 4425
4192 4426 error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie,
4193 4427 buf, &zc->zc_nvlist_dst_size);
4194 4428
4195 4429 if (error == 0) {
4196 4430 error = xcopyout(buf,
4197 4431 (void *)(uintptr_t)zc->zc_nvlist_dst,
4198 4432 zc->zc_nvlist_dst_size);
4199 4433 }
4200 4434 kmem_free(buf, bufsize);
4201 4435 zfsvfs_rele(zfsvfs, FTAG);
4202 4436
4203 4437 return (error);
4204 4438 }
4205 4439
4206 4440 /*
4207 4441 * inputs:
4208 4442 * zc_name name of filesystem
4209 4443 *
4210 4444 * outputs:
4211 4445 * none
4212 4446 */
4213 4447 static int
4214 4448 zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
4215 4449 {
4216 4450 objset_t *os;
4217 4451 int error = 0;
4218 4452 zfsvfs_t *zfsvfs;
4219 4453
4220 4454 if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
4221 4455 if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
4222 4456 /*
4223 4457 * If userused is not enabled, it may be because the
4224 4458 * objset needs to be closed & reopened (to grow the
4225 4459 * objset_phys_t). Suspend/resume the fs will do that.
4226 4460 */
4227 4461 error = zfs_suspend_fs(zfsvfs);
4228 4462 if (error == 0)
4229 4463 error = zfs_resume_fs(zfsvfs, zc->zc_name);
4230 4464 }
4231 4465 if (error == 0)
4232 4466 error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
4233 4467 VFS_RELE(zfsvfs->z_vfs);
4234 4468 } else {
4235 4469 /* XXX kind of reading contents without owning */
4236 4470 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
4237 4471 if (error)
4238 4472 return (error);
4239 4473
4240 4474 error = dmu_objset_userspace_upgrade(os);
4241 4475 dmu_objset_rele(os, FTAG);
4242 4476 }
4243 4477
4244 4478 return (error);
4245 4479 }
4246 4480
4247 4481 /*
4248 4482 * We don't want to have a hard dependency
4249 4483 * against some special symbols in sharefs
4250 4484 * nfs, and smbsrv. Determine them if needed when
4251 4485 * the first file system is shared.
4252 4486 * Neither sharefs, nfs or smbsrv are unloadable modules.
4253 4487 */
4254 4488 int (*znfsexport_fs)(void *arg);
4255 4489 int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
4256 4490 int (*zsmbexport_fs)(void *arg, boolean_t add_share);
4257 4491
4258 4492 int zfs_nfsshare_inited;
4259 4493 int zfs_smbshare_inited;
4260 4494
4261 4495 ddi_modhandle_t nfs_mod;
4262 4496 ddi_modhandle_t sharefs_mod;
4263 4497 ddi_modhandle_t smbsrv_mod;
4264 4498 kmutex_t zfs_share_lock;
4265 4499
4266 4500 static int
4267 4501 zfs_init_sharefs()
4268 4502 {
4269 4503 int error;
4270 4504
4271 4505 ASSERT(MUTEX_HELD(&zfs_share_lock));
4272 4506 /* Both NFS and SMB shares also require sharetab support. */
4273 4507 if (sharefs_mod == NULL && ((sharefs_mod =
4274 4508 ddi_modopen("fs/sharefs",
4275 4509 KRTLD_MODE_FIRST, &error)) == NULL)) {
4276 4510 return (ENOSYS);
4277 4511 }
4278 4512 if (zshare_fs == NULL && ((zshare_fs =
4279 4513 (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
4280 4514 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
4281 4515 return (ENOSYS);
4282 4516 }
4283 4517 return (0);
4284 4518 }
4285 4519
4286 4520 static int
4287 4521 zfs_ioc_share(zfs_cmd_t *zc)
4288 4522 {
4289 4523 int error;
4290 4524 int opcode;
4291 4525
4292 4526 switch (zc->zc_share.z_sharetype) {
4293 4527 case ZFS_SHARE_NFS:
4294 4528 case ZFS_UNSHARE_NFS:
4295 4529 if (zfs_nfsshare_inited == 0) {
4296 4530 mutex_enter(&zfs_share_lock);
4297 4531 if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs",
4298 4532 KRTLD_MODE_FIRST, &error)) == NULL)) {
4299 4533 mutex_exit(&zfs_share_lock);
4300 4534 return (ENOSYS);
4301 4535 }
4302 4536 if (znfsexport_fs == NULL &&
4303 4537 ((znfsexport_fs = (int (*)(void *))
4304 4538 ddi_modsym(nfs_mod,
4305 4539 "nfs_export", &error)) == NULL)) {
4306 4540 mutex_exit(&zfs_share_lock);
4307 4541 return (ENOSYS);
4308 4542 }
4309 4543 error = zfs_init_sharefs();
4310 4544 if (error) {
4311 4545 mutex_exit(&zfs_share_lock);
4312 4546 return (ENOSYS);
4313 4547 }
4314 4548 zfs_nfsshare_inited = 1;
4315 4549 mutex_exit(&zfs_share_lock);
4316 4550 }
4317 4551 break;
4318 4552 case ZFS_SHARE_SMB:
4319 4553 case ZFS_UNSHARE_SMB:
4320 4554 if (zfs_smbshare_inited == 0) {
4321 4555 mutex_enter(&zfs_share_lock);
4322 4556 if (smbsrv_mod == NULL && ((smbsrv_mod =
4323 4557 ddi_modopen("drv/smbsrv",
4324 4558 KRTLD_MODE_FIRST, &error)) == NULL)) {
4325 4559 mutex_exit(&zfs_share_lock);
4326 4560 return (ENOSYS);
4327 4561 }
4328 4562 if (zsmbexport_fs == NULL && ((zsmbexport_fs =
4329 4563 (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod,
4330 4564 "smb_server_share", &error)) == NULL)) {
4331 4565 mutex_exit(&zfs_share_lock);
4332 4566 return (ENOSYS);
4333 4567 }
4334 4568 error = zfs_init_sharefs();
4335 4569 if (error) {
4336 4570 mutex_exit(&zfs_share_lock);
4337 4571 return (ENOSYS);
4338 4572 }
4339 4573 zfs_smbshare_inited = 1;
4340 4574 mutex_exit(&zfs_share_lock);
4341 4575 }
4342 4576 break;
4343 4577 default:
4344 4578 return (EINVAL);
4345 4579 }
4346 4580
4347 4581 switch (zc->zc_share.z_sharetype) {
4348 4582 case ZFS_SHARE_NFS:
4349 4583 case ZFS_UNSHARE_NFS:
4350 4584 if (error =
4351 4585 znfsexport_fs((void *)
4352 4586 (uintptr_t)zc->zc_share.z_exportdata))
4353 4587 return (error);
4354 4588 break;
4355 4589 case ZFS_SHARE_SMB:
4356 4590 case ZFS_UNSHARE_SMB:
4357 4591 if (error = zsmbexport_fs((void *)
4358 4592 (uintptr_t)zc->zc_share.z_exportdata,
4359 4593 zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
4360 4594 B_TRUE: B_FALSE)) {
4361 4595 return (error);
4362 4596 }
4363 4597 break;
4364 4598 }
4365 4599
4366 4600 opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
4367 4601 zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
4368 4602 SHAREFS_ADD : SHAREFS_REMOVE;
4369 4603
4370 4604 /*
4371 4605 * Add or remove share from sharetab
4372 4606 */
4373 4607 error = zshare_fs(opcode,
4374 4608 (void *)(uintptr_t)zc->zc_share.z_sharedata,
4375 4609 zc->zc_share.z_sharemax);
4376 4610
4377 4611 return (error);
4378 4612
4379 4613 }
4380 4614
4381 4615 ace_t full_access[] = {
4382 4616 {(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
4383 4617 };
4384 4618
4385 4619 /*
4386 4620 * inputs:
4387 4621 * zc_name name of containing filesystem
4388 4622 * zc_obj object # beyond which we want next in-use object #
4389 4623 *
4390 4624 * outputs:
4391 4625 * zc_obj next in-use object #
4392 4626 */
4393 4627 static int
4394 4628 zfs_ioc_next_obj(zfs_cmd_t *zc)
4395 4629 {
4396 4630 objset_t *os = NULL;
4397 4631 int error;
4398 4632
4399 4633 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
4400 4634 if (error)
4401 4635 return (error);
4402 4636
4403 4637 error = dmu_object_next(os, &zc->zc_obj, B_FALSE,
4404 4638 os->os_dsl_dataset->ds_phys->ds_prev_snap_txg);
4405 4639
4406 4640 dmu_objset_rele(os, FTAG);
↓ open down ↓ |
493 lines elided |
↑ open up ↑ |
4407 4641 return (error);
4408 4642 }
4409 4643
4410 4644 /*
4411 4645 * inputs:
4412 4646 * zc_name name of filesystem
4413 4647 * zc_value prefix name for snapshot
4414 4648 * zc_cleanup_fd cleanup-on-exit file descriptor for calling process
4415 4649 *
4416 4650 * outputs:
4651 + * zc_value short name of new snapshot
4417 4652 */
4418 4653 static int
4419 4654 zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
4420 4655 {
4421 4656 char *snap_name;
4422 4657 int error;
4423 4658
4424 - snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
4659 + snap_name = kmem_asprintf("%s@%s-%016llx", zc->zc_name, zc->zc_value,
4425 4660 (u_longlong_t)ddi_get_lbolt64());
4426 4661
4427 - if (strlen(snap_name) >= MAXNAMELEN) {
4662 + if (strlen(snap_name) >= MAXPATHLEN) {
4428 4663 strfree(snap_name);
4429 4664 return (E2BIG);
4430 4665 }
4431 4666
4432 - error = dmu_objset_snapshot(zc->zc_name, snap_name, snap_name,
4433 - NULL, B_FALSE, B_TRUE, zc->zc_cleanup_fd);
4667 + error = dmu_objset_snapshot_tmp(snap_name, "%temp", zc->zc_cleanup_fd);
4434 4668 if (error != 0) {
4435 4669 strfree(snap_name);
4436 4670 return (error);
4437 4671 }
4438 4672
4439 - (void) strcpy(zc->zc_value, snap_name);
4673 + (void) strcpy(zc->zc_value, strchr(snap_name, '@') + 1);
4440 4674 strfree(snap_name);
4441 4675 return (0);
4442 4676 }
4443 4677
4444 4678 /*
4445 4679 * inputs:
4446 4680 * zc_name name of "to" snapshot
4447 4681 * zc_value name of "from" snapshot
4448 4682 * zc_cookie file descriptor to write diff data on
4449 4683 *
4450 4684 * outputs:
4451 4685 * dmu_diff_record_t's to the file descriptor
4452 4686 */
4453 4687 static int
4454 4688 zfs_ioc_diff(zfs_cmd_t *zc)
4455 4689 {
4456 4690 objset_t *fromsnap;
4457 4691 objset_t *tosnap;
4458 4692 file_t *fp;
4459 4693 offset_t off;
4460 4694 int error;
4461 4695
4462 4696 error = dmu_objset_hold(zc->zc_name, FTAG, &tosnap);
4463 4697 if (error)
4464 4698 return (error);
4465 4699
4466 4700 error = dmu_objset_hold(zc->zc_value, FTAG, &fromsnap);
4467 4701 if (error) {
4468 4702 dmu_objset_rele(tosnap, FTAG);
4469 4703 return (error);
4470 4704 }
4471 4705
4472 4706 fp = getf(zc->zc_cookie);
4473 4707 if (fp == NULL) {
4474 4708 dmu_objset_rele(fromsnap, FTAG);
4475 4709 dmu_objset_rele(tosnap, FTAG);
4476 4710 return (EBADF);
4477 4711 }
4478 4712
4479 4713 off = fp->f_offset;
4480 4714
4481 4715 error = dmu_diff(tosnap, fromsnap, fp->f_vnode, &off);
4482 4716
4483 4717 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4484 4718 fp->f_offset = off;
4485 4719 releasef(zc->zc_cookie);
4486 4720
4487 4721 dmu_objset_rele(fromsnap, FTAG);
4488 4722 dmu_objset_rele(tosnap, FTAG);
4489 4723 return (error);
4490 4724 }
4491 4725
4492 4726 /*
4493 4727 * Remove all ACL files in shares dir
4494 4728 */
4495 4729 static int
4496 4730 zfs_smb_acl_purge(znode_t *dzp)
4497 4731 {
4498 4732 zap_cursor_t zc;
4499 4733 zap_attribute_t zap;
4500 4734 zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
4501 4735 int error;
4502 4736
4503 4737 for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
4504 4738 (error = zap_cursor_retrieve(&zc, &zap)) == 0;
4505 4739 zap_cursor_advance(&zc)) {
4506 4740 if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
4507 4741 NULL, 0)) != 0)
4508 4742 break;
4509 4743 }
4510 4744 zap_cursor_fini(&zc);
4511 4745 return (error);
4512 4746 }
4513 4747
4514 4748 static int
4515 4749 zfs_ioc_smb_acl(zfs_cmd_t *zc)
4516 4750 {
4517 4751 vnode_t *vp;
4518 4752 znode_t *dzp;
4519 4753 vnode_t *resourcevp = NULL;
4520 4754 znode_t *sharedir;
4521 4755 zfsvfs_t *zfsvfs;
4522 4756 nvlist_t *nvlist;
4523 4757 char *src, *target;
4524 4758 vattr_t vattr;
4525 4759 vsecattr_t vsec;
4526 4760 int error = 0;
4527 4761
4528 4762 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
4529 4763 NO_FOLLOW, NULL, &vp)) != 0)
4530 4764 return (error);
4531 4765
4532 4766 /* Now make sure mntpnt and dataset are ZFS */
4533 4767
4534 4768 if (vp->v_vfsp->vfs_fstype != zfsfstype ||
4535 4769 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
4536 4770 zc->zc_name) != 0)) {
4537 4771 VN_RELE(vp);
4538 4772 return (EINVAL);
4539 4773 }
4540 4774
4541 4775 dzp = VTOZ(vp);
4542 4776 zfsvfs = dzp->z_zfsvfs;
4543 4777 ZFS_ENTER(zfsvfs);
4544 4778
4545 4779 /*
4546 4780 * Create share dir if its missing.
4547 4781 */
4548 4782 mutex_enter(&zfsvfs->z_lock);
4549 4783 if (zfsvfs->z_shares_dir == 0) {
4550 4784 dmu_tx_t *tx;
4551 4785
4552 4786 tx = dmu_tx_create(zfsvfs->z_os);
4553 4787 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
4554 4788 ZFS_SHARES_DIR);
4555 4789 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
4556 4790 error = dmu_tx_assign(tx, TXG_WAIT);
4557 4791 if (error) {
4558 4792 dmu_tx_abort(tx);
4559 4793 } else {
4560 4794 error = zfs_create_share_dir(zfsvfs, tx);
4561 4795 dmu_tx_commit(tx);
4562 4796 }
4563 4797 if (error) {
4564 4798 mutex_exit(&zfsvfs->z_lock);
4565 4799 VN_RELE(vp);
4566 4800 ZFS_EXIT(zfsvfs);
4567 4801 return (error);
4568 4802 }
4569 4803 }
4570 4804 mutex_exit(&zfsvfs->z_lock);
4571 4805
4572 4806 ASSERT(zfsvfs->z_shares_dir);
4573 4807 if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
4574 4808 VN_RELE(vp);
4575 4809 ZFS_EXIT(zfsvfs);
4576 4810 return (error);
4577 4811 }
4578 4812
4579 4813 switch (zc->zc_cookie) {
4580 4814 case ZFS_SMB_ACL_ADD:
4581 4815 vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
4582 4816 vattr.va_type = VREG;
4583 4817 vattr.va_mode = S_IFREG|0777;
4584 4818 vattr.va_uid = 0;
4585 4819 vattr.va_gid = 0;
4586 4820
4587 4821 vsec.vsa_mask = VSA_ACE;
4588 4822 vsec.vsa_aclentp = &full_access;
4589 4823 vsec.vsa_aclentsz = sizeof (full_access);
4590 4824 vsec.vsa_aclcnt = 1;
4591 4825
4592 4826 error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
4593 4827 &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
4594 4828 if (resourcevp)
4595 4829 VN_RELE(resourcevp);
4596 4830 break;
4597 4831
4598 4832 case ZFS_SMB_ACL_REMOVE:
4599 4833 error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
4600 4834 NULL, 0);
4601 4835 break;
4602 4836
4603 4837 case ZFS_SMB_ACL_RENAME:
4604 4838 if ((error = get_nvlist(zc->zc_nvlist_src,
4605 4839 zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
4606 4840 VN_RELE(vp);
4607 4841 ZFS_EXIT(zfsvfs);
4608 4842 return (error);
4609 4843 }
4610 4844 if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
4611 4845 nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
4612 4846 &target)) {
4613 4847 VN_RELE(vp);
4614 4848 VN_RELE(ZTOV(sharedir));
4615 4849 ZFS_EXIT(zfsvfs);
4616 4850 nvlist_free(nvlist);
4617 4851 return (error);
4618 4852 }
4619 4853 error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
4620 4854 kcred, NULL, 0);
4621 4855 nvlist_free(nvlist);
4622 4856 break;
4623 4857
4624 4858 case ZFS_SMB_ACL_PURGE:
4625 4859 error = zfs_smb_acl_purge(sharedir);
4626 4860 break;
4627 4861
4628 4862 default:
4629 4863 error = EINVAL;
4630 4864 break;
4631 4865 }
4632 4866
4633 4867 VN_RELE(vp);
4634 4868 VN_RELE(ZTOV(sharedir));
4635 4869
4636 4870 ZFS_EXIT(zfsvfs);
4637 4871
4638 4872 return (error);
4639 4873 }
4640 4874
4641 4875 /*
4642 4876 * inputs:
4643 4877 * zc_name name of filesystem
4644 4878 * zc_value short name of snap
4645 4879 * zc_string user-supplied tag for this hold
4646 4880 * zc_cookie recursive flag
4647 4881 * zc_temphold set if hold is temporary
4648 4882 * zc_cleanup_fd cleanup-on-exit file descriptor for calling process
4649 4883 * zc_sendobj if non-zero, the objid for zc_name@zc_value
4650 4884 * zc_createtxg if zc_sendobj is non-zero, snap must have zc_createtxg
4651 4885 *
4652 4886 * outputs: none
4653 4887 */
4654 4888 static int
4655 4889 zfs_ioc_hold(zfs_cmd_t *zc)
4656 4890 {
4657 4891 boolean_t recursive = zc->zc_cookie;
4658 4892 spa_t *spa;
4659 4893 dsl_pool_t *dp;
4660 4894 dsl_dataset_t *ds;
4661 4895 int error;
4662 4896 minor_t minor = 0;
4663 4897
4664 4898 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
4665 4899 return (EINVAL);
4666 4900
4667 4901 if (zc->zc_sendobj == 0) {
4668 4902 return (dsl_dataset_user_hold(zc->zc_name, zc->zc_value,
4669 4903 zc->zc_string, recursive, zc->zc_temphold,
4670 4904 zc->zc_cleanup_fd));
4671 4905 }
4672 4906
4673 4907 if (recursive)
4674 4908 return (EINVAL);
4675 4909
4676 4910 error = spa_open(zc->zc_name, &spa, FTAG);
4677 4911 if (error)
4678 4912 return (error);
4679 4913
4680 4914 dp = spa_get_dsl(spa);
4681 4915 rw_enter(&dp->dp_config_rwlock, RW_READER);
4682 4916 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
4683 4917 rw_exit(&dp->dp_config_rwlock);
4684 4918 spa_close(spa, FTAG);
4685 4919 if (error)
4686 4920 return (error);
4687 4921
4688 4922 /*
4689 4923 * Until we have a hold on this snapshot, it's possible that
4690 4924 * zc_sendobj could've been destroyed and reused as part
4691 4925 * of a later txg. Make sure we're looking at the right object.
4692 4926 */
4693 4927 if (zc->zc_createtxg != ds->ds_phys->ds_creation_txg) {
4694 4928 dsl_dataset_rele(ds, FTAG);
4695 4929 return (ENOENT);
4696 4930 }
4697 4931
4698 4932 if (zc->zc_cleanup_fd != -1 && zc->zc_temphold) {
4699 4933 error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
4700 4934 if (error) {
4701 4935 dsl_dataset_rele(ds, FTAG);
4702 4936 return (error);
4703 4937 }
4704 4938 }
4705 4939
4706 4940 error = dsl_dataset_user_hold_for_send(ds, zc->zc_string,
4707 4941 zc->zc_temphold);
4708 4942 if (minor != 0) {
4709 4943 if (error == 0) {
4710 4944 dsl_register_onexit_hold_cleanup(ds, zc->zc_string,
4711 4945 minor);
4712 4946 }
4713 4947 zfs_onexit_fd_rele(zc->zc_cleanup_fd);
4714 4948 }
4715 4949 dsl_dataset_rele(ds, FTAG);
4716 4950
4717 4951 return (error);
4718 4952 }
4719 4953
4720 4954 /*
4721 4955 * inputs:
4722 4956 * zc_name name of dataset from which we're releasing a user hold
4723 4957 * zc_value short name of snap
4724 4958 * zc_string user-supplied tag for this hold
4725 4959 * zc_cookie recursive flag
4726 4960 *
4727 4961 * outputs: none
4728 4962 */
4729 4963 static int
4730 4964 zfs_ioc_release(zfs_cmd_t *zc)
4731 4965 {
4732 4966 boolean_t recursive = zc->zc_cookie;
4733 4967
4734 4968 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0)
4735 4969 return (EINVAL);
4736 4970
4737 4971 return (dsl_dataset_user_release(zc->zc_name, zc->zc_value,
4738 4972 zc->zc_string, recursive));
4739 4973 }
4740 4974
4741 4975 /*
4742 4976 * inputs:
4743 4977 * zc_name name of filesystem
4744 4978 *
4745 4979 * outputs:
4746 4980 * zc_nvlist_src{_size} nvlist of snapshot holds
4747 4981 */
4748 4982 static int
4749 4983 zfs_ioc_get_holds(zfs_cmd_t *zc)
4750 4984 {
4751 4985 nvlist_t *nvp;
4752 4986 int error;
4753 4987
4754 4988 if ((error = dsl_dataset_get_holds(zc->zc_name, &nvp)) == 0) {
4755 4989 error = put_nvlist(zc, nvp);
4756 4990 nvlist_free(nvp);
4757 4991 }
4758 4992
4759 4993 return (error);
4760 4994 }
4761 4995
4762 4996 /*
4763 4997 * inputs:
4764 4998 * zc_name name of new filesystem or snapshot
4765 4999 * zc_value full name of old snapshot
4766 5000 *
4767 5001 * outputs:
4768 5002 * zc_cookie space in bytes
4769 5003 * zc_objset_type compressed space in bytes
4770 5004 * zc_perm_action uncompressed space in bytes
4771 5005 */
4772 5006 static int
4773 5007 zfs_ioc_space_written(zfs_cmd_t *zc)
4774 5008 {
4775 5009 int error;
4776 5010 dsl_dataset_t *new, *old;
4777 5011
4778 5012 error = dsl_dataset_hold(zc->zc_name, FTAG, &new);
4779 5013 if (error != 0)
4780 5014 return (error);
4781 5015 error = dsl_dataset_hold(zc->zc_value, FTAG, &old);
4782 5016 if (error != 0) {
↓ open down ↓ |
333 lines elided |
↑ open up ↑ |
4783 5017 dsl_dataset_rele(new, FTAG);
4784 5018 return (error);
4785 5019 }
4786 5020
4787 5021 error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
4788 5022 &zc->zc_objset_type, &zc->zc_perm_action);
4789 5023 dsl_dataset_rele(old, FTAG);
4790 5024 dsl_dataset_rele(new, FTAG);
4791 5025 return (error);
4792 5026 }
4793 -
4794 5027 /*
4795 - * inputs:
4796 - * zc_name full name of last snapshot
4797 - * zc_value full name of first snapshot
4798 - *
4799 - * outputs:
4800 - * zc_cookie space in bytes
4801 - * zc_objset_type compressed space in bytes
4802 - * zc_perm_action uncompressed space in bytes
5028 + * innvl: {
5029 + * "firstsnap" -> snapshot name
5030 + * }
5031 + *
5032 + * outnvl: {
5033 + * "used" -> space in bytes
5034 + * "compressed" -> compressed space in bytes
5035 + * "uncompressed" -> uncompressed space in bytes
5036 + * }
4803 5037 */
4804 5038 static int
4805 -zfs_ioc_space_snaps(zfs_cmd_t *zc)
5039 +zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
4806 5040 {
4807 5041 int error;
4808 5042 dsl_dataset_t *new, *old;
5043 + char *firstsnap;
5044 + uint64_t used, comp, uncomp;
4809 5045
4810 - error = dsl_dataset_hold(zc->zc_name, FTAG, &new);
5046 + if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0)
5047 + return (EINVAL);
5048 +
5049 + error = dsl_dataset_hold(lastsnap, FTAG, &new);
4811 5050 if (error != 0)
4812 5051 return (error);
4813 - error = dsl_dataset_hold(zc->zc_value, FTAG, &old);
5052 + error = dsl_dataset_hold(firstsnap, FTAG, &old);
4814 5053 if (error != 0) {
4815 5054 dsl_dataset_rele(new, FTAG);
4816 5055 return (error);
4817 5056 }
4818 5057
4819 - error = dsl_dataset_space_wouldfree(old, new, &zc->zc_cookie,
4820 - &zc->zc_objset_type, &zc->zc_perm_action);
5058 + error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
4821 5059 dsl_dataset_rele(old, FTAG);
4822 5060 dsl_dataset_rele(new, FTAG);
5061 + fnvlist_add_uint64(outnvl, "used", used);
5062 + fnvlist_add_uint64(outnvl, "compressed", comp);
5063 + fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
4823 5064 return (error);
4824 5065 }
4825 5066
4826 5067 /*
4827 - * pool create, destroy, and export don't log the history as part of
4828 - * zfsdev_ioctl, but rather zfs_ioc_pool_create, and zfs_ioc_pool_export
4829 - * do the logging of those commands.
4830 - */
4831 -static zfs_ioc_vec_t zfs_ioc_vec[] = {
4832 - { zfs_ioc_pool_create, zfs_secpolicy_config, POOL_NAME, B_FALSE,
4833 - POOL_CHECK_NONE },
4834 - { zfs_ioc_pool_destroy, zfs_secpolicy_config, POOL_NAME, B_FALSE,
4835 - POOL_CHECK_NONE },
4836 - { zfs_ioc_pool_import, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4837 - POOL_CHECK_NONE },
4838 - { zfs_ioc_pool_export, zfs_secpolicy_config, POOL_NAME, B_FALSE,
4839 - POOL_CHECK_NONE },
4840 - { zfs_ioc_pool_configs, zfs_secpolicy_none, NO_NAME, B_FALSE,
4841 - POOL_CHECK_NONE },
4842 - { zfs_ioc_pool_stats, zfs_secpolicy_read, POOL_NAME, B_FALSE,
4843 - POOL_CHECK_NONE },
4844 - { zfs_ioc_pool_tryimport, zfs_secpolicy_config, NO_NAME, B_FALSE,
4845 - POOL_CHECK_NONE },
4846 - { zfs_ioc_pool_scan, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4847 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4848 - { zfs_ioc_pool_freeze, zfs_secpolicy_config, NO_NAME, B_FALSE,
4849 - POOL_CHECK_READONLY },
4850 - { zfs_ioc_pool_upgrade, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4851 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4852 - { zfs_ioc_pool_get_history, zfs_secpolicy_config, POOL_NAME, B_FALSE,
4853 - POOL_CHECK_NONE },
4854 - { zfs_ioc_vdev_add, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4855 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4856 - { zfs_ioc_vdev_remove, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4857 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4858 - { zfs_ioc_vdev_set_state, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4859 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4860 - { zfs_ioc_vdev_attach, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4861 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4862 - { zfs_ioc_vdev_detach, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4863 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4864 - { zfs_ioc_vdev_setpath, zfs_secpolicy_config, POOL_NAME, B_FALSE,
4865 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4866 - { zfs_ioc_vdev_setfru, zfs_secpolicy_config, POOL_NAME, B_FALSE,
4867 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4868 - { zfs_ioc_objset_stats, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4869 - POOL_CHECK_SUSPENDED },
4870 - { zfs_ioc_objset_zplprops, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4871 - POOL_CHECK_NONE },
4872 - { zfs_ioc_dataset_list_next, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4873 - POOL_CHECK_SUSPENDED },
4874 - { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4875 - POOL_CHECK_SUSPENDED },
4876 - { zfs_ioc_set_prop, zfs_secpolicy_none, DATASET_NAME, B_TRUE,
4877 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4878 - { zfs_ioc_create, zfs_secpolicy_create, DATASET_NAME, B_TRUE,
4879 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4880 - { zfs_ioc_destroy, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE,
4881 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4882 - { zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, B_TRUE,
4883 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4884 - { zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE,
4885 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4886 - { zfs_ioc_recv, zfs_secpolicy_receive, DATASET_NAME, B_TRUE,
4887 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4888 - { zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_FALSE,
4889 - POOL_CHECK_NONE },
4890 - { zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
4891 - POOL_CHECK_NONE },
4892 - { zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE,
4893 - POOL_CHECK_NONE },
4894 - { zfs_ioc_inject_list_next, zfs_secpolicy_inject, NO_NAME, B_FALSE,
4895 - POOL_CHECK_NONE },
4896 - { zfs_ioc_error_log, zfs_secpolicy_inject, POOL_NAME, B_FALSE,
4897 - POOL_CHECK_NONE },
4898 - { zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4899 - POOL_CHECK_NONE },
4900 - { zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE,
4901 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4902 - { zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE,
4903 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4904 - { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_diff, POOL_NAME, B_FALSE,
4905 - POOL_CHECK_NONE },
4906 - { zfs_ioc_obj_to_path, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
4907 - POOL_CHECK_SUSPENDED },
4908 - { zfs_ioc_pool_set_props, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4909 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4910 - { zfs_ioc_pool_get_props, zfs_secpolicy_read, POOL_NAME, B_FALSE,
4911 - POOL_CHECK_NONE },
4912 - { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, DATASET_NAME, B_TRUE,
4913 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4914 - { zfs_ioc_get_fsacl, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4915 - POOL_CHECK_NONE },
4916 - { zfs_ioc_share, zfs_secpolicy_share, DATASET_NAME, B_FALSE,
4917 - POOL_CHECK_NONE },
4918 - { zfs_ioc_inherit_prop, zfs_secpolicy_inherit, DATASET_NAME, B_TRUE,
4919 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4920 - { zfs_ioc_smb_acl, zfs_secpolicy_smb_acl, DATASET_NAME, B_FALSE,
4921 - POOL_CHECK_NONE },
4922 - { zfs_ioc_userspace_one, zfs_secpolicy_userspace_one, DATASET_NAME,
4923 - B_FALSE, POOL_CHECK_NONE },
4924 - { zfs_ioc_userspace_many, zfs_secpolicy_userspace_many, DATASET_NAME,
4925 - B_FALSE, POOL_CHECK_NONE },
4926 - { zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
4927 - DATASET_NAME, B_FALSE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4928 - { zfs_ioc_hold, zfs_secpolicy_hold, DATASET_NAME, B_TRUE,
4929 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4930 - { zfs_ioc_release, zfs_secpolicy_release, DATASET_NAME, B_TRUE,
4931 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4932 - { zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4933 - POOL_CHECK_SUSPENDED },
4934 - { zfs_ioc_objset_recvd_props, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4935 - POOL_CHECK_NONE },
4936 - { zfs_ioc_vdev_split, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4937 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4938 - { zfs_ioc_next_obj, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4939 - POOL_CHECK_NONE },
4940 - { zfs_ioc_diff, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
4941 - POOL_CHECK_NONE },
4942 - { zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot, DATASET_NAME,
4943 - B_FALSE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4944 - { zfs_ioc_obj_to_stats, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
4945 - POOL_CHECK_SUSPENDED },
4946 - { zfs_ioc_space_written, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4947 - POOL_CHECK_SUSPENDED },
4948 - { zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4949 - POOL_CHECK_SUSPENDED },
4950 - { zfs_ioc_destroy_snaps_nvl, zfs_secpolicy_destroy_recursive,
4951 - DATASET_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4952 - { zfs_ioc_pool_reguid, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4953 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
4954 - { zfs_ioc_pool_reopen, zfs_secpolicy_config, POOL_NAME, B_TRUE,
4955 - POOL_CHECK_SUSPENDED },
4956 - { zfs_ioc_send_progress, zfs_secpolicy_read, DATASET_NAME, B_FALSE,
4957 - POOL_CHECK_NONE }
4958 -};
5068 + * innvl: {
5069 + * "fd" -> file descriptor to write stream to (int32)
5070 + * (optional) "fromsnap" -> full snap name to send an incremental from
5071 + * }
5072 + *
5073 + * outnvl is unused
5074 + */
5075 +/* ARGSUSED */
5076 +static int
5077 +zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5078 +{
5079 + objset_t *fromsnap = NULL;
5080 + objset_t *tosnap;
5081 + int error;
5082 + offset_t off;
5083 + char *fromname;
5084 + int fd;
5085 +
5086 + error = nvlist_lookup_int32(innvl, "fd", &fd);
5087 + if (error != 0)
5088 + return (EINVAL);
5089 +
5090 + error = dmu_objset_hold(snapname, FTAG, &tosnap);
5091 + if (error)
5092 + return (error);
5093 +
5094 + error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5095 + if (error == 0) {
5096 + error = dmu_objset_hold(fromname, FTAG, &fromsnap);
5097 + if (error) {
5098 + dmu_objset_rele(tosnap, FTAG);
5099 + return (error);
5100 + }
5101 + }
5102 +
5103 + file_t *fp = getf(fd);
5104 + if (fp == NULL) {
5105 + dmu_objset_rele(tosnap, FTAG);
5106 + if (fromsnap != NULL)
5107 + dmu_objset_rele(fromsnap, FTAG);
5108 + return (EBADF);
5109 + }
5110 +
5111 + off = fp->f_offset;
5112 + error = dmu_send(tosnap, fromsnap, fd, fp->f_vnode, &off);
5113 +
5114 + if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5115 + fp->f_offset = off;
5116 + releasef(fd);
5117 + if (fromsnap != NULL)
5118 + dmu_objset_rele(fromsnap, FTAG);
5119 + dmu_objset_rele(tosnap, FTAG);
5120 + return (error);
5121 +}
5122 +
5123 +/*
5124 + * Determine approximately how large a zfs send stream will be -- the number
5125 + * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5126 + *
5127 + * innvl: {
5128 + * (optional) "fromsnap" -> full snap name to send an incremental from
5129 + * }
5130 + *
5131 + * outnvl: {
5132 + * "space" -> bytes of space (uint64)
5133 + * }
5134 + */
5135 +static int
5136 +zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5137 +{
5138 + objset_t *fromsnap = NULL;
5139 + objset_t *tosnap;
5140 + int error;
5141 + char *fromname;
5142 + uint64_t space;
5143 +
5144 + error = dmu_objset_hold(snapname, FTAG, &tosnap);
5145 + if (error)
5146 + return (error);
5147 +
5148 + error = nvlist_lookup_string(innvl, "fromsnap", &fromname);
5149 + if (error == 0) {
5150 + error = dmu_objset_hold(fromname, FTAG, &fromsnap);
5151 + if (error) {
5152 + dmu_objset_rele(tosnap, FTAG);
5153 + return (error);
5154 + }
5155 + }
5156 +
5157 + error = dmu_send_estimate(tosnap, fromsnap, &space);
5158 + fnvlist_add_uint64(outnvl, "space", space);
5159 +
5160 + if (fromsnap != NULL)
5161 + dmu_objset_rele(fromsnap, FTAG);
5162 + dmu_objset_rele(tosnap, FTAG);
5163 + return (error);
5164 +}
5165 +
5166 +
5167 +static zfs_ioc_vec_t zfs_ioc_vec[ZFS_IOC_LAST - ZFS_IOC_FIRST];
5168 +
5169 +static void
5170 +zfs_ioctl_register_legacy(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5171 + zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
5172 + boolean_t log_history, zfs_ioc_poolcheck_t pool_check)
5173 +{
5174 + zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
5175 +
5176 + ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
5177 + ASSERT3U(ioc, <, ZFS_IOC_LAST);
5178 + ASSERT3P(vec->zvec_legacy_func, ==, NULL);
5179 + ASSERT3P(vec->zvec_func, ==, NULL);
5180 +
5181 + vec->zvec_legacy_func = func;
5182 + vec->zvec_secpolicy = secpolicy;
5183 + vec->zvec_namecheck = namecheck;
5184 + vec->zvec_allow_log = log_history;
5185 + vec->zvec_pool_check = pool_check;
5186 +}
5187 +
5188 +/*
5189 + * See the block comment at the beginning of this file for details on
5190 + * each argument to this function.
5191 + */
5192 +static void
5193 +zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
5194 + zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
5195 + zfs_ioc_poolcheck_t pool_check, boolean_t smush_outnvlist,
5196 + boolean_t allow_log)
5197 +{
5198 + zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
5199 +
5200 + ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
5201 + ASSERT3U(ioc, <, ZFS_IOC_LAST);
5202 + ASSERT3P(vec->zvec_legacy_func, ==, NULL);
5203 + ASSERT3P(vec->zvec_func, ==, NULL);
5204 +
5205 + /* if we are logging, the name must be valid */
5206 + ASSERT(!allow_log || namecheck != NO_NAME);
5207 +
5208 + vec->zvec_name = name;
5209 + vec->zvec_func = func;
5210 + vec->zvec_secpolicy = secpolicy;
5211 + vec->zvec_namecheck = namecheck;
5212 + vec->zvec_pool_check = pool_check;
5213 + vec->zvec_smush_outnvlist = smush_outnvlist;
5214 + vec->zvec_allow_log = allow_log;
5215 +}
5216 +
5217 +static void
5218 +zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5219 + zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
5220 + zfs_ioc_poolcheck_t pool_check)
5221 +{
5222 + zfs_ioctl_register_legacy(ioc, func, secpolicy,
5223 + POOL_NAME, log_history, pool_check);
5224 +}
5225 +
5226 +static void
5227 +zfs_ioctl_register_dataset_nolog(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5228 + zfs_secpolicy_func_t *secpolicy, zfs_ioc_poolcheck_t pool_check)
5229 +{
5230 + zfs_ioctl_register_legacy(ioc, func, secpolicy,
5231 + DATASET_NAME, B_FALSE, pool_check);
5232 +}
5233 +
5234 +static void
5235 +zfs_ioctl_register_pool_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
5236 +{
5237 + zfs_ioctl_register_legacy(ioc, func, zfs_secpolicy_config,
5238 + POOL_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5239 +}
5240 +
5241 +static void
5242 +zfs_ioctl_register_pool_meta(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5243 + zfs_secpolicy_func_t *secpolicy)
5244 +{
5245 + zfs_ioctl_register_legacy(ioc, func, secpolicy,
5246 + NO_NAME, B_FALSE, POOL_CHECK_NONE);
5247 +}
5248 +
5249 +static void
5250 +zfs_ioctl_register_dataset_read_secpolicy(zfs_ioc_t ioc,
5251 + zfs_ioc_legacy_func_t *func, zfs_secpolicy_func_t *secpolicy)
5252 +{
5253 + zfs_ioctl_register_legacy(ioc, func, secpolicy,
5254 + DATASET_NAME, B_FALSE, POOL_CHECK_SUSPENDED);
5255 +}
5256 +
5257 +static void
5258 +zfs_ioctl_register_dataset_read(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
5259 +{
5260 + zfs_ioctl_register_dataset_read_secpolicy(ioc, func,
5261 + zfs_secpolicy_read);
5262 +}
5263 +
5264 +static void
5265 +zfs_ioctl_register_dataset_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5266 + zfs_secpolicy_func_t *secpolicy)
5267 +{
5268 + zfs_ioctl_register_legacy(ioc, func, secpolicy,
5269 + DATASET_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5270 +}
5271 +
5272 +static void
5273 +zfs_ioctl_init(void)
5274 +{
5275 + zfs_ioctl_register("snapshot", ZFS_IOC_SNAPSHOT,
5276 + zfs_ioc_snapshot, zfs_secpolicy_snapshot, POOL_NAME,
5277 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5278 +
5279 + zfs_ioctl_register("log_history", ZFS_IOC_LOG_HISTORY,
5280 + zfs_ioc_log_history, zfs_secpolicy_log_history, NO_NAME,
5281 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE);
5282 +
5283 + zfs_ioctl_register("space_snaps", ZFS_IOC_SPACE_SNAPS,
5284 + zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME,
5285 + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5286 +
5287 + zfs_ioctl_register("send", ZFS_IOC_SEND_NEW,
5288 + zfs_ioc_send_new, zfs_secpolicy_send_new, DATASET_NAME,
5289 + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5290 +
5291 + zfs_ioctl_register("send_space", ZFS_IOC_SEND_SPACE,
5292 + zfs_ioc_send_space, zfs_secpolicy_read, DATASET_NAME,
5293 + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5294 +
5295 + zfs_ioctl_register("create", ZFS_IOC_CREATE,
5296 + zfs_ioc_create, zfs_secpolicy_create_clone, DATASET_NAME,
5297 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5298 +
5299 + zfs_ioctl_register("clone", ZFS_IOC_CLONE,
5300 + zfs_ioc_clone, zfs_secpolicy_create_clone, DATASET_NAME,
5301 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5302 +
5303 + zfs_ioctl_register("destroy_snaps", ZFS_IOC_DESTROY_SNAPS,
5304 + zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, POOL_NAME,
5305 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5306 +
5307 + /* IOCTLS that use the legacy function signature */
5308 +
5309 + zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
5310 + zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_READONLY);
5311 +
5312 + zfs_ioctl_register_pool(ZFS_IOC_POOL_CREATE, zfs_ioc_pool_create,
5313 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5314 + zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SCAN,
5315 + zfs_ioc_pool_scan);
5316 + zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_UPGRADE,
5317 + zfs_ioc_pool_upgrade);
5318 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ADD,
5319 + zfs_ioc_vdev_add);
5320 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_REMOVE,
5321 + zfs_ioc_vdev_remove);
5322 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SET_STATE,
5323 + zfs_ioc_vdev_set_state);
5324 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ATTACH,
5325 + zfs_ioc_vdev_attach);
5326 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_DETACH,
5327 + zfs_ioc_vdev_detach);
5328 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETPATH,
5329 + zfs_ioc_vdev_setpath);
5330 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETFRU,
5331 + zfs_ioc_vdev_setfru);
5332 + zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SET_PROPS,
5333 + zfs_ioc_pool_set_props);
5334 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SPLIT,
5335 + zfs_ioc_vdev_split);
5336 + zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_REGUID,
5337 + zfs_ioc_pool_reguid);
5338 +
5339 + zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_CONFIGS,
5340 + zfs_ioc_pool_configs, zfs_secpolicy_none);
5341 + zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_TRYIMPORT,
5342 + zfs_ioc_pool_tryimport, zfs_secpolicy_config);
5343 + zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_FAULT,
5344 + zfs_ioc_inject_fault, zfs_secpolicy_inject);
5345 + zfs_ioctl_register_pool_meta(ZFS_IOC_CLEAR_FAULT,
5346 + zfs_ioc_clear_fault, zfs_secpolicy_inject);
5347 + zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_LIST_NEXT,
5348 + zfs_ioc_inject_list_next, zfs_secpolicy_inject);
5349 +
5350 + /*
5351 + * pool destroy, and export don't log the history as part of
5352 + * zfsdev_ioctl, but rather zfs_ioc_pool_export
5353 + * does the logging of those commands.
5354 + */
5355 + zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
5356 + zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
5357 + zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
5358 + zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
5359 +
5360 + zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
5361 + zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
5362 + zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_PROPS, zfs_ioc_pool_get_props,
5363 + zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
5364 +
5365 + zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
5366 + zfs_secpolicy_inject, B_FALSE, POOL_CHECK_SUSPENDED);
5367 + zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
5368 + zfs_ioc_dsobj_to_dsname,
5369 + zfs_secpolicy_diff, B_FALSE, POOL_CHECK_SUSPENDED);
5370 + zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
5371 + zfs_ioc_pool_get_history,
5372 + zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
5373 +
5374 + zfs_ioctl_register_pool(ZFS_IOC_POOL_IMPORT, zfs_ioc_pool_import,
5375 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5376 +
5377 + zfs_ioctl_register_pool(ZFS_IOC_CLEAR, zfs_ioc_clear,
5378 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
5379 + zfs_ioctl_register_pool(ZFS_IOC_POOL_REOPEN, zfs_ioc_pool_reopen,
5380 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
5381 +
5382 + zfs_ioctl_register_dataset_read(ZFS_IOC_SPACE_WRITTEN,
5383 + zfs_ioc_space_written);
5384 + zfs_ioctl_register_dataset_read(ZFS_IOC_GET_HOLDS,
5385 + zfs_ioc_get_holds);
5386 + zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_RECVD_PROPS,
5387 + zfs_ioc_objset_recvd_props);
5388 + zfs_ioctl_register_dataset_read(ZFS_IOC_NEXT_OBJ,
5389 + zfs_ioc_next_obj);
5390 + zfs_ioctl_register_dataset_read(ZFS_IOC_GET_FSACL,
5391 + zfs_ioc_get_fsacl);
5392 + zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_STATS,
5393 + zfs_ioc_objset_stats);
5394 + zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_ZPLPROPS,
5395 + zfs_ioc_objset_zplprops);
5396 + zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
5397 + zfs_ioc_dataset_list_next);
5398 + zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
5399 + zfs_ioc_snapshot_list_next);
5400 + zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
5401 + zfs_ioc_send_progress);
5402 +
5403 + zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
5404 + zfs_ioc_diff, zfs_secpolicy_diff);
5405 + zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
5406 + zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
5407 + zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
5408 + zfs_ioc_obj_to_path, zfs_secpolicy_diff);
5409 + zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
5410 + zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
5411 + zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
5412 + zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
5413 + zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
5414 + zfs_ioc_send, zfs_secpolicy_send);
5415 +
5416 + zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
5417 + zfs_secpolicy_none);
5418 + zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
5419 + zfs_secpolicy_destroy);
5420 + zfs_ioctl_register_dataset_modify(ZFS_IOC_ROLLBACK, zfs_ioc_rollback,
5421 + zfs_secpolicy_rollback);
5422 + zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
5423 + zfs_secpolicy_rename);
5424 + zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
5425 + zfs_secpolicy_recv);
5426 + zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
5427 + zfs_secpolicy_promote);
5428 + zfs_ioctl_register_dataset_modify(ZFS_IOC_HOLD, zfs_ioc_hold,
5429 + zfs_secpolicy_hold);
5430 + zfs_ioctl_register_dataset_modify(ZFS_IOC_RELEASE, zfs_ioc_release,
5431 + zfs_secpolicy_release);
5432 + zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
5433 + zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
5434 + zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,
5435 + zfs_secpolicy_set_fsacl);
5436 +
5437 + zfs_ioctl_register_dataset_nolog(ZFS_IOC_SHARE, zfs_ioc_share,
5438 + zfs_secpolicy_share, POOL_CHECK_NONE);
5439 + zfs_ioctl_register_dataset_nolog(ZFS_IOC_SMB_ACL, zfs_ioc_smb_acl,
5440 + zfs_secpolicy_smb_acl, POOL_CHECK_NONE);
5441 + zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERSPACE_UPGRADE,
5442 + zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
5443 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5444 + zfs_ioctl_register_dataset_nolog(ZFS_IOC_TMP_SNAPSHOT,
5445 + zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot,
5446 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5447 +}
4959 5448
4960 5449 int
4961 5450 pool_status_check(const char *name, zfs_ioc_namecheck_t type,
4962 5451 zfs_ioc_poolcheck_t check)
4963 5452 {
4964 5453 spa_t *spa;
4965 5454 int error;
4966 5455
4967 5456 ASSERT(type == POOL_NAME || type == DATASET_NAME);
4968 5457
4969 5458 if (check & POOL_CHECK_NONE)
4970 5459 return (0);
4971 5460
4972 5461 error = spa_open(name, &spa, FTAG);
4973 5462 if (error == 0) {
4974 5463 if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa))
4975 5464 error = EAGAIN;
4976 5465 else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa))
4977 5466 error = EROFS;
4978 5467 spa_close(spa, FTAG);
4979 5468 }
4980 5469 return (error);
4981 5470 }
4982 5471
4983 5472 /*
4984 5473 * Find a free minor number.
4985 5474 */
4986 5475 minor_t
4987 5476 zfsdev_minor_alloc(void)
4988 5477 {
4989 5478 static minor_t last_minor;
4990 5479 minor_t m;
4991 5480
4992 5481 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
4993 5482
4994 5483 for (m = last_minor + 1; m != last_minor; m++) {
4995 5484 if (m > ZFSDEV_MAX_MINOR)
4996 5485 m = 1;
4997 5486 if (ddi_get_soft_state(zfsdev_state, m) == NULL) {
4998 5487 last_minor = m;
4999 5488 return (m);
5000 5489 }
5001 5490 }
5002 5491
5003 5492 return (0);
5004 5493 }
5005 5494
5006 5495 static int
5007 5496 zfs_ctldev_init(dev_t *devp)
5008 5497 {
5009 5498 minor_t minor;
5010 5499 zfs_soft_state_t *zs;
5011 5500
5012 5501 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
5013 5502 ASSERT(getminor(*devp) == 0);
5014 5503
5015 5504 minor = zfsdev_minor_alloc();
5016 5505 if (minor == 0)
5017 5506 return (ENXIO);
5018 5507
5019 5508 if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS)
5020 5509 return (EAGAIN);
5021 5510
5022 5511 *devp = makedevice(getemajor(*devp), minor);
5023 5512
5024 5513 zs = ddi_get_soft_state(zfsdev_state, minor);
5025 5514 zs->zss_type = ZSST_CTLDEV;
5026 5515 zfs_onexit_init((zfs_onexit_t **)&zs->zss_data);
5027 5516
5028 5517 return (0);
5029 5518 }
5030 5519
5031 5520 static void
5032 5521 zfs_ctldev_destroy(zfs_onexit_t *zo, minor_t minor)
5033 5522 {
5034 5523 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
5035 5524
5036 5525 zfs_onexit_destroy(zo);
5037 5526 ddi_soft_state_free(zfsdev_state, minor);
5038 5527 }
5039 5528
5040 5529 void *
5041 5530 zfsdev_get_soft_state(minor_t minor, enum zfs_soft_state_type which)
5042 5531 {
5043 5532 zfs_soft_state_t *zp;
5044 5533
5045 5534 zp = ddi_get_soft_state(zfsdev_state, minor);
5046 5535 if (zp == NULL || zp->zss_type != which)
5047 5536 return (NULL);
5048 5537
5049 5538 return (zp->zss_data);
5050 5539 }
5051 5540
5052 5541 static int
5053 5542 zfsdev_open(dev_t *devp, int flag, int otyp, cred_t *cr)
5054 5543 {
5055 5544 int error = 0;
5056 5545
5057 5546 if (getminor(*devp) != 0)
5058 5547 return (zvol_open(devp, flag, otyp, cr));
5059 5548
5060 5549 /* This is the control device. Allocate a new minor if requested. */
5061 5550 if (flag & FEXCL) {
5062 5551 mutex_enter(&zfsdev_state_lock);
5063 5552 error = zfs_ctldev_init(devp);
5064 5553 mutex_exit(&zfsdev_state_lock);
5065 5554 }
5066 5555
5067 5556 return (error);
5068 5557 }
5069 5558
5070 5559 static int
5071 5560 zfsdev_close(dev_t dev, int flag, int otyp, cred_t *cr)
5072 5561 {
5073 5562 zfs_onexit_t *zo;
5074 5563 minor_t minor = getminor(dev);
5075 5564
5076 5565 if (minor == 0)
5077 5566 return (0);
5078 5567
5079 5568 mutex_enter(&zfsdev_state_lock);
5080 5569 zo = zfsdev_get_soft_state(minor, ZSST_CTLDEV);
5081 5570 if (zo == NULL) {
5082 5571 mutex_exit(&zfsdev_state_lock);
5083 5572 return (zvol_close(dev, flag, otyp, cr));
5084 5573 }
↓ open down ↓ |
116 lines elided |
↑ open up ↑ |
5085 5574 zfs_ctldev_destroy(zo, minor);
5086 5575 mutex_exit(&zfsdev_state_lock);
5087 5576
5088 5577 return (0);
5089 5578 }
5090 5579
5091 5580 static int
5092 5581 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
5093 5582 {
5094 5583 zfs_cmd_t *zc;
5095 - uint_t vec;
5096 - int error, rc;
5584 + uint_t vecnum;
5585 + int error, rc, len;
5097 5586 minor_t minor = getminor(dev);
5587 + const zfs_ioc_vec_t *vec;
5588 + char *saved_poolname = NULL;
5589 + nvlist_t *innvl = NULL;
5098 5590
5099 5591 if (minor != 0 &&
5100 5592 zfsdev_get_soft_state(minor, ZSST_CTLDEV) == NULL)
5101 5593 return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp));
5102 5594
5103 - vec = cmd - ZFS_IOC;
5595 + vecnum = cmd - ZFS_IOC_FIRST;
5104 5596 ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip));
5105 5597
5106 - if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
5598 + if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
5107 5599 return (EINVAL);
5600 + vec = &zfs_ioc_vec[vecnum];
5108 5601
5109 5602 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
5110 5603
5111 5604 error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
5112 - if (error != 0)
5605 + if (error != 0) {
5113 5606 error = EFAULT;
5607 + goto out;
5608 + }
5114 5609
5115 - if ((error == 0) && !(flag & FKIOCTL))
5116 - error = zfs_ioc_vec[vec].zvec_secpolicy(zc, cr);
5610 + zc->zc_iflags = flag & FKIOCTL;
5611 + if (zc->zc_nvlist_src_size != 0) {
5612 + error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
5613 + zc->zc_iflags, &innvl);
5614 + if (error != 0)
5615 + goto out;
5616 + }
5117 5617
5118 5618 /*
5119 5619 * Ensure that all pool/dataset names are valid before we pass down to
5120 5620 * the lower layers.
5121 5621 */
5122 - if (error == 0) {
5123 - zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
5124 - zc->zc_iflags = flag & FKIOCTL;
5125 - switch (zfs_ioc_vec[vec].zvec_namecheck) {
5126 - case POOL_NAME:
5127 - if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
5128 - error = EINVAL;
5622 + zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
5623 + switch (vec->zvec_namecheck) {
5624 + case POOL_NAME:
5625 + if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
5626 + error = EINVAL;
5627 + else
5129 5628 error = pool_status_check(zc->zc_name,
5130 - zfs_ioc_vec[vec].zvec_namecheck,
5131 - zfs_ioc_vec[vec].zvec_pool_check);
5132 - break;
5629 + vec->zvec_namecheck, vec->zvec_pool_check);
5630 + break;
5133 5631
5134 - case DATASET_NAME:
5135 - if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
5136 - error = EINVAL;
5632 + case DATASET_NAME:
5633 + if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
5634 + error = EINVAL;
5635 + else
5137 5636 error = pool_status_check(zc->zc_name,
5138 - zfs_ioc_vec[vec].zvec_namecheck,
5139 - zfs_ioc_vec[vec].zvec_pool_check);
5140 - break;
5637 + vec->zvec_namecheck, vec->zvec_pool_check);
5638 + break;
5141 5639
5142 - case NO_NAME:
5143 - break;
5144 - }
5640 + case NO_NAME:
5641 + break;
5145 5642 }
5146 5643
5147 - if (error == 0)
5148 - error = zfs_ioc_vec[vec].zvec_func(zc);
5149 5644
5645 + if (error == 0 && !(flag & FKIOCTL))
5646 + error = vec->zvec_secpolicy(zc, innvl, cr);
5647 +
5648 + if (error != 0)
5649 + goto out;
5650 +
5651 + /* legacy ioctls can modify zc_name */
5652 + len = strcspn(zc->zc_name, "/@") + 1;
5653 + saved_poolname = kmem_alloc(len, KM_SLEEP);
5654 + (void) strlcpy(saved_poolname, zc->zc_name, len);
5655 +
5656 + if (vec->zvec_func != NULL) {
5657 + nvlist_t *outnvl;
5658 + int puterror = 0;
5659 + spa_t *spa;
5660 + nvlist_t *lognv = NULL;
5661 +
5662 + ASSERT(vec->zvec_legacy_func == NULL);
5663 +
5664 + /*
5665 + * Add the innvl to the lognv before calling the func,
5666 + * in case the func changes the innvl.
5667 + */
5668 + if (vec->zvec_allow_log) {
5669 + lognv = fnvlist_alloc();
5670 + fnvlist_add_string(lognv, ZPOOL_HIST_IOCTL,
5671 + vec->zvec_name);
5672 + if (!nvlist_empty(innvl)) {
5673 + fnvlist_add_nvlist(lognv, ZPOOL_HIST_INPUT_NVL,
5674 + innvl);
5675 + }
5676 + }
5677 +
5678 + outnvl = fnvlist_alloc();
5679 + error = vec->zvec_func(zc->zc_name, innvl, outnvl);
5680 +
5681 + if (error == 0 && vec->zvec_allow_log &&
5682 + spa_open(zc->zc_name, &spa, FTAG) == 0) {
5683 + if (!nvlist_empty(outnvl)) {
5684 + fnvlist_add_nvlist(lognv, ZPOOL_HIST_OUTPUT_NVL,
5685 + outnvl);
5686 + }
5687 + (void) spa_history_log_nvl(spa, lognv);
5688 + spa_close(spa, FTAG);
5689 + }
5690 + fnvlist_free(lognv);
5691 +
5692 + if (!nvlist_empty(outnvl) || zc->zc_nvlist_dst_size != 0) {
5693 + int smusherror = 0;
5694 + if (vec->zvec_smush_outnvlist) {
5695 + smusherror = nvlist_smush(outnvl,
5696 + zc->zc_nvlist_dst_size);
5697 + }
5698 + if (smusherror == 0)
5699 + puterror = put_nvlist(zc, outnvl);
5700 + }
5701 +
5702 + if (puterror != 0)
5703 + error = puterror;
5704 +
5705 + nvlist_free(outnvl);
5706 + } else {
5707 + error = vec->zvec_legacy_func(zc);
5708 + }
5709 +
5710 +out:
5711 + nvlist_free(innvl);
5150 5712 rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
5151 - if (error == 0) {
5152 - if (rc != 0)
5153 - error = EFAULT;
5154 - if (zfs_ioc_vec[vec].zvec_his_log)
5155 - zfs_log_history(zc);
5713 + if (error == 0 && rc != 0)
5714 + error = EFAULT;
5715 + if (error == 0 && vec->zvec_allow_log) {
5716 + char *s = tsd_get(zfs_allow_log_key);
5717 + if (s != NULL)
5718 + strfree(s);
5719 + (void) tsd_set(zfs_allow_log_key, saved_poolname);
5720 + } else {
5721 + if (saved_poolname != NULL)
5722 + strfree(saved_poolname);
5156 5723 }
5157 5724
5158 5725 kmem_free(zc, sizeof (zfs_cmd_t));
5159 5726 return (error);
5160 5727 }
5161 5728
5162 5729 static int
5163 5730 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
5164 5731 {
5165 5732 if (cmd != DDI_ATTACH)
5166 5733 return (DDI_FAILURE);
5167 5734
5168 5735 if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0,
5169 5736 DDI_PSEUDO, 0) == DDI_FAILURE)
5170 5737 return (DDI_FAILURE);
5171 5738
5172 5739 zfs_dip = dip;
5173 5740
5174 5741 ddi_report_dev(dip);
5175 5742
5176 5743 return (DDI_SUCCESS);
5177 5744 }
5178 5745
5179 5746 static int
5180 5747 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
5181 5748 {
5182 5749 if (spa_busy() || zfs_busy() || zvol_busy())
5183 5750 return (DDI_FAILURE);
5184 5751
5185 5752 if (cmd != DDI_DETACH)
5186 5753 return (DDI_FAILURE);
5187 5754
5188 5755 zfs_dip = NULL;
5189 5756
5190 5757 ddi_prop_remove_all(dip);
5191 5758 ddi_remove_minor_node(dip, NULL);
5192 5759
5193 5760 return (DDI_SUCCESS);
5194 5761 }
5195 5762
5196 5763 /*ARGSUSED*/
5197 5764 static int
5198 5765 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
5199 5766 {
5200 5767 switch (infocmd) {
5201 5768 case DDI_INFO_DEVT2DEVINFO:
5202 5769 *result = zfs_dip;
5203 5770 return (DDI_SUCCESS);
5204 5771
5205 5772 case DDI_INFO_DEVT2INSTANCE:
5206 5773 *result = (void *)0;
5207 5774 return (DDI_SUCCESS);
5208 5775 }
5209 5776
5210 5777 return (DDI_FAILURE);
5211 5778 }
5212 5779
5213 5780 /*
5214 5781 * OK, so this is a little weird.
5215 5782 *
5216 5783 * /dev/zfs is the control node, i.e. minor 0.
5217 5784 * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0.
5218 5785 *
5219 5786 * /dev/zfs has basically nothing to do except serve up ioctls,
5220 5787 * so most of the standard driver entry points are in zvol.c.
5221 5788 */
5222 5789 static struct cb_ops zfs_cb_ops = {
5223 5790 zfsdev_open, /* open */
5224 5791 zfsdev_close, /* close */
5225 5792 zvol_strategy, /* strategy */
5226 5793 nodev, /* print */
5227 5794 zvol_dump, /* dump */
5228 5795 zvol_read, /* read */
5229 5796 zvol_write, /* write */
5230 5797 zfsdev_ioctl, /* ioctl */
5231 5798 nodev, /* devmap */
5232 5799 nodev, /* mmap */
5233 5800 nodev, /* segmap */
5234 5801 nochpoll, /* poll */
5235 5802 ddi_prop_op, /* prop_op */
5236 5803 NULL, /* streamtab */
5237 5804 D_NEW | D_MP | D_64BIT, /* Driver compatibility flag */
5238 5805 CB_REV, /* version */
5239 5806 nodev, /* async read */
5240 5807 nodev, /* async write */
5241 5808 };
5242 5809
5243 5810 static struct dev_ops zfs_dev_ops = {
5244 5811 DEVO_REV, /* version */
5245 5812 0, /* refcnt */
5246 5813 zfs_info, /* info */
5247 5814 nulldev, /* identify */
5248 5815 nulldev, /* probe */
5249 5816 zfs_attach, /* attach */
5250 5817 zfs_detach, /* detach */
5251 5818 nodev, /* reset */
5252 5819 &zfs_cb_ops, /* driver operations */
5253 5820 NULL, /* no bus operations */
5254 5821 NULL, /* power */
5255 5822 ddi_quiesce_not_needed, /* quiesce */
5256 5823 };
5257 5824
5258 5825 static struct modldrv zfs_modldrv = {
5259 5826 &mod_driverops,
5260 5827 "ZFS storage pool",
↓ open down ↓ |
95 lines elided |
↑ open up ↑ |
5261 5828 &zfs_dev_ops
5262 5829 };
5263 5830
5264 5831 static struct modlinkage modlinkage = {
5265 5832 MODREV_1,
5266 5833 (void *)&zfs_modlfs,
5267 5834 (void *)&zfs_modldrv,
5268 5835 NULL
5269 5836 };
5270 5837
5271 -
5272 -uint_t zfs_fsyncer_key;
5273 -extern uint_t rrw_tsd_key;
5838 +static void
5839 +zfs_allow_log_destroy(void *arg)
5840 +{
5841 + char *poolname = arg;
5842 + strfree(poolname);
5843 +}
5274 5844
5275 5845 int
5276 5846 _init(void)
5277 5847 {
5278 5848 int error;
5279 5849
5280 5850 spa_init(FREAD | FWRITE);
5281 5851 zfs_init();
5282 5852 zvol_init();
5853 + zfs_ioctl_init();
5283 5854
5284 5855 if ((error = mod_install(&modlinkage)) != 0) {
5285 5856 zvol_fini();
5286 5857 zfs_fini();
5287 5858 spa_fini();
5288 5859 return (error);
5289 5860 }
5290 5861
5291 5862 tsd_create(&zfs_fsyncer_key, NULL);
5292 - tsd_create(&rrw_tsd_key, NULL);
5863 + tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
5864 + tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
5293 5865
5294 5866 error = ldi_ident_from_mod(&modlinkage, &zfs_li);
5295 5867 ASSERT(error == 0);
5296 5868 mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
5297 5869
5298 5870 return (0);
5299 5871 }
5300 5872
5301 5873 int
5302 5874 _fini(void)
5303 5875 {
5304 5876 int error;
5305 5877
5306 5878 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled)
5307 5879 return (EBUSY);
5308 5880
5309 5881 if ((error = mod_remove(&modlinkage)) != 0)
5310 5882 return (error);
5311 5883
5312 5884 zvol_fini();
5313 5885 zfs_fini();
5314 5886 spa_fini();
5315 5887 if (zfs_nfsshare_inited)
5316 5888 (void) ddi_modclose(nfs_mod);
5317 5889 if (zfs_smbshare_inited)
5318 5890 (void) ddi_modclose(smbsrv_mod);
5319 5891 if (zfs_nfsshare_inited || zfs_smbshare_inited)
5320 5892 (void) ddi_modclose(sharefs_mod);
5321 5893
5322 5894 tsd_destroy(&zfs_fsyncer_key);
5323 5895 ldi_ident_release(zfs_li);
5324 5896 zfs_li = NULL;
5325 5897 mutex_destroy(&zfs_share_lock);
5326 5898
5327 5899 return (error);
5328 5900 }
5329 5901
5330 5902 int
5331 5903 _info(struct modinfo *modinfop)
5332 5904 {
5333 5905 return (mod_info(&modlinkage, modinfop));
5334 5906 }
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX