-/*
- * Apply mode to canonical six ACEs.
- */
-static void
-zfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode)
-{
- zfs_acl_node_t *aclnode = list_tail(&aclp->z_acl);
- void *acep;
- int maskoff = aclp->z_ops.ace_mask_off();
- size_t abstract_size = aclp->z_ops.ace_abstract_size();
-
- ASSERT(aclnode != NULL);
-
- acep = (void *)((caddr_t)aclnode->z_acldata +
- aclnode->z_size - (abstract_size * 6));
-
- /*
- * Fixup final ACEs to match the mode
- */
-
- adjust_ace_pair_common(acep, maskoff, abstract_size,
- (mode & 0700) >> 6); /* owner@ */
-
- acep = (caddr_t)acep + (abstract_size * 2);
-
- adjust_ace_pair_common(acep, maskoff, abstract_size,
- (mode & 0070) >> 3); /* group@ */
-
- acep = (caddr_t)acep + (abstract_size * 2);
- adjust_ace_pair_common(acep, maskoff,
- abstract_size, mode); /* everyone@ */
-}
-
-
-static int
-zfs_acl_ace_match(zfs_acl_t *aclp, void *acep, int allow_deny,
- int entry_type, int accessmask)
-{
- uint32_t mask = aclp->z_ops.ace_mask_get(acep);
- uint16_t type = aclp->z_ops.ace_type_get(acep);
- uint16_t flags = aclp->z_ops.ace_flags_get(acep);
-
- return (mask == accessmask && type == allow_deny &&
- ((flags & ACE_TYPE_FLAGS) == entry_type));
-}
-
-/*
- * Can prepended ACE be reused?
- */
-static int
-zfs_reuse_deny(zfs_acl_t *aclp, void *acep, void *prevacep)
-{
- int okay_masks;
- uint16_t prevtype;
- uint16_t prevflags;
- uint16_t flags;
- uint32_t mask, prevmask;
-
- if (prevacep == NULL)
- return (B_FALSE);
-
- prevtype = aclp->z_ops.ace_type_get(prevacep);
- prevflags = aclp->z_ops.ace_flags_get(prevacep);
- flags = aclp->z_ops.ace_flags_get(acep);
- mask = aclp->z_ops.ace_mask_get(acep);
- prevmask = aclp->z_ops.ace_mask_get(prevacep);
-
- if (prevtype != DENY)
- return (B_FALSE);
-
- if (prevflags != (flags & ACE_IDENTIFIER_GROUP))
- return (B_FALSE);
-
- okay_masks = (mask & OKAY_MASK_BITS);
-
- if (prevmask & ~okay_masks)
- return (B_FALSE);
-
- return (B_TRUE);
-}
-
-
-/*
- * Insert new ACL node into chain of zfs_acl_node_t's
- *
- * This will result in two possible results.
- * 1. If the ACL is currently just a single zfs_acl_node and
- * we are prepending the entry then current acl node will have
- * a new node inserted above it.
- *
- * 2. If we are inserting in the middle of current acl node then
- * the current node will be split in two and new node will be inserted
- * in between the two split nodes.
- */
-static zfs_acl_node_t *
-zfs_acl_ace_insert(zfs_acl_t *aclp, void *acep)
-{
- zfs_acl_node_t *newnode;
- zfs_acl_node_t *trailernode = NULL;
- zfs_acl_node_t *currnode = zfs_acl_curr_node(aclp);
- int curr_idx = aclp->z_curr_node->z_ace_idx;
- int trailer_count;
- size_t oldsize;
-
- newnode = zfs_acl_node_alloc(aclp->z_ops.ace_size(acep));
- newnode->z_ace_count = 1;
-
- oldsize = currnode->z_size;
-
- if (curr_idx != 1) {
- trailernode = zfs_acl_node_alloc(0);
- trailernode->z_acldata = acep;
-
- trailer_count = currnode->z_ace_count - curr_idx + 1;
- currnode->z_ace_count = curr_idx - 1;
- currnode->z_size = (caddr_t)acep - (caddr_t)currnode->z_acldata;
- trailernode->z_size = oldsize - currnode->z_size;
- trailernode->z_ace_count = trailer_count;
- }
-
- aclp->z_acl_count += 1;
- aclp->z_acl_bytes += aclp->z_ops.ace_size(acep);
-
- if (curr_idx == 1)
- list_insert_before(&aclp->z_acl, currnode, newnode);
- else
- list_insert_after(&aclp->z_acl, currnode, newnode);
- if (trailernode) {
- list_insert_after(&aclp->z_acl, newnode, trailernode);
- aclp->z_curr_node = trailernode;
- trailernode->z_ace_idx = 1;
- }
-
- return (newnode);
-}
-
-/*
- * Prepend deny ACE
- */
-static void *
-zfs_acl_prepend_deny(uint64_t uid, zfs_acl_t *aclp, void *acep,
- mode_t mode)
-{
- zfs_acl_node_t *aclnode;
- void *newacep;
- uint64_t fuid;
- uint16_t flags;
-
- aclnode = zfs_acl_ace_insert(aclp, acep);
- newacep = aclnode->z_acldata;
- fuid = aclp->z_ops.ace_who_get(acep);
- flags = aclp->z_ops.ace_flags_get(acep);
- zfs_set_ace(aclp, newacep, 0, DENY, fuid, (flags & ACE_TYPE_FLAGS));
- zfs_acl_prepend_fixup(aclp, newacep, acep, mode, uid);
-
- return (newacep);
-}
-
-/*
- * Split an inherited ACE into inherit_only ACE
- * and original ACE with inheritance flags stripped off.
- */
-static void
-zfs_acl_split_ace(zfs_acl_t *aclp, zfs_ace_hdr_t *acep)
-{
- zfs_acl_node_t *aclnode;
- zfs_acl_node_t *currnode;
- void *newacep;
- uint16_t type, flags;
- uint32_t mask;
- uint64_t fuid;
-
- type = aclp->z_ops.ace_type_get(acep);
- flags = aclp->z_ops.ace_flags_get(acep);
- mask = aclp->z_ops.ace_mask_get(acep);
- fuid = aclp->z_ops.ace_who_get(acep);
-
- aclnode = zfs_acl_ace_insert(aclp, acep);
- newacep = aclnode->z_acldata;
-
- aclp->z_ops.ace_type_set(newacep, type);
- aclp->z_ops.ace_flags_set(newacep, flags | ACE_INHERIT_ONLY_ACE);
- aclp->z_ops.ace_mask_set(newacep, mask);
- aclp->z_ops.ace_type_set(newacep, type);
- aclp->z_ops.ace_who_set(newacep, fuid);
- aclp->z_next_ace = acep;
- flags &= ~ALL_INHERIT;
- aclp->z_ops.ace_flags_set(acep, flags);
- currnode = zfs_acl_curr_node(aclp);
- ASSERT(currnode->z_ace_idx >= 1);
- currnode->z_ace_idx -= 1;
-}
-
-/*
- * Are ACES started at index i, the canonical six ACES?
- */
-static int
-zfs_have_canonical_six(zfs_acl_t *aclp)
-{
- void *acep;
- zfs_acl_node_t *aclnode = list_tail(&aclp->z_acl);
- int i = 0;
- size_t abstract_size = aclp->z_ops.ace_abstract_size();
-
- ASSERT(aclnode != NULL);
-
- if (aclnode->z_ace_count < 6)
- return (0);
-
- acep = (void *)((caddr_t)aclnode->z_acldata +
- aclnode->z_size - (aclp->z_ops.ace_abstract_size() * 6));
-
- if ((zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
- DENY, ACE_OWNER, 0) &&
- zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
- ALLOW, ACE_OWNER, OWNER_ALLOW_MASK) &&
- zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++), DENY,
- OWNING_GROUP, 0) && zfs_acl_ace_match(aclp, (caddr_t)acep +
- (abstract_size * i++),
- ALLOW, OWNING_GROUP, 0) &&
- zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
- DENY, ACE_EVERYONE, EVERYONE_DENY_MASK) &&
- zfs_acl_ace_match(aclp, (caddr_t)acep + (abstract_size * i++),
- ALLOW, ACE_EVERYONE, EVERYONE_ALLOW_MASK))) {
- return (1);
- } else {
- return (0);
- }
-}
-
-
-/*
- * Apply step 1g, to group entries
- *
- * Need to deal with corner case where group may have
- * greater permissions than owner. If so then limit
- * group permissions, based on what extra permissions
- * group has.
- */