diff options
author | pjd <pjd@FreeBSD.org> | 2011-02-27 19:41:40 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2011-02-27 19:41:40 +0000 |
commit | 1b03c5bf41222b723415638f03e00ed12cac076a (patch) | |
tree | ef515cadc08bf427e4d3f1360199ec9827b1596b /sys/cddl/contrib/opensolaris/common | |
parent | c67d387baf03726323703774b1b320235fb1f24b (diff) | |
download | FreeBSD-src-1b03c5bf41222b723415638f03e00ed12cac076a.zip FreeBSD-src-1b03c5bf41222b723415638f03e00ed12cac076a.tar.gz |
Finally... Import the latest open-source ZFS version - (SPA) 28.
Few new things available from now on:
- Data deduplication.
- Triple parity RAIDZ (RAIDZ3).
- zfs diff.
- zpool split.
- Snapshot holds.
- zpool import -F. Allows to rewind corrupted pool to earlier
transaction group.
- Possibility to import pool in read-only mode.
MFC after: 1 month
Diffstat (limited to 'sys/cddl/contrib/opensolaris/common')
23 files changed, 1566 insertions, 337 deletions
diff --git a/sys/cddl/contrib/opensolaris/common/acl/acl_common.c b/sys/cddl/contrib/opensolaris/common/acl/acl_common.c index 5e8de19..47e0ffd 100644 --- a/sys/cddl/contrib/opensolaris/common/acl/acl_common.c +++ b/sys/cddl/contrib/opensolaris/common/acl/acl_common.c @@ -19,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/stat.h> #include <sys/avl.h> @@ -152,166 +149,6 @@ typedef struct ace_list { int seen; /* bitmask of all aclent_t a_type values seen */ } ace_list_t; -ace_t trivial_acl[] = { - {(uid_t)-1, 0, ACE_OWNER, ACE_ACCESS_DENIED_ACE_TYPE}, - {(uid_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES| - ACE_WRITE_NAMED_ATTRS, ACE_OWNER, ACE_ACCESS_ALLOWED_ACE_TYPE}, - {(uid_t)-1, 0, ACE_GROUP|ACE_IDENTIFIER_GROUP, - ACE_ACCESS_DENIED_ACE_TYPE}, - {(uid_t)-1, 0, ACE_GROUP|ACE_IDENTIFIER_GROUP, - ACE_ACCESS_ALLOWED_ACE_TYPE}, - {(uid_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER| ACE_WRITE_ATTRIBUTES| - ACE_WRITE_NAMED_ATTRS, ACE_EVERYONE, ACE_ACCESS_DENIED_ACE_TYPE}, - {(uid_t)-1, ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS| - ACE_SYNCHRONIZE, ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE} -}; - - -void -adjust_ace_pair_common(void *pair, size_t access_off, - size_t pairsize, mode_t mode) -{ - char *datap = (char *)pair; - uint32_t *amask0 = (uint32_t *)(uintptr_t)(datap + access_off); - uint32_t *amask1 = (uint32_t *)(uintptr_t)(datap + pairsize + - access_off); - if (mode & S_IROTH) - *amask1 |= ACE_READ_DATA; - else - *amask0 |= ACE_READ_DATA; - if (mode & S_IWOTH) - *amask1 |= ACE_WRITE_DATA|ACE_APPEND_DATA; - else - *amask0 |= ACE_WRITE_DATA|ACE_APPEND_DATA; - if (mode & S_IXOTH) - *amask1 |= ACE_EXECUTE; - else - *amask0 |= ACE_EXECUTE; -} - -void -adjust_ace_pair(ace_t *pair, mode_t mode) -{ - adjust_ace_pair_common(pair, offsetof(ace_t, a_access_mask), - sizeof (ace_t), mode); -} - -static void -ace_allow_deny_helper(uint16_t type, boolean_t *allow, boolean_t *deny) -{ - if (type == ACE_ACCESS_ALLOWED_ACE_TYPE) - *allow = B_TRUE; - else if (type == ACE_ACCESS_DENIED_ACE_TYPE) - *deny = B_TRUE; -} - -/* - * ace_trivial: - * determine whether an ace_t acl is trivial - * - * Trivialness implies that the acl is composed of only - * owner, group, everyone entries. ACL can't - * have read_acl denied, and write_owner/write_acl/write_attributes - * can only be owner@ entry. - */ -int -ace_trivial_common(void *acep, int aclcnt, - uint64_t (*walk)(void *, uint64_t, int aclcnt, - uint16_t *, uint16_t *, uint32_t *)) -{ - boolean_t owner_allow = B_FALSE; - boolean_t group_allow = B_FALSE; - boolean_t everyone_allow = B_FALSE; - boolean_t owner_deny = B_FALSE; - boolean_t group_deny = B_FALSE; - boolean_t everyone_deny = B_FALSE; - uint16_t flags; - uint32_t mask; - uint16_t type; - uint64_t cookie = 0; - - while (cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask)) { - switch (flags & ACE_TYPE_FLAGS) { - case ACE_OWNER: - if (group_allow || group_deny || everyone_allow || - everyone_deny) - return (1); - ace_allow_deny_helper(type, &owner_allow, &owner_deny); - break; - case ACE_GROUP|ACE_IDENTIFIER_GROUP: - if (everyone_allow || everyone_deny && - (!owner_allow && !owner_deny)) - return (1); - ace_allow_deny_helper(type, &group_allow, &group_deny); - break; - - case ACE_EVERYONE: - if (!owner_allow && !owner_deny && - !group_allow && !group_deny) - return (1); - ace_allow_deny_helper(type, - &everyone_allow, &everyone_deny); - break; - default: - return (1); - - } - - if (flags & (ACE_FILE_INHERIT_ACE| - ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE| - ACE_INHERIT_ONLY_ACE)) - return (1); - - /* - * Special check for some special bits - * - * Don't allow anybody to deny reading basic - * attributes or a files ACL. - */ - if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) && - (type == ACE_ACCESS_DENIED_ACE_TYPE)) - return (1); - - /* - * Allow on owner@ to allow - * write_acl/write_owner/write_attributes - */ - if (type == ACE_ACCESS_ALLOWED_ACE_TYPE && - (!(flags & ACE_OWNER) && (mask & - (ACE_WRITE_OWNER|ACE_WRITE_ACL|ACE_WRITE_ATTRIBUTES)))) - return (1); - - } - - if (!owner_allow || !owner_deny || !group_allow || !group_deny || - !everyone_allow || !everyone_deny) - return (1); - - return (0); -} - -uint64_t -ace_walk(void *datap, uint64_t cookie, int aclcnt, uint16_t *flags, - uint16_t *type, uint32_t *mask) -{ - ace_t *acep = datap; - - if (cookie >= aclcnt) - return (0); - - *flags = acep[cookie].a_flags; - *type = acep[cookie].a_type; - *mask = acep[cookie++].a_access_mask; - - return (cookie); -} - -int -ace_trivial(ace_t *acep, int aclcnt) -{ - return (ace_trivial_common(acep, aclcnt, ace_walk)); -} - /* * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified. * v = Ptr to array/vector of objs @@ -1726,4 +1563,198 @@ out: return (error); #endif } -#endif /* _KERNEL */ +#endif /* !_KERNEL */ + +#define SET_ACE(acl, index, who, mask, type, flags) { \ + acl[0][index].a_who = (uint32_t)who; \ + acl[0][index].a_type = type; \ + acl[0][index].a_flags = flags; \ + acl[0][index++].a_access_mask = mask; \ +} + +void +acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1, + uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone) +{ + *deny1 = *deny2 = *allow0 = *group = 0; + + if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) + *deny1 |= ACE_READ_DATA; + if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) + *deny1 |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))) + *deny1 |= ACE_EXECUTE; + + if (!(mode & S_IRGRP) && (mode & S_IROTH)) + *deny2 = ACE_READ_DATA; + if (!(mode & S_IWGRP) && (mode & S_IWOTH)) + *deny2 |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (!(mode & S_IXGRP) && (mode & S_IXOTH)) + *deny2 |= ACE_EXECUTE; + + if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH))) + *allow0 |= ACE_READ_DATA; + if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH))) + *allow0 |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH))) + *allow0 |= ACE_EXECUTE; + + *owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL| + ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES| + ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE; + if (mode & S_IRUSR) + *owner |= ACE_READ_DATA; + if (mode & S_IWUSR) + *owner |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (mode & S_IXUSR) + *owner |= ACE_EXECUTE; + + *group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS| + ACE_SYNCHRONIZE; + if (mode & S_IRGRP) + *group |= ACE_READ_DATA; + if (mode & S_IWGRP) + *group |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (mode & S_IXGRP) + *group |= ACE_EXECUTE; + + *everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS| + ACE_SYNCHRONIZE; + if (mode & S_IROTH) + *everyone |= ACE_READ_DATA; + if (mode & S_IWOTH) + *everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA; + if (mode & S_IXOTH) + *everyone |= ACE_EXECUTE; +} + +int +acl_trivial_create(mode_t mode, ace_t **acl, int *count) +{ + uint32_t deny1, deny2; + uint32_t allow0; + uint32_t owner, group, everyone; + int index = 0; + int error; + + *count = 3; + acl_trivial_access_masks(mode, &allow0, &deny1, &deny2, &owner, &group, + &everyone); + + if (allow0) + (*count)++; + if (deny1) + (*count)++; + if (deny2) + (*count)++; + + if ((error = cacl_malloc((void **)acl, *count * sizeof (ace_t))) != 0) + return (error); + + if (allow0) { + SET_ACE(acl, index, -1, allow0, ACE_ACCESS_ALLOWED_ACE_TYPE, + ACE_OWNER); + } + if (deny1) { + SET_ACE(acl, index, -1, deny1, ACE_ACCESS_DENIED_ACE_TYPE, + ACE_OWNER); + } + if (deny2) { + SET_ACE(acl, index, -1, deny2, ACE_ACCESS_DENIED_ACE_TYPE, + ACE_GROUP|ACE_IDENTIFIER_GROUP); + } + + SET_ACE(acl, index, -1, owner, ACE_ACCESS_ALLOWED_ACE_TYPE, ACE_OWNER); + SET_ACE(acl, index, -1, group, ACE_ACCESS_ALLOWED_ACE_TYPE, + ACE_IDENTIFIER_GROUP|ACE_GROUP); + SET_ACE(acl, index, -1, everyone, ACE_ACCESS_ALLOWED_ACE_TYPE, + ACE_EVERYONE); + + return (0); +} + +/* + * ace_trivial: + * determine whether an ace_t acl is trivial + * + * Trivialness implies that the acl is composed of only + * owner, group, everyone entries. ACL can't + * have read_acl denied, and write_owner/write_acl/write_attributes + * can only be owner@ entry. + */ +int +ace_trivial_common(void *acep, int aclcnt, + uint64_t (*walk)(void *, uint64_t, int aclcnt, + uint16_t *, uint16_t *, uint32_t *)) +{ + uint16_t flags; + uint32_t mask; + uint16_t type; + uint64_t cookie = 0; + + while (cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask)) { + switch (flags & ACE_TYPE_FLAGS) { + case ACE_OWNER: + case ACE_GROUP|ACE_IDENTIFIER_GROUP: + case ACE_EVERYONE: + break; + default: + return (1); + + } + + if (flags & (ACE_FILE_INHERIT_ACE| + ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE| + ACE_INHERIT_ONLY_ACE)) + return (1); + + /* + * Special check for some special bits + * + * Don't allow anybody to deny reading basic + * attributes or a files ACL. + */ + if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) && + (type == ACE_ACCESS_DENIED_ACE_TYPE)) + return (1); + + /* + * Delete permissions are never set by default + */ + if (mask & (ACE_DELETE|ACE_DELETE_CHILD)) + return (1); + /* + * only allow owner@ to have + * write_acl/write_owner/write_attributes/write_xattr/ + */ + if (type == ACE_ACCESS_ALLOWED_ACE_TYPE && + (!(flags & ACE_OWNER) && (mask & + (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES| + ACE_WRITE_NAMED_ATTRS)))) + return (1); + + } + return (0); +} + +uint64_t +ace_walk(void *datap, uint64_t cookie, int aclcnt, uint16_t *flags, + uint16_t *type, uint32_t *mask) +{ + ace_t *acep = datap; + + if (cookie >= aclcnt) + return (0); + + *flags = acep[cookie].a_flags; + *type = acep[cookie].a_type; + *mask = acep[cookie++].a_access_mask; + + return (cookie); +} + +int +ace_trivial(ace_t *acep, int aclcnt) +{ + return (ace_trivial_common(acep, aclcnt, ace_walk)); +} diff --git a/sys/cddl/contrib/opensolaris/common/acl/acl_common.h b/sys/cddl/contrib/opensolaris/common/acl/acl_common.h index 85ba0bd..20be9a0 100644 --- a/sys/cddl/contrib/opensolaris/common/acl/acl_common.h +++ b/sys/cddl/contrib/opensolaris/common/acl/acl_common.h @@ -19,16 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _ACL_COMMON_H #define _ACL_COMMON_H -#pragma ident "%Z%%M% %I% %E% SMI" - - #include <sys/types.h> #include <sys/acl.h> #include <sys/stat.h> @@ -51,10 +47,12 @@ extern acl_t *acl_alloc(acl_type_t); extern void acl_free(acl_t *aclp); extern int acl_translate(acl_t *aclp, int target_flavor, int isdir, uid_t owner, gid_t group); +#endif /* !_KERNEL */ void ksort(caddr_t v, int n, int s, int (*f)()); int cmp2acls(void *a, void *b); - -#endif /* _KERNEL */ +int acl_trivial_create(mode_t mode, ace_t **acl, int *count); +void acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1, + uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone); #ifdef __cplusplus } diff --git a/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S index 6851086..6d0a1f8 100644 --- a/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S +++ b/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S @@ -20,8 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. */ .file "atomic.s" @@ -30,14 +29,10 @@ #include <sys/asm_linkage.h> ENTRY(atomic_add_64_nv) - movq (%rdi), %rax -1: - movq %rsi, %rcx - addq %rax, %rcx + mov %rsi, %rax // %rax = delta addend lock - cmpxchgq %rcx, (%rdi) - jne 1b - movq %rcx, %rax + xaddq %rsi, (%rdi) // %rsi = old value, (%rdi) = sum + addq %rsi, %rax // new value = original value + delta ret SET_SIZE(atomic_add_64_nv) @@ -53,6 +48,13 @@ ret SET_SIZE(atomic_or_8_nv) + ENTRY(atomic_cas_32) + movl %esi, %eax + lock + cmpxchgl %edx, (%rdi) + ret + SET_SIZE(atomic_cas_32) + ENTRY(atomic_cas_64) movq %rsi, %rax lock diff --git a/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S index 57f7d0a..c9dbd79 100644 --- a/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S +++ b/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -102,14 +102,14 @@ ret SET_SIZE(atomic_or_8_nv) - ENTRY(atomic_cas_ptr) + ENTRY(atomic_cas_32) movl 4(%esp), %edx movl 8(%esp), %eax movl 12(%esp), %ecx lock cmpxchgl %ecx, (%edx) ret - SET_SIZE(atomic_cas_ptr) + SET_SIZE(atomic_cas_32) ENTRY(atomic_cas_64) pushl %ebx diff --git a/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S index 1b7c580..3324fe3 100644 --- a/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S +++ b/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S @@ -31,6 +31,17 @@ .text /* + * uint32_t atomic_cas_32(volatile uint32_t *p, uint32_t cmp, uint32_t v) + */ +ENTRY(atomic_cas_32, 3) + mov ar.ccv = r33 + ;; + cmpxchg4.acq r8 = [r32], r34, ar.ccv + ;; + br.ret.sptk rp +END(atomic_cas_64) + +/* * uint64_t atomic_cas_64(volatile uint64_t *p, uint64_t cmp, uint64_t v) */ ENTRY(atomic_cas_64, 3) diff --git a/sys/cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S index 0004f44..0ab5d19 100644 --- a/sys/cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S +++ b/sys/cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S @@ -36,6 +36,19 @@ ENTRY(atomic_add_64_nv) mr %r3,%r5 blr +ENTRY(atomic_cas_32) + 1: lwarx %r6,0,%r3 + cmplw %r6,%r4 + bne 2f + stwcx. %r5,0,%r3 + bne- 1b + b 3f + + 2: stwcx. %r6,0,%r3 /* clear reservation */ + + 3: mr %r3,%r6 + blr + ENTRY(atomic_cas_64) 1: ldarx %r6,0,%r3 cmpld %r6,%r4 diff --git a/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S index 5651ae0..3a498fe 100644 --- a/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S +++ b/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S @@ -77,7 +77,6 @@ add_64: ENTRY(atomic_or_8) ALTENTRY(atomic_or_8_nv) ALTENTRY(atomic_or_uchar) - ALTENTRY(atomic_or_uchar_nv) and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left @@ -97,7 +96,6 @@ add_64: and %o5, %o3, %o5 retl srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_or_uchar_nv) SET_SIZE(atomic_or_uchar) SET_SIZE(atomic_or_8_nv) SET_SIZE(atomic_or_8) diff --git a/sys/cddl/contrib/opensolaris/common/avl/avl.c b/sys/cddl/contrib/opensolaris/common/avl/avl.c index 01aa3cb..6106ef1 100644 --- a/sys/cddl/contrib/opensolaris/common/avl/avl.c +++ b/sys/cddl/contrib/opensolaris/common/avl/avl.c @@ -19,13 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - - /* * AVL - generic AVL tree implementation for kernel use * @@ -243,7 +240,7 @@ avl_nearest(avl_tree_t *tree, avl_index_t where, int direction) * "void *" of the found tree node */ void * -avl_find(avl_tree_t *tree, void *value, avl_index_t *where) +avl_find(avl_tree_t *tree, const void *value, avl_index_t *where) { avl_node_t *node; avl_node_t *prev = NULL; diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c index eb824c7..53ed5f2 100644 --- a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c +++ b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/debug.h> #include <sys/nvpair.h> #include <sys/nvpair_impl.h> @@ -39,6 +36,7 @@ #include <stdarg.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #endif #ifndef offsetof @@ -254,6 +252,12 @@ nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv) nvl->nvl_pad = 0; } +uint_t +nvlist_nvflag(nvlist_t *nvl) +{ + return (nvl->nvl_nvflag); +} + /* * nvlist_alloc - Allocate nvlist. */ @@ -687,6 +691,18 @@ nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type) return (ENOENT); } +int +nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp) +{ + if (nvl == NULL || nvp == NULL) + return (EINVAL); + + nvp_buf_unlink(nvl, nvp); + nvpair_free(nvp); + nvp_buf_free(nvl, nvp); + return (0); +} + /* * This function calculates the size of an nvpair value. * @@ -1157,6 +1173,42 @@ nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *nvp) return (curr != NULL ? &curr->nvi_nvp : NULL); } +nvpair_t * +nvlist_prev_nvpair(nvlist_t *nvl, nvpair_t *nvp) +{ + nvpriv_t *priv; + i_nvp_t *curr; + + if (nvl == NULL || + (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) + return (NULL); + + curr = NVPAIR2I_NVP(nvp); + + if (nvp == NULL) + curr = priv->nvp_last; + else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp)) + curr = curr->nvi_prev; + else + curr = NULL; + + priv->nvp_curr = curr; + + return (curr != NULL ? &curr->nvi_nvp : NULL); +} + +boolean_t +nvlist_empty(nvlist_t *nvl) +{ + nvpriv_t *priv; + + if (nvl == NULL || + (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL) + return (B_TRUE); + + return (priv->nvp_list == NULL); +} + char * nvpair_name(nvpair_t *nvp) { diff --git a/sys/cddl/contrib/opensolaris/common/unicode/u8_textprep.c b/sys/cddl/contrib/opensolaris/common/unicode/u8_textprep.c index 73cf74a..07186b3 100644 --- a/sys/cddl/contrib/opensolaris/common/unicode/u8_textprep.c +++ b/sys/cddl/contrib/opensolaris/common/unicode/u8_textprep.c @@ -42,6 +42,7 @@ #include <sys/systm.h> #include <sys/debug.h> #include <sys/kmem.h> +#include <sys/sunddi.h> #else #include <strings.h> #endif /* _KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.c index 74517a3..5df6876 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.c @@ -19,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file is intended for functions that ought to be common between user * land (libzfs) and the kernel. When many common routines need to be shared @@ -33,11 +30,14 @@ #if defined(_KERNEL) #include <sys/systm.h> +#else +#include <string.h> #endif #include <sys/types.h> #include <sys/fs/zfs.h> #include <sys/nvpair.h> +#include "zfs_comutil.h" /* * Are there allocatable vdevs? @@ -63,3 +63,139 @@ zfs_allocatable_devs(nvlist_t *nv) } return (B_FALSE); } + +void +zpool_get_rewind_policy(nvlist_t *nvl, zpool_rewind_policy_t *zrpp) +{ + nvlist_t *policy; + nvpair_t *elem; + char *nm; + + /* Defaults */ + zrpp->zrp_request = ZPOOL_NO_REWIND; + zrpp->zrp_maxmeta = 0; + zrpp->zrp_maxdata = UINT64_MAX; + zrpp->zrp_txg = UINT64_MAX; + + if (nvl == NULL) + return; + + elem = NULL; + while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { + nm = nvpair_name(elem); + if (strcmp(nm, ZPOOL_REWIND_POLICY) == 0) { + if (nvpair_value_nvlist(elem, &policy) == 0) + zpool_get_rewind_policy(policy, zrpp); + return; + } else if (strcmp(nm, ZPOOL_REWIND_REQUEST) == 0) { + if (nvpair_value_uint32(elem, &zrpp->zrp_request) == 0) + if (zrpp->zrp_request & ~ZPOOL_REWIND_POLICIES) + zrpp->zrp_request = ZPOOL_NO_REWIND; + } else if (strcmp(nm, ZPOOL_REWIND_REQUEST_TXG) == 0) { + (void) nvpair_value_uint64(elem, &zrpp->zrp_txg); + } else if (strcmp(nm, ZPOOL_REWIND_META_THRESH) == 0) { + (void) nvpair_value_uint64(elem, &zrpp->zrp_maxmeta); + } else if (strcmp(nm, ZPOOL_REWIND_DATA_THRESH) == 0) { + (void) nvpair_value_uint64(elem, &zrpp->zrp_maxdata); + } + } + if (zrpp->zrp_request == 0) + zrpp->zrp_request = ZPOOL_NO_REWIND; +} + +typedef struct zfs_version_spa_map { + int version_zpl; + int version_spa; +} zfs_version_spa_map_t; + +/* + * Keep this table in monotonically increasing version number order. + */ +static zfs_version_spa_map_t zfs_version_table[] = { + {ZPL_VERSION_INITIAL, SPA_VERSION_INITIAL}, + {ZPL_VERSION_DIRENT_TYPE, SPA_VERSION_INITIAL}, + {ZPL_VERSION_FUID, SPA_VERSION_FUID}, + {ZPL_VERSION_USERSPACE, SPA_VERSION_USERSPACE}, + {ZPL_VERSION_SA, SPA_VERSION_SA}, + {0, 0} +}; + +/* + * Return the max zpl version for a corresponding spa version + * -1 is returned if no mapping exists. + */ +int +zfs_zpl_version_map(int spa_version) +{ + int i; + int version = -1; + + for (i = 0; zfs_version_table[i].version_spa; i++) { + if (spa_version >= zfs_version_table[i].version_spa) + version = zfs_version_table[i].version_zpl; + } + + return (version); +} + +/* + * Return the min spa version for a corresponding spa version + * -1 is returned if no mapping exists. + */ +int +zfs_spa_version_map(int zpl_version) +{ + int i; + int version = -1; + + for (i = 0; zfs_version_table[i].version_zpl; i++) { + if (zfs_version_table[i].version_zpl >= zpl_version) + return (zfs_version_table[i].version_spa); + } + + return (version); +} + +const char *zfs_history_event_names[LOG_END] = { + "invalid event", + "pool create", + "vdev add", + "pool remove", + "pool destroy", + "pool export", + "pool import", + "vdev attach", + "vdev replace", + "vdev detach", + "vdev online", + "vdev offline", + "vdev upgrade", + "pool clear", + "pool scrub", + "pool property set", + "create", + "clone", + "destroy", + "destroy_begin_sync", + "inherit", + "property set", + "quota set", + "permission update", + "permission remove", + "permission who remove", + "promote", + "receive", + "rename", + "reservation set", + "replay_inc_sync", + "replay_full_sync", + "rollback", + "snapshot", + "filesystem version upgrade", + "refquota set", + "refreservation set", + "pool scrub done", + "user hold", + "user release", + "pool split", +}; diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.h index f517044..61327f9 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.h +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.h @@ -19,15 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _ZFS_COMUTIL_H #define _ZFS_COMUTIL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/fs/zfs.h> #include <sys/types.h> @@ -35,7 +32,12 @@ extern "C" { #endif -extern boolean_t zfs_allocatable_devs(nvlist_t *nv); +extern boolean_t zfs_allocatable_devs(nvlist_t *); +extern void zpool_get_rewind_policy(nvlist_t *, zpool_rewind_policy_t *); + +extern int zfs_zpl_version_map(int spa_version); +extern int zfs_spa_version_map(int zpl_version); +extern const char *zfs_history_event_names[LOG_END]; #ifdef __cplusplus } diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c index 2964cae..1868103 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.c @@ -19,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. */ #if defined(_KERNEL) @@ -61,12 +61,15 @@ zfs_deleg_perm_tab_t zfs_deleg_perm_tab[] = { {ZFS_DELEG_PERM_ROLLBACK, ZFS_DELEG_NOTE_ROLLBACK }, {ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT }, {ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE }, - {ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_NONE }, + {ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_SEND }, {ZFS_DELEG_PERM_USERPROP, ZFS_DELEG_NOTE_USERPROP }, {ZFS_DELEG_PERM_USERQUOTA, ZFS_DELEG_NOTE_USERQUOTA }, {ZFS_DELEG_PERM_GROUPQUOTA, ZFS_DELEG_NOTE_GROUPQUOTA }, {ZFS_DELEG_PERM_USERUSED, ZFS_DELEG_NOTE_USERUSED }, {ZFS_DELEG_PERM_GROUPUSED, ZFS_DELEG_NOTE_GROUPUSED }, + {ZFS_DELEG_PERM_HOLD, ZFS_DELEG_NOTE_HOLD }, + {ZFS_DELEG_PERM_RELEASE, ZFS_DELEG_NOTE_RELEASE }, + {ZFS_DELEG_PERM_DIFF, ZFS_DELEG_NOTE_DIFF}, {NULL, ZFS_DELEG_NOTE_NONE } }; diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.h index cdbbd83..9997dff 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.h +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_deleg.h @@ -19,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. */ #ifndef _ZFS_DELEG_H @@ -52,6 +52,7 @@ typedef enum { ZFS_DELEG_NOTE_CLONE, ZFS_DELEG_NOTE_PROMOTE, ZFS_DELEG_NOTE_RENAME, + ZFS_DELEG_NOTE_SEND, ZFS_DELEG_NOTE_RECEIVE, ZFS_DELEG_NOTE_ALLOW, ZFS_DELEG_NOTE_USERPROP, @@ -61,6 +62,9 @@ typedef enum { ZFS_DELEG_NOTE_GROUPQUOTA, ZFS_DELEG_NOTE_USERUSED, ZFS_DELEG_NOTE_GROUPUSED, + ZFS_DELEG_NOTE_HOLD, + ZFS_DELEG_NOTE_RELEASE, + ZFS_DELEG_NOTE_DIFF, ZFS_DELEG_NOTE_NONE } zfs_deleg_note_t; diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_fletcher.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_fletcher.c new file mode 100644 index 0000000..fa43ce6 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_fletcher.c @@ -0,0 +1,246 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Fletcher Checksums + * ------------------ + * + * ZFS's 2nd and 4th order Fletcher checksums are defined by the following + * recurrence relations: + * + * a = a + f + * i i-1 i-1 + * + * b = b + a + * i i-1 i + * + * c = c + b (fletcher-4 only) + * i i-1 i + * + * d = d + c (fletcher-4 only) + * i i-1 i + * + * Where + * a_0 = b_0 = c_0 = d_0 = 0 + * and + * f_0 .. f_(n-1) are the input data. + * + * Using standard techniques, these translate into the following series: + * + * __n_ __n_ + * \ | \ | + * a = > f b = > i * f + * n /___| n - i n /___| n - i + * i = 1 i = 1 + * + * + * __n_ __n_ + * \ | i*(i+1) \ | i*(i+1)*(i+2) + * c = > ------- f d = > ------------- f + * n /___| 2 n - i n /___| 6 n - i + * i = 1 i = 1 + * + * For fletcher-2, the f_is are 64-bit, and [ab]_i are 64-bit accumulators. + * Since the additions are done mod (2^64), errors in the high bits may not + * be noticed. For this reason, fletcher-2 is deprecated. + * + * For fletcher-4, the f_is are 32-bit, and [abcd]_i are 64-bit accumulators. + * A conservative estimate of how big the buffer can get before we overflow + * can be estimated using f_i = 0xffffffff for all i: + * + * % bc + * f=2^32-1;d=0; for (i = 1; d<2^64; i++) { d += f*i*(i+1)*(i+2)/6 }; (i-1)*4 + * 2264 + * quit + * % + * + * So blocks of up to 2k will not overflow. Our largest block size is + * 128k, which has 32k 4-byte words, so we can compute the largest possible + * accumulators, then divide by 2^64 to figure the max amount of overflow: + * + * % bc + * a=b=c=d=0; f=2^32-1; for (i=1; i<=32*1024; i++) { a+=f; b+=a; c+=b; d+=c } + * a/2^64;b/2^64;c/2^64;d/2^64 + * 0 + * 0 + * 1365 + * 11186858 + * quit + * % + * + * So a and b cannot overflow. To make sure each bit of input has some + * effect on the contents of c and d, we can look at what the factors of + * the coefficients in the equations for c_n and d_n are. The number of 2s + * in the factors determines the lowest set bit in the multiplier. Running + * through the cases for n*(n+1)/2 reveals that the highest power of 2 is + * 2^14, and for n*(n+1)*(n+2)/6 it is 2^15. So while some data may overflow + * the 64-bit accumulators, every bit of every f_i effects every accumulator, + * even for 128k blocks. + * + * If we wanted to make a stronger version of fletcher4 (fletcher4c?), + * we could do our calculations mod (2^32 - 1) by adding in the carries + * periodically, and store the number of carries in the top 32-bits. + * + * -------------------- + * Checksum Performance + * -------------------- + * + * There are two interesting components to checksum performance: cached and + * uncached performance. With cached data, fletcher-2 is about four times + * faster than fletcher-4. With uncached data, the performance difference is + * negligible, since the cost of a cache fill dominates the processing time. + * Even though fletcher-4 is slower than fletcher-2, it is still a pretty + * efficient pass over the data. + * + * In normal operation, the data which is being checksummed is in a buffer + * which has been filled either by: + * + * 1. a compression step, which will be mostly cached, or + * 2. a bcopy() or copyin(), which will be uncached (because the + * copy is cache-bypassing). + * + * For both cached and uncached data, both fletcher checksums are much faster + * than sha-256, and slower than 'off', which doesn't touch the data at all. + */ + +#include <sys/types.h> +#include <sys/sysmacros.h> +#include <sys/byteorder.h> +#include <sys/zio.h> +#include <sys/spa.h> + +void +fletcher_2_native(const void *buf, uint64_t size, zio_cksum_t *zcp) +{ + const uint64_t *ip = buf; + const uint64_t *ipend = ip + (size / sizeof (uint64_t)); + uint64_t a0, b0, a1, b1; + + for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) { + a0 += ip[0]; + a1 += ip[1]; + b0 += a0; + b1 += a1; + } + + ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1); +} + +void +fletcher_2_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp) +{ + const uint64_t *ip = buf; + const uint64_t *ipend = ip + (size / sizeof (uint64_t)); + uint64_t a0, b0, a1, b1; + + for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) { + a0 += BSWAP_64(ip[0]); + a1 += BSWAP_64(ip[1]); + b0 += a0; + b1 += a1; + } + + ZIO_SET_CHECKSUM(zcp, a0, a1, b0, b1); +} + +void +fletcher_4_native(const void *buf, uint64_t size, zio_cksum_t *zcp) +{ + const uint32_t *ip = buf; + const uint32_t *ipend = ip + (size / sizeof (uint32_t)); + uint64_t a, b, c, d; + + for (a = b = c = d = 0; ip < ipend; ip++) { + a += ip[0]; + b += a; + c += b; + d += c; + } + + ZIO_SET_CHECKSUM(zcp, a, b, c, d); +} + +void +fletcher_4_byteswap(const void *buf, uint64_t size, zio_cksum_t *zcp) +{ + const uint32_t *ip = buf; + const uint32_t *ipend = ip + (size / sizeof (uint32_t)); + uint64_t a, b, c, d; + + for (a = b = c = d = 0; ip < ipend; ip++) { + a += BSWAP_32(ip[0]); + b += a; + c += b; + d += c; + } + + ZIO_SET_CHECKSUM(zcp, a, b, c, d); +} + +void +fletcher_4_incremental_native(const void *buf, uint64_t size, + zio_cksum_t *zcp) +{ + const uint32_t *ip = buf; + const uint32_t *ipend = ip + (size / sizeof (uint32_t)); + uint64_t a, b, c, d; + + a = zcp->zc_word[0]; + b = zcp->zc_word[1]; + c = zcp->zc_word[2]; + d = zcp->zc_word[3]; + + for (; ip < ipend; ip++) { + a += ip[0]; + b += a; + c += b; + d += c; + } + + ZIO_SET_CHECKSUM(zcp, a, b, c, d); +} + +void +fletcher_4_incremental_byteswap(const void *buf, uint64_t size, + zio_cksum_t *zcp) +{ + const uint32_t *ip = buf; + const uint32_t *ipend = ip + (size / sizeof (uint32_t)); + uint64_t a, b, c, d; + + a = zcp->zc_word[0]; + b = zcp->zc_word[1]; + c = zcp->zc_word[2]; + d = zcp->zc_word[3]; + + for (; ip < ipend; ip++) { + a += BSWAP_32(ip[0]); + b += a; + c += b; + d += c; + } + + ZIO_SET_CHECKSUM(zcp, a, b, c, d); +} diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_fletcher.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_fletcher.h new file mode 100644 index 0000000..b49df0c --- /dev/null +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_fletcher.h @@ -0,0 +1,53 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _ZFS_FLETCHER_H +#define _ZFS_FLETCHER_H + +#include <sys/types.h> +#include <sys/spa.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * fletcher checksum functions + */ + +void fletcher_2_native(const void *, uint64_t, zio_cksum_t *); +void fletcher_2_byteswap(const void *, uint64_t, zio_cksum_t *); +void fletcher_4_native(const void *, uint64_t, zio_cksum_t *); +void fletcher_4_byteswap(const void *, uint64_t, zio_cksum_t *); +void fletcher_4_incremental_native(const void *, uint64_t, + zio_cksum_t *); +void fletcher_4_incremental_byteswap(const void *, uint64_t, + zio_cksum_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZFS_FLETCHER_H */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c new file mode 100644 index 0000000..d830fd9 --- /dev/null +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c @@ -0,0 +1,349 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2010 Martin Matuska <mm@FreeBSD.org>. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/cred.h> +#include <sys/dmu.h> +#include <sys/zio.h> +#include <sys/nvpair.h> +#include <sys/dsl_deleg.h> +#include <sys/zfs_ioctl.h> +#include "zfs_ioctl_compat.h" + +/* + * FreeBSD zfs_cmd compatibility with v15 and older binaries + * appropriately remap/extend the zfs_cmd_t structure + */ +void +zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag) +{ + zfs_cmd_v15_t *zc_c; + + if (cflag == ZFS_CMD_COMPAT_V15) { + zc_c = (void *)addr; + + /* zc */ + strlcpy(zc->zc_name,zc_c->zc_name,MAXPATHLEN); + strlcpy(zc->zc_value,zc_c->zc_value,MAXPATHLEN); + strlcpy(zc->zc_string,zc_c->zc_string,MAXPATHLEN); + zc->zc_guid = zc_c->zc_guid; + zc->zc_nvlist_conf = zc_c->zc_nvlist_conf; + zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size; + zc->zc_nvlist_src = zc_c->zc_nvlist_src; + zc->zc_nvlist_src_size = zc_c->zc_nvlist_src_size; + zc->zc_nvlist_dst = zc_c->zc_nvlist_dst; + zc->zc_nvlist_dst_size = zc_c->zc_nvlist_dst_size; + zc->zc_cookie = zc_c->zc_cookie; + zc->zc_objset_type = zc_c->zc_objset_type; + zc->zc_perm_action = zc_c->zc_perm_action; + zc->zc_history = zc_c->zc_history; + zc->zc_history_len = zc_c->zc_history_len; + zc->zc_history_offset = zc_c->zc_history_offset; + zc->zc_obj = zc_c->zc_obj; + zc->zc_share = zc_c->zc_share; + zc->zc_jailid = zc_c->zc_jailid; + zc->zc_objset_stats = zc_c->zc_objset_stats; + zc->zc_begin_record = zc_c->zc_begin_record; + + /* zc->zc_inject_record */ + zc->zc_inject_record.zi_objset = + zc_c->zc_inject_record.zi_objset; + zc->zc_inject_record.zi_object = + zc_c->zc_inject_record.zi_object; + zc->zc_inject_record.zi_start = + zc_c->zc_inject_record.zi_start; + zc->zc_inject_record.zi_end = + zc_c->zc_inject_record.zi_end; + zc->zc_inject_record.zi_guid = + zc_c->zc_inject_record.zi_guid; + zc->zc_inject_record.zi_level = + zc_c->zc_inject_record.zi_level; + zc->zc_inject_record.zi_error = + zc_c->zc_inject_record.zi_error; + zc->zc_inject_record.zi_type = + zc_c->zc_inject_record.zi_type; + zc->zc_inject_record.zi_freq = + zc_c->zc_inject_record.zi_freq; + zc->zc_inject_record.zi_failfast = + zc_c->zc_inject_record.zi_failfast; + } +} + +void +zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag) +{ + zfs_cmd_v15_t *zc_c; + + switch (cflag) { + case ZFS_CMD_COMPAT_V15: + zc_c = (void *)addr; + + /* zc */ + strlcpy(zc_c->zc_name,zc->zc_name,MAXPATHLEN); + strlcpy(zc_c->zc_value,zc->zc_value,MAXPATHLEN); + strlcpy(zc_c->zc_string,zc->zc_string,MAXPATHLEN); + zc_c->zc_guid = zc->zc_guid; + zc_c->zc_nvlist_conf = zc->zc_nvlist_conf; + zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size; + zc_c->zc_nvlist_src = zc->zc_nvlist_src; + zc_c->zc_nvlist_src_size = zc->zc_nvlist_src_size; + zc_c->zc_nvlist_dst = zc->zc_nvlist_dst; + zc_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size; + zc_c->zc_cookie = zc->zc_cookie; + zc_c->zc_objset_type = zc->zc_objset_type; + zc_c->zc_perm_action = zc->zc_perm_action; + zc_c->zc_history = zc->zc_history; + zc_c->zc_history_len = zc->zc_history_len; + zc_c->zc_history_offset = zc->zc_history_offset; + zc_c->zc_obj = zc->zc_obj; + zc_c->zc_share = zc->zc_share; + zc_c->zc_jailid = zc->zc_jailid; + zc_c->zc_objset_stats = zc->zc_objset_stats; + zc_c->zc_begin_record = zc->zc_begin_record; + + /* zc_inject_record */ + zc_c->zc_inject_record.zi_objset = + zc->zc_inject_record.zi_objset; + zc_c->zc_inject_record.zi_object = + zc->zc_inject_record.zi_object; + zc_c->zc_inject_record.zi_start = + zc->zc_inject_record.zi_start; + zc_c->zc_inject_record.zi_end = + zc->zc_inject_record.zi_end; + zc_c->zc_inject_record.zi_guid = + zc->zc_inject_record.zi_guid; + zc_c->zc_inject_record.zi_level = + zc->zc_inject_record.zi_level; + zc_c->zc_inject_record.zi_error = + zc->zc_inject_record.zi_error; + zc_c->zc_inject_record.zi_type = + zc->zc_inject_record.zi_type; + zc_c->zc_inject_record.zi_freq = + zc->zc_inject_record.zi_freq; + zc_c->zc_inject_record.zi_failfast = + zc->zc_inject_record.zi_failfast; + + break; + } +} + +static int +zfs_ioctl_compat_write_nvlist_dst(zfs_cmd_t *zc, nvlist_t *nvl, size_t nvsize) +{ + char *packed = (void *)(uintptr_t)zc->zc_nvlist_dst; + int err; + + err = nvlist_pack(nvl, &packed, &nvsize, + NV_ENCODE_NATIVE, 0); + if (err == 0) + zc->zc_nvlist_dst_size = nvsize; + + return (err); +} + +static void +zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl) +{ + nvlist_t **child; + nvlist_t *nvroot = NULL; + vdev_stat_t *vs; + uint_t c, children, nelem; + + if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN, + &child, &children) == 0) { + for (c = 0; c < children; c++) { + zfs_ioctl_compat_fix_stats_nvlist(child[c]); + } + } + + if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE, + &nvroot) == 0) + zfs_ioctl_compat_fix_stats_nvlist(nvroot); +#ifdef _KERNEL + if ((nvlist_lookup_uint64_array(nvl, ZPOOL_CONFIG_VDEV_STATS, +#else + if ((nvlist_lookup_uint64_array(nvl, "stats", +#endif + + (uint64_t **)&vs, &nelem) == 0)) { + nvlist_add_uint64_array(nvl, +#ifdef _KERNEL + "stats", +#else + ZPOOL_CONFIG_VDEV_STATS, +#endif + (uint64_t *)vs, nelem); +#ifdef _KERNEL + nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS, +#else + nvlist_remove(nvl, "stats", +#endif + DATA_TYPE_UINT64_ARRAY); + } +} + +static void +zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int cflag) +{ + nvlist_t *nv, *nvp = NULL; + nvpair_t *elem; + size_t nvsize; + char *packed; + + if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst, + zc->zc_nvlist_dst_size, &nv, 0) != 0) + return; + + if (cflag == 5) { /* ZFS_IOC_POOL_STATS */ + elem = NULL; + while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) { + if (nvpair_value_nvlist(elem, &nvp) == 0) + zfs_ioctl_compat_fix_stats_nvlist(nvp); + } + elem = NULL; + } else + zfs_ioctl_compat_fix_stats_nvlist(nv); + + VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_NATIVE) == 0); + zfs_ioctl_compat_write_nvlist_dst(zc, nv, nvsize); + + nvlist_free(nv); +} + +static void +zfs_ioctl_compat_pool_get_props(zfs_cmd_t *zc) +{ + nvlist_t *nv, *nva = NULL; + size_t nvsize; + + if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst, + zc->zc_nvlist_dst_size, &nv, 0) != 0) + return; + +#ifdef _KERNEL + if (nvlist_lookup_nvlist(nv, "allocated", &nva) == 0) { + nvlist_add_nvlist(nv, "used", nva); + nvlist_remove(nv, "allocated", DATA_TYPE_NVLIST); + } + + if (nvlist_lookup_nvlist(nv, "free", &nva) == 0) { + nvlist_add_nvlist(nv, "available", nva); + nvlist_remove(nv, "free", DATA_TYPE_NVLIST); + } +#else + if (nvlist_lookup_nvlist(nv, "used", &nva) == 0) { + nvlist_add_nvlist(nv, "allocated", nva); + nvlist_remove(nv, "used", DATA_TYPE_NVLIST); + } + + if (nvlist_lookup_nvlist(nv, "available", &nva) == 0) { + nvlist_add_nvlist(nv, "free", nva); + nvlist_remove(nv, "available", DATA_TYPE_NVLIST); + } +#endif + + VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_NATIVE) == 0); + zfs_ioctl_compat_write_nvlist_dst(zc, nv, nvsize); + + nvlist_free(nv); +} + +#ifndef _KERNEL +int +zcmd_ioctl_compat(int fd, unsigned long cmd, zfs_cmd_t *zc, const int cflag) +{ + int nc, ret; + void *zc_c; + unsigned long ncmd; + + if (cflag == ZFS_CMD_COMPAT_NONE) { + ret = ioctl(fd, cmd, zc); + return (ret); + } + + if (cflag == ZFS_CMD_COMPAT_V15) { + nc = zfs_ioctl_v28_to_v15[ZFS_IOC(cmd)]; + zc_c = malloc(sizeof(zfs_cmd_v15_t)); + ncmd = _IOWR('Z', nc, struct zfs_cmd_v15); + } else + return (EINVAL); + + if (ZFS_IOC(ncmd) == ZFS_IOC_COMPAT_FAIL) + return (ENOTSUP); + + zfs_cmd_compat_put(zc, (caddr_t)zc_c, cflag); + ret = ioctl(fd, ncmd, zc_c); + if (cflag == ZFS_CMD_COMPAT_V15 && + nc == 2 /* ZFS_IOC_POOL_IMPORT */) + ret = ioctl(fd, _IOWR('Z', 4 /* ZFS_IOC_POOL_CONFIGS */, + struct zfs_cmd_v15), zc_c); + zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag); + free(zc_c); + + switch (nc) { + case 2: /* ZFS_IOC_POOL_IMPORT */ + case 4: /* ZFS_IOC_POOL_CONFIGS */ + case 5: /* ZFS_IOC_POOL_STATS */ + case 6: /* ZFS_IOC_POOL_TRYIMPORT */ + zfs_ioctl_compat_fix_stats(zc, nc); + break; + case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */ + zfs_ioctl_compat_pool_get_props(zc); + break; + } + + return (ret); +} +#else /* _KERNEL */ +void +zfs_ioctl_compat_pre(zfs_cmd_t *zc, int *vec, const int cflag) +{ + if (cflag == ZFS_CMD_COMPAT_V15) + switch (*vec) { + + case 7: /* ZFS_IOC_POOL_SCRUB (v15) */ + zc->zc_cookie = POOL_SCAN_SCRUB; + break; + } +} + +void +zfs_ioctl_compat_post(zfs_cmd_t *zc, int vec, const int cflag) +{ + if (cflag == ZFS_CMD_COMPAT_V15) { + switch (vec) { + case 4: /* ZFS_IOC_POOL_CONFIGS */ + case 5: /* ZFS_IOC_POOL_STATS */ + case 6: /* ZFS_IOC_POOL_TRYIMPORT */ + zfs_ioctl_compat_fix_stats(zc, vec); + break; + case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */ + zfs_ioctl_compat_pool_get_props(zc); + break; + } + } +} +#endif /* KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h new file mode 100644 index 0000000..03d648c --- /dev/null +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h @@ -0,0 +1,223 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2010 Martin Matuska <mm@FreeBSD.org>. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_ZFS_IOCTL_COMPAT_H +#define _SYS_ZFS_IOCTL_COMPAT_H + +#include <sys/cred.h> +#include <sys/dmu.h> +#include <sys/zio.h> +#include <sys/dsl_deleg.h> +#include <sys/zfs_ioctl.h> + +#ifdef _KERNEL +#include <sys/nvpair.h> +#endif /* _KERNEL */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZFS_CMD_COMPAT_NONE 0 +#define ZFS_CMD_COMPAT_V15 1 + +#define ZFS_IOC_COMPAT_PASS 254 +#define ZFS_IOC_COMPAT_FAIL 255 + +typedef struct zinject_record_v15 { + uint64_t zi_objset; + uint64_t zi_object; + uint64_t zi_start; + uint64_t zi_end; + uint64_t zi_guid; + uint32_t zi_level; + uint32_t zi_error; + uint64_t zi_type; + uint32_t zi_freq; + uint32_t zi_failfast; +} zinject_record_v15_t; + +typedef struct zfs_cmd_v15 { + char zc_name[MAXPATHLEN]; + char zc_value[MAXPATHLEN]; + char zc_string[MAXNAMELEN]; + uint64_t zc_guid; + uint64_t zc_nvlist_conf; /* really (char *) */ + uint64_t zc_nvlist_conf_size; + uint64_t zc_nvlist_src; /* really (char *) */ + uint64_t zc_nvlist_src_size; + uint64_t zc_nvlist_dst; /* really (char *) */ + uint64_t zc_nvlist_dst_size; + uint64_t zc_cookie; + uint64_t zc_objset_type; + uint64_t zc_perm_action; + uint64_t zc_history; /* really (char *) */ + uint64_t zc_history_len; + uint64_t zc_history_offset; + uint64_t zc_obj; + zfs_share_t zc_share; + uint64_t zc_jailid; + dmu_objset_stats_t zc_objset_stats; + struct drr_begin zc_begin_record; + zinject_record_v15_t zc_inject_record; +} zfs_cmd_v15_t; + +#ifdef _KERNEL +unsigned static long zfs_ioctl_v15_to_v28[] = { + 0, /* 0 ZFS_IOC_POOL_CREATE */ + 1, /* 1 ZFS_IOC_POOL_DESTROY */ + 2, /* 2 ZFS_IOC_POOL_IMPORT */ + 3, /* 3 ZFS_IOC_POOL_EXPORT */ + 4, /* 4 ZFS_IOC_POOL_CONFIGS */ + 5, /* 5 ZFS_IOC_POOL_STATS */ + 6, /* 6 ZFS_IOC_POOL_TRYIMPORT */ + 7, /* 7 ZFS_IOC_POOL_SCRUB */ + 8, /* 8 ZFS_IOC_POOL_FREEZE */ + 9, /* 9 ZFS_IOC_POOL_UPGRADE */ + 10, /* 10 ZFS_IOC_POOL_GET_HISTORY */ + 11, /* 11 ZFS_IOC_VDEV_ADD */ + 12, /* 12 ZFS_IOC_VDEV_REMOVE */ + 13, /* 13 ZFS_IOC_VDEV_SET_STATE */ + 14, /* 14 ZFS_IOC_VDEV_ATTACH */ + 15, /* 15 ZFS_IOC_VDEV_DETACH */ + 16, /* 16 ZFS_IOC_VDEV_SETPATH */ + 18, /* 17 ZFS_IOC_OBJSET_STATS */ + 19, /* 18 ZFS_IOC_OBJSET_ZPLPROPS */ + 20, /* 19 ZFS_IOC_DATASET_LIST_NEXT */ + 21, /* 20 ZFS_IOC_SNAPSHOT_LIST_NEXT */ + 22, /* 21 ZFS_IOC_SET_PROP */ + ZFS_IOC_COMPAT_PASS, /* 22 ZFS_IOC_CREATE_MINOR */ + ZFS_IOC_COMPAT_PASS, /* 23 ZFS_IOC_REMOVE_MINOR */ + 23, /* 24 ZFS_IOC_CREATE */ + 24, /* 25 ZFS_IOC_DESTROY */ + 25, /* 26 ZFS_IOC_ROLLBACK */ + 26, /* 27 ZFS_IOC_RENAME */ + 27, /* 28 ZFS_IOC_RECV */ + 28, /* 29 ZFS_IOC_SEND */ + 29, /* 30 ZFS_IOC_INJECT_FAULT */ + 30, /* 31 ZFS_IOC_CLEAR_FAULT */ + 31, /* 32 ZFS_IOC_INJECT_LIST_NEXT */ + 32, /* 33 ZFS_IOC_ERROR_LOG */ + 33, /* 34 ZFS_IOC_CLEAR */ + 34, /* 35 ZFS_IOC_PROMOTE */ + 35, /* 36 ZFS_IOC_DESTROY_SNAPS */ + 36, /* 37 ZFS_IOC_SNAPSHOT */ + 37, /* 38 ZFS_IOC_DSOBJ_TO_DSNAME */ + 38, /* 39 ZFS_IOC_OBJ_TO_PATH */ + 39, /* 40 ZFS_IOC_POOL_SET_PROPS */ + 40, /* 41 ZFS_IOC_POOL_GET_PROPS */ + 41, /* 42 ZFS_IOC_SET_FSACL */ + 42, /* 43 ZFS_IOC_GET_FSACL */ + ZFS_IOC_COMPAT_PASS, /* 44 ZFS_IOC_ISCSI_PERM_CHECK */ + 43, /* 45 ZFS_IOC_SHARE */ + 44, /* 46 ZFS_IOC_IHNERIT_PROP */ + 58, /* 47 ZFS_IOC_JAIL */ + 59, /* 48 ZFS_IOC_UNJAIL */ + 45, /* 49 ZFS_IOC_SMB_ACL */ + 46, /* 50 ZFS_IOC_USERSPACE_ONE */ + 47, /* 51 ZFS_IOC_USERSPACE_MANY */ + 48, /* 52 ZFS_IOC_USERSPACE_UPGRADE */ + 17, /* 53 ZFS_IOC_SETFRU */ +}; + +#else /* KERNEL */ +unsigned static long zfs_ioctl_v28_to_v15[] = { + 0, /* 0 ZFS_IOC_POOL_CREATE */ + 1, /* 1 ZFS_IOC_POOL_DESTROY */ + 2, /* 2 ZFS_IOC_POOL_IMPORT */ + 3, /* 3 ZFS_IOC_POOL_EXPORT */ + 4, /* 4 ZFS_IOC_POOL_CONFIGS */ + 5, /* 5 ZFS_IOC_POOL_STATS */ + 6, /* 6 ZFS_IOC_POOL_TRYIMPORT */ + 7, /* 7 ZFS_IOC_POOL_SCAN */ + 8, /* 8 ZFS_IOC_POOL_FREEZE */ + 9, /* 9 ZFS_IOC_POOL_UPGRADE */ + 10, /* 10 ZFS_IOC_POOL_GET_HISTORY */ + 11, /* 11 ZFS_IOC_VDEV_ADD */ + 12, /* 12 ZFS_IOC_VDEV_REMOVE */ + 13, /* 13 ZFS_IOC_VDEV_SET_STATE */ + 14, /* 14 ZFS_IOC_VDEV_ATTACH */ + 15, /* 15 ZFS_IOC_VDEV_DETACH */ + 16, /* 16 ZFS_IOC_VDEV_SETPATH */ + 53, /* 17 ZFS_IOC_VDEV_SETFRU */ + 17, /* 18 ZFS_IOC_OBJSET_STATS */ + 18, /* 19 ZFS_IOC_OBJSET_ZPLPROPS */ + 19, /* 20 ZFS_IOC_DATASET_LIST_NEXT */ + 20, /* 21 ZFS_IOC_SNAPSHOT_LIST_NEXT */ + 21, /* 22 ZFS_IOC_SET_PROP */ + 24, /* 23 ZFS_IOC_CREATE */ + 25, /* 24 ZFS_IOC_DESTROY */ + 26, /* 25 ZFS_IOC_ROLLBACK */ + 27, /* 26 ZFS_IOC_RENAME */ + 28, /* 27 ZFS_IOC_RECV */ + 29, /* 28 ZFS_IOC_SEND */ + 30, /* 39 ZFS_IOC_INJECT_FAULT */ + 31, /* 30 ZFS_IOC_CLEAR_FAULT */ + 32, /* 31 ZFS_IOC_INJECT_LIST_NEXT */ + 33, /* 32 ZFS_IOC_ERROR_LOG */ + 34, /* 33 ZFS_IOC_CLEAR */ + 35, /* 34 ZFS_IOC_PROMOTE */ + 36, /* 35 ZFS_IOC_DESTROY_SNAPS */ + 37, /* 36 ZFS_IOC_SNAPSHOT */ + 38, /* 37 ZFS_IOC_DSOBJ_TO_DSNAME */ + 39, /* 38 ZFS_IOC_OBJ_TO_PATH */ + 40, /* 39 ZFS_IOC_POOL_SET_PROPS */ + 41, /* 40 ZFS_IOC_POOL_GET_PROPS */ + 42, /* 41 ZFS_IOC_SET_FSACL */ + 43, /* 42 ZFS_IOC_GET_FSACL */ + 45, /* 43 ZFS_IOC_SHARE */ + 46, /* 44 ZFS_IOC_IHNERIT_PROP */ + 49, /* 45 ZFS_IOC_SMB_ACL */ + 50, /* 46 ZFS_IOC_USERSPACE_ONE */ + 51, /* 47 ZFS_IOC_USERSPACE_MANY */ + 52, /* 48 ZFS_IOC_USERSPACE_UPGRADE */ + ZFS_IOC_COMPAT_FAIL, /* 49 ZFS_IOC_HOLD */ + ZFS_IOC_COMPAT_FAIL, /* 50 ZFS_IOC_RELEASE */ + ZFS_IOC_COMPAT_FAIL, /* 51 ZFS_IOC_GET_HOLDS */ + ZFS_IOC_COMPAT_FAIL, /* 52 ZFS_IOC_OBJSET_RECVD_PROPS */ + ZFS_IOC_COMPAT_FAIL, /* 53 ZFS_IOC_VDEV_SPLIT */ + ZFS_IOC_COMPAT_FAIL, /* 54 ZFS_IOC_NEXT_OBJ */ + ZFS_IOC_COMPAT_FAIL, /* 55 ZFS_IOC_DIFF */ + ZFS_IOC_COMPAT_FAIL, /* 56 ZFS_IOC_TMP_SNAPSHOT */ + ZFS_IOC_COMPAT_FAIL, /* 57 ZFS_IOC_OBJ_TO_STATS */ + 47, /* 58 ZFS_IOC_JAIL */ + 48, /* 59 ZFS_IOC_UNJAIL */ +}; +#endif /* ! _KERNEL */ + +#ifdef _KERNEL +void zfs_ioctl_compat_pre(zfs_cmd_t *, int *, const int); +void zfs_ioctl_compat_post(zfs_cmd_t *, const int, const int); +#else +int zcmd_ioctl_compat(int, unsigned long, zfs_cmd_t *, const int); +#endif /* _KERNEL */ +void zfs_cmd_compat_get(zfs_cmd_t *, caddr_t, const int); +void zfs_cmd_compat_put(zfs_cmd_t *, caddr_t, const int); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_ZFS_IOCTL_COMPAT_H */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c index 45730c6..5cfafea 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c @@ -59,7 +59,7 @@ valid_char(char c) * Snapshot names must be made up of alphanumeric characters plus the following * characters: * - * [-_.:] + * [-_.: ] */ int snapshot_namecheck(const char *path, namecheck_err_t *why, char *what) diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c index fa98192..434b482 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c @@ -19,10 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* Portions Copyright 2010 Robert Milkowski */ + #include <sys/zio.h> #include <sys/spa.h> #include <sys/u8_textprep.h> @@ -69,6 +70,16 @@ zfs_prop_init(void) { NULL } }; + static zprop_index_t dedup_table[] = { + { "on", ZIO_CHECKSUM_ON }, + { "off", ZIO_CHECKSUM_OFF }, + { "verify", ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY }, + { "sha256", ZIO_CHECKSUM_SHA256 }, + { "sha256,verify", + ZIO_CHECKSUM_SHA256 | ZIO_CHECKSUM_VERIFY }, + { NULL } + }; + static zprop_index_t compress_table[] = { { "on", ZIO_COMPRESS_ON }, { "off", ZIO_COMPRESS_OFF }, @@ -83,6 +94,7 @@ zfs_prop_init(void) { "gzip-7", ZIO_COMPRESS_GZIP_7 }, { "gzip-8", ZIO_COMPRESS_GZIP_8 }, { "gzip-9", ZIO_COMPRESS_GZIP_9 }, + { "zle", ZIO_COMPRESS_ZLE }, { NULL } }; @@ -92,13 +104,6 @@ zfs_prop_init(void) { NULL } }; - static zprop_index_t acl_mode_table[] = { - { "discard", ZFS_ACL_DISCARD }, - { "groupmask", ZFS_ACL_GROUPMASK }, - { "passthrough", ZFS_ACL_PASSTHROUGH }, - { NULL } - }; - static zprop_index_t acl_inherit_table[] = { { "discard", ZFS_ACL_DISCARD }, { "noallow", ZFS_ACL_NOALLOW }, @@ -142,6 +147,7 @@ zfs_prop_init(void) { "2", 2 }, { "3", 3 }, { "4", 4 }, + { "5", 5 }, { "current", ZPL_VERSION }, { NULL } }; @@ -152,6 +158,12 @@ zfs_prop_init(void) { NULL } }; + static zprop_index_t logbias_table[] = { + { "latency", ZFS_LOGBIAS_LATENCY }, + { "throughput", ZFS_LOGBIAS_THROUGHPUT }, + { NULL } + }; + static zprop_index_t canmount_table[] = { { "off", ZFS_CANMOUNT_OFF }, { "on", ZFS_CANMOUNT_ON }, @@ -166,162 +178,208 @@ zfs_prop_init(void) { NULL } }; + static zprop_index_t sync_table[] = { + { "standard", ZFS_SYNC_STANDARD }, + { "always", ZFS_SYNC_ALWAYS }, + { "disabled", ZFS_SYNC_DISABLED }, + { NULL } + }; + /* inherit index properties */ - register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT, + zprop_register_index(ZFS_PROP_SYNC, "sync", ZFS_SYNC_STANDARD, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, + "standard | always | disabled", "SYNC", + sync_table); + zprop_register_index(ZFS_PROP_CHECKSUM, "checksum", + ZIO_CHECKSUM_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | + ZFS_TYPE_VOLUME, "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", checksum_table); - register_index(ZFS_PROP_COMPRESSION, "compression", + zprop_register_index(ZFS_PROP_DEDUP, "dedup", ZIO_CHECKSUM_OFF, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, + "on | off | verify | sha256[,verify]", "DEDUP", + dedup_table); + zprop_register_index(ZFS_PROP_COMPRESSION, "compression", ZIO_COMPRESS_DEFAULT, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, - "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table); - register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN, + "on | off | lzjb | gzip | gzip-[1-9] | zle", "COMPRESS", + compress_table); + zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "hidden | visible", "SNAPDIR", snapdir_table); - register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK, - PROP_INHERIT, ZFS_TYPE_FILESYSTEM, - "discard | groupmask | passthrough", "ACLMODE", acl_mode_table); - register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED, - PROP_INHERIT, ZFS_TYPE_FILESYSTEM, + zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit", + ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "discard | noallow | restricted | passthrough | passthrough-x", "ACLINHERIT", acl_inherit_table); - register_index(ZFS_PROP_COPIES, "copies", 1, - PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, + zprop_register_index(ZFS_PROP_COPIES, "copies", 1, PROP_INHERIT, + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "1 | 2 | 3", "COPIES", copies_table); - register_index(ZFS_PROP_PRIMARYCACHE, "primarycache", + zprop_register_index(ZFS_PROP_PRIMARYCACHE, "primarycache", ZFS_CACHE_ALL, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, "all | none | metadata", "PRIMARYCACHE", cache_table); - register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache", + zprop_register_index(ZFS_PROP_SECONDARYCACHE, "secondarycache", ZFS_CACHE_ALL, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, "all | none | metadata", "SECONDARYCACHE", cache_table); + zprop_register_index(ZFS_PROP_LOGBIAS, "logbias", ZFS_LOGBIAS_LATENCY, + PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, + "latency | throughput", "LOGBIAS", logbias_table); /* inherit index (boolean) properties */ - register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT, + zprop_register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table); - register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT, + zprop_register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES", boolean_table); - register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT, + zprop_register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC", boolean_table); - register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT, + zprop_register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID", boolean_table); - register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT, + zprop_register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY", boolean_table); - register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT, + zprop_register_index(ZFS_PROP_ZONED, "jailed", 0, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off", "JAILED", boolean_table); - register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT, + zprop_register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR", boolean_table); - register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT, + zprop_register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN", boolean_table); - register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT, + zprop_register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND", boolean_table); /* default index properties */ - register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT, + zprop_register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "1 | 2 | 3 | 4 | current", "VERSION", version_table); - register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON, + zprop_register_index(ZFS_PROP_CANMOUNT, "canmount", ZFS_CANMOUNT_ON, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "on | off | noauto", "CANMOUNT", canmount_table); /* readonly index (boolean) properties */ - register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY, + zprop_register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY, ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table); + zprop_register_index(ZFS_PROP_DEFER_DESTROY, "defer_destroy", 0, + PROP_READONLY, ZFS_TYPE_SNAPSHOT, "yes | no", "DEFER_DESTROY", + boolean_table); /* set once index properties */ - register_index(ZFS_PROP_NORMALIZE, "normalization", 0, + zprop_register_index(ZFS_PROP_NORMALIZE, "normalization", 0, PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "none | formC | formD | formKC | formKD", "NORMALIZATION", normalize_table); - register_index(ZFS_PROP_CASE, "casesensitivity", ZFS_CASE_SENSITIVE, - PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, + zprop_register_index(ZFS_PROP_CASE, "casesensitivity", + ZFS_CASE_SENSITIVE, PROP_ONETIME, ZFS_TYPE_FILESYSTEM | + ZFS_TYPE_SNAPSHOT, "sensitive | insensitive | mixed", "CASE", case_table); /* set once index (boolean) properties */ - register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME, + zprop_register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "UTF8ONLY", boolean_table); /* string properties */ - register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY, + zprop_register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN"); - register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT, - ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT"); - register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT, - ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS"); - register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT, - ZFS_TYPE_DATASET, "on | off | type=<type>", "SHAREISCSI"); - register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY, + zprop_register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", + "MOUNTPOINT"); + zprop_register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", + "SHARENFS"); + zprop_register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY, ZFS_TYPE_DATASET, "filesystem | volume | snapshot", "TYPE"); - register_string(ZFS_PROP_SHARESMB, "sharesmb", "off", PROP_INHERIT, - ZFS_TYPE_FILESYSTEM, "on | off | sharemgr(1M) options", "SHARESMB"); + zprop_register_string(ZFS_PROP_SHARESMB, "sharesmb", "off", + PROP_INHERIT, ZFS_TYPE_FILESYSTEM, + "on | off | sharemgr(1M) options", "SHARESMB"); + zprop_register_string(ZFS_PROP_MLSLABEL, "mlslabel", + ZFS_MLSLABEL_DEFAULT, PROP_INHERIT, ZFS_TYPE_DATASET, + "<sensitivity label>", "MLSLABEL"); /* readonly number properties */ - register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY, + zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "USED"); - register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY, + zprop_register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL"); - register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY, - ZFS_TYPE_DATASET, "<size>", "REFER"); - register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0, + zprop_register_number(ZFS_PROP_REFERENCED, "referenced", 0, + PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "REFER"); + zprop_register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0, PROP_READONLY, ZFS_TYPE_DATASET, "<1.00x or higher if compressed>", "RATIO"); - register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192, - PROP_ONETIME, + zprop_register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", + ZVOL_DEFAULT_BLOCKSIZE, PROP_ONETIME, ZFS_TYPE_VOLUME, "512 to 128k, power of 2", "VOLBLOCK"); - register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0, PROP_READONLY, - ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDSNAP"); - register_number(ZFS_PROP_USEDDS, "usedbydataset", 0, PROP_READONLY, - ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDDS"); - register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0, PROP_READONLY, - ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDCHILD"); - register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0, + zprop_register_number(ZFS_PROP_USEDSNAP, "usedbysnapshots", 0, + PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", + "USEDSNAP"); + zprop_register_number(ZFS_PROP_USEDDS, "usedbydataset", 0, + PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", + "USEDDS"); + zprop_register_number(ZFS_PROP_USEDCHILD, "usedbychildren", 0, + PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", + "USEDCHILD"); + zprop_register_number(ZFS_PROP_USEDREFRESERV, "usedbyrefreservation", 0, PROP_READONLY, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "USEDREFRESERV"); + zprop_register_number(ZFS_PROP_USERREFS, "userrefs", 0, PROP_READONLY, + ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS"); /* default number properties */ - register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT, + zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA"); - register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT, - ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV"); - register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT, + zprop_register_number(ZFS_PROP_RESERVATION, "reservation", 0, + PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, + "<size> | none", "RESERV"); + zprop_register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT, ZFS_TYPE_VOLUME, "<size>", "VOLSIZE"); - register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT, + zprop_register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA"); - register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0, + zprop_register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "REFRESERV"); /* inherit number properties */ - register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE, - PROP_INHERIT, + zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize", + SPA_MAXBLOCKSIZE, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE"); /* hidden properties */ - register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER, + zprop_register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "CREATETXG"); - register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER, - PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL); - register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING, + zprop_register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER, + PROP_READONLY, ZFS_TYPE_SNAPSHOT, "NUMCLONES"); + zprop_register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING, PROP_READONLY, ZFS_TYPE_DATASET, "NAME"); - register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING, - PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS"); - register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER, PROP_READONLY, - ZFS_TYPE_DATASET, "GUID"); - register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting", - PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, NULL); + zprop_register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", + PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS"); + zprop_register_hidden(ZFS_PROP_STMF_SHAREINFO, "stmf_sbd_lu", + PROP_TYPE_STRING, PROP_INHERIT, ZFS_TYPE_VOLUME, + "STMF_SBD_LU"); + zprop_register_hidden(ZFS_PROP_GUID, "guid", PROP_TYPE_NUMBER, + PROP_READONLY, ZFS_TYPE_DATASET, "GUID"); + zprop_register_hidden(ZFS_PROP_USERACCOUNTING, "useraccounting", + PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, + "USERACCOUNTING"); + zprop_register_hidden(ZFS_PROP_UNIQUE, "unique", PROP_TYPE_NUMBER, + PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE"); + zprop_register_hidden(ZFS_PROP_OBJSETID, "objsetid", PROP_TYPE_NUMBER, + PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID"); + + /* + * Property to be removed once libbe is integrated + */ + zprop_register_hidden(ZFS_PROP_PRIVATE, "priv_prop", + PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_FILESYSTEM, + "PRIV_PROP"); /* oddball properties */ - register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL, - PROP_READONLY, ZFS_TYPE_DATASET, + zprop_register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, + NULL, PROP_READONLY, ZFS_TYPE_DATASET, "<date>", "CREATION", B_FALSE, B_TRUE, NULL); } @@ -329,6 +387,11 @@ boolean_t zfs_prop_delegatable(zfs_prop_t prop) { zprop_desc_t *pd = &zfs_prop_table[prop]; + + /* The mlslabel property is never delegatable. */ + if (prop == ZFS_PROP_MLSLABEL) + return (B_FALSE); + return (pd->pd_attr != PROP_READONLY); } @@ -413,6 +476,12 @@ zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string) return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET)); } +uint64_t +zfs_prop_random_value(zfs_prop_t prop, uint64_t seed) +{ + return (zprop_random_value(prop, seed, ZFS_TYPE_DATASET)); +} + /* * Returns TRUE if the property applies to any of the given dataset types. */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.h b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.h index da5ae43..a632623 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.h +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ZFS_PROP_H #define _ZFS_PROP_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/fs/zfs.h> #include <sys/types.h> @@ -79,6 +77,7 @@ typedef struct { /* "zfs get" help message */ const zprop_index_t *pd_table; /* for index properties, a table */ /* defining the possible values */ + size_t pd_table_size; /* number of entries in pd_table[] */ } zprop_desc_t; /* @@ -99,16 +98,16 @@ zprop_desc_t *zpool_prop_get_table(void); /* * Common routines to initialize property tables */ -void register_impl(int, const char *, zprop_type_t, uint64_t, +void zprop_register_impl(int, const char *, zprop_type_t, uint64_t, const char *, zprop_attr_t, int, const char *, const char *, boolean_t, boolean_t, const zprop_index_t *); -void register_string(int, const char *, const char *, zprop_attr_t attr, - int, const char *, const char *); -void register_number(int, const char *, uint64_t, zprop_attr_t, int, +void zprop_register_string(int, const char *, const char *, + zprop_attr_t attr, int, const char *, const char *); +void zprop_register_number(int, const char *, uint64_t, zprop_attr_t, int, const char *, const char *); -void register_index(int, const char *, uint64_t, zprop_attr_t, int, +void zprop_register_index(int, const char *, uint64_t, zprop_attr_t, int, const char *, const char *, const zprop_index_t *); -void register_hidden(int, const char *, zprop_type_t, zprop_attr_t, +void zprop_register_hidden(int, const char *, zprop_type_t, zprop_attr_t, int, const char *); /* @@ -118,6 +117,7 @@ int zprop_iter_common(zprop_func, void *, boolean_t, boolean_t, zfs_type_t); int zprop_name_to_prop(const char *, zfs_type_t); int zprop_string_to_index(int, const char *, uint64_t *, zfs_type_t); int zprop_index_to_string(int, uint64_t, const char **, zfs_type_t); +uint64_t zprop_random_value(int, uint64_t, zfs_type_t); const char *zprop_values(int, zfs_type_t); size_t zprop_width(int, boolean_t *, zfs_type_t); boolean_t zprop_valid_for_type(int, zfs_type_t); diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c index f5efe18..988d05d 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/zio.h> @@ -64,46 +63,57 @@ zpool_prop_init(void) }; /* string properties */ - register_string(ZPOOL_PROP_ALTROOT, "altroot", NULL, PROP_DEFAULT, + zprop_register_string(ZPOOL_PROP_ALTROOT, "altroot", NULL, PROP_DEFAULT, ZFS_TYPE_POOL, "<path>", "ALTROOT"); - register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT, + zprop_register_string(ZPOOL_PROP_BOOTFS, "bootfs", NULL, PROP_DEFAULT, ZFS_TYPE_POOL, "<filesystem>", "BOOTFS"); - register_string(ZPOOL_PROP_CACHEFILE, "cachefile", NULL, PROP_DEFAULT, - ZFS_TYPE_POOL, "<file> | none", "CACHEFILE"); + zprop_register_string(ZPOOL_PROP_CACHEFILE, "cachefile", NULL, + PROP_DEFAULT, ZFS_TYPE_POOL, "<file> | none", "CACHEFILE"); /* readonly number properties */ - register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY, + zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY, ZFS_TYPE_POOL, "<size>", "SIZE"); - register_number(ZPOOL_PROP_USED, "used", 0, PROP_READONLY, - ZFS_TYPE_POOL, "<size>", "USED"); - register_number(ZPOOL_PROP_AVAILABLE, "available", 0, PROP_READONLY, - ZFS_TYPE_POOL, "<size>", "AVAIL"); - register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY, + zprop_register_number(ZPOOL_PROP_FREE, "free", 0, PROP_READONLY, + ZFS_TYPE_POOL, "<size>", "FREE"); + zprop_register_number(ZPOOL_PROP_ALLOCATED, "allocated", 0, + PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC"); + zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY, ZFS_TYPE_POOL, "<size>", "CAP"); - register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY, + zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY, ZFS_TYPE_POOL, "<guid>", "GUID"); - register_number(ZPOOL_PROP_HEALTH, "health", 0, PROP_READONLY, + zprop_register_number(ZPOOL_PROP_HEALTH, "health", 0, PROP_READONLY, ZFS_TYPE_POOL, "<state>", "HEALTH"); + zprop_register_number(ZPOOL_PROP_DEDUPRATIO, "dedupratio", 0, + PROP_READONLY, ZFS_TYPE_POOL, "<1.00x or higher if deduped>", + "DEDUP"); /* default number properties */ - register_number(ZPOOL_PROP_VERSION, "version", SPA_VERSION, + zprop_register_number(ZPOOL_PROP_VERSION, "version", SPA_VERSION, PROP_DEFAULT, ZFS_TYPE_POOL, "<version>", "VERSION"); + zprop_register_number(ZPOOL_PROP_DEDUPDITTO, "dedupditto", 0, + PROP_DEFAULT, ZFS_TYPE_POOL, "<threshold (min 100)>", "DEDUPDITTO"); /* default index (boolean) properties */ - register_index(ZPOOL_PROP_DELEGATION, "delegation", 1, PROP_DEFAULT, - ZFS_TYPE_POOL, "on | off", "DELEGATION", boolean_table); - register_index(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0, PROP_DEFAULT, - ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table); - register_index(ZPOOL_PROP_LISTSNAPS, "listsnapshots", 0, PROP_DEFAULT, - ZFS_TYPE_POOL, "on | off", "LISTSNAPS", boolean_table); + zprop_register_index(ZPOOL_PROP_DELEGATION, "delegation", 1, + PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "DELEGATION", + boolean_table); + zprop_register_index(ZPOOL_PROP_AUTOREPLACE, "autoreplace", 0, + PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "REPLACE", boolean_table); + zprop_register_index(ZPOOL_PROP_LISTSNAPS, "listsnapshots", 0, + PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "LISTSNAPS", + boolean_table); + zprop_register_index(ZPOOL_PROP_AUTOEXPAND, "autoexpand", 0, + PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "EXPAND", boolean_table); + zprop_register_index(ZPOOL_PROP_READONLY, "readonly", 0, + PROP_DEFAULT, ZFS_TYPE_POOL, "on | off", "RDONLY", boolean_table); /* default index properties */ - register_index(ZPOOL_PROP_FAILUREMODE, "failmode", + zprop_register_index(ZPOOL_PROP_FAILUREMODE, "failmode", ZIO_FAILURE_MODE_WAIT, PROP_DEFAULT, ZFS_TYPE_POOL, "wait | continue | panic", "FAILMODE", failuremode_table); /* hidden properties */ - register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING, + zprop_register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING, PROP_READONLY, ZFS_TYPE_POOL, "NAME"); } @@ -164,6 +174,12 @@ zpool_prop_index_to_string(zpool_prop_t prop, uint64_t index, return (zprop_index_to_string(prop, index, string, ZFS_TYPE_POOL)); } +uint64_t +zpool_prop_random_value(zpool_prop_t prop, uint64_t seed) +{ + return (zprop_random_value(prop, seed, ZFS_TYPE_POOL)); +} + #ifndef _KERNEL const char * diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zprop_common.c b/sys/cddl/contrib/opensolaris/common/zfs/zprop_common.c index d3301b5..4d7e79c 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zprop_common.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zprop_common.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -65,7 +65,7 @@ zprop_get_numprops(zfs_type_t type) } void -register_impl(int prop, const char *name, zprop_type_t type, +zprop_register_impl(int prop, const char *name, zprop_type_t type, uint64_t numdefault, const char *strdefault, zprop_attr_t attr, int objset_types, const char *values, const char *colname, boolean_t rightalign, boolean_t visible, const zprop_index_t *idx_tbl) @@ -76,6 +76,8 @@ register_impl(int prop, const char *name, zprop_type_t type, pd = &prop_tbl[prop]; ASSERT(pd->pd_name == NULL || pd->pd_name == name); + ASSERT(name != NULL); + ASSERT(colname != NULL); pd->pd_name = name; pd->pd_propnum = prop; @@ -89,40 +91,44 @@ register_impl(int prop, const char *name, zprop_type_t type, pd->pd_rightalign = rightalign; pd->pd_visible = visible; pd->pd_table = idx_tbl; + pd->pd_table_size = 0; + while (idx_tbl && (idx_tbl++)->pi_name != NULL) + pd->pd_table_size++; } void -register_string(int prop, const char *name, const char *def, +zprop_register_string(int prop, const char *name, const char *def, zprop_attr_t attr, int objset_types, const char *values, const char *colname) { - register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr, + zprop_register_impl(prop, name, PROP_TYPE_STRING, 0, def, attr, objset_types, values, colname, B_FALSE, B_TRUE, NULL); } void -register_number(int prop, const char *name, uint64_t def, zprop_attr_t attr, - int objset_types, const char *values, const char *colname) +zprop_register_number(int prop, const char *name, uint64_t def, + zprop_attr_t attr, int objset_types, const char *values, + const char *colname) { - register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr, + zprop_register_impl(prop, name, PROP_TYPE_NUMBER, def, NULL, attr, objset_types, values, colname, B_TRUE, B_TRUE, NULL); } void -register_index(int prop, const char *name, uint64_t def, zprop_attr_t attr, - int objset_types, const char *values, const char *colname, - const zprop_index_t *idx_tbl) +zprop_register_index(int prop, const char *name, uint64_t def, + zprop_attr_t attr, int objset_types, const char *values, + const char *colname, const zprop_index_t *idx_tbl) { - register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, attr, + zprop_register_impl(prop, name, PROP_TYPE_INDEX, def, NULL, attr, objset_types, values, colname, B_TRUE, B_TRUE, idx_tbl); } void -register_hidden(int prop, const char *name, zprop_type_t type, +zprop_register_hidden(int prop, const char *name, zprop_type_t type, zprop_attr_t attr, int objset_types, const char *colname) { - register_impl(prop, name, type, 0, NULL, attr, + zprop_register_impl(prop, name, type, 0, NULL, attr, objset_types, NULL, colname, B_FALSE, B_FALSE, NULL); } @@ -307,6 +313,25 @@ zprop_index_to_string(int prop, uint64_t index, const char **string, return (-1); } +/* + * Return a random valid property value. Used by ztest. + */ +uint64_t +zprop_random_value(int prop, uint64_t seed, zfs_type_t type) +{ + zprop_desc_t *prop_tbl; + const zprop_index_t *idx_tbl; + + ASSERT((uint_t)prop < zprop_get_numprops(type)); + prop_tbl = zprop_get_proptable(type); + idx_tbl = prop_tbl[prop].pd_table; + + if (idx_tbl == NULL) + return (seed); + + return (idx_tbl[seed % prop_tbl[prop].pd_table_size].pi_value); +} + const char * zprop_values(int prop, zfs_type_t type) { |