/*
* 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
* 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 (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
*/
#include <sys/zfs_context.h>
#include <sys/refcount.h>
#include <sys/zap_impl.h>
#include <sys/zap_leaf.h>
#include <sys/dmu_objset.h>
#ifdef _KERNEL
#endif
{
if (zap->zap_ismicro)
return (0);
}
int
{
return (48);
else
return (28);
}
{
return ((1<<16)-1);
else
return (-1U);
}
static uint64_t
{
uint64_t h = 0;
} else {
ASSERT(h != 0);
int i;
int j;
for (j = 0; j < zn->zn_key_intlen; j++) {
h = (h >> 8) ^
}
}
} else {
int i, len;
/*
* We previously stored the terminating null on
* disk, but didn't hash it, so we need to
* continue to not hash it. (The
* zn_key_*_numints includes the terminating
* null for non-binary keys.)
*/
h = (h >> 8) ^
}
}
}
/*
* Don't use all 64 bits, since we need some in the cookie for
* the collision differentiator. We MUST use the high bits,
* since those are the ones that we first pay attention to when
* chosing the bucket.
*/
return (h);
}
static int
{
int err;
err = 0;
return (err);
}
{
return (B_FALSE);
} else {
/* MT_BEST or MT_EXACT */
}
}
void
{
}
{
if (zap->zap_normflags) {
return (NULL);
}
} else {
return (NULL);
}
}
return (zn);
}
{
return (zn);
}
static void
{
int i, max;
for (i = 0; i < max; i++) {
}
}
void
{
/* ASSERT(magic == ZAP_LEAF_MAGIC); */
} else {
}
}
static int
{
return (+1);
return (-1);
return (+1);
return (-1);
return (0);
}
static void
{
}
static mzap_ent_t *
{
mze_tofind.mze_cd = 0;
return (mze);
}
goto again;
}
return (NULL);
}
static uint32_t
{
mze_tofind.mze_cd = 0;
cd = 0;
break;
cd++;
}
return (cd);
}
static void
{
}
static void
{
}
static zap_t *
{
int i;
if (zap_block_type != ZBT_MICRO) {
goto handle_winner;
}
} else {
}
/*
* Make sure that zap_ismicro is set before we let others see
* it, because zap_lockdir() checks zap_ismicro without the lock
* held.
*/
goto handle_winner;
if (zap->zap_ismicro) {
MT_EXACT);
}
}
} else {
ASSERT3U(sizeof (struct zap_leaf_header), ==,
/*
* The embedded pointer table should not overlap the
* other members.
*/
/*
* The embedded pointer table should end at the end of
* the block
*/
}
return (zap);
if (!zap->zap_ismicro)
return (winner);
}
static int
{
#ifdef ZFS_DEBUG
{
}
#endif
/*
* mzap_open() didn't like what it saw on-disk.
* Check for corruption!
*/
}
}
/*
* We're checking zap_ismicro without the lock held, in order to
* tell what type of lock we want. Once we have some sort of
* lock, see if it really is the right type. In practice this
* can only be different if it was upgraded from micro to fat,
* and micro wanted WRITER but fat only needs READER.
*/
/* it was upgraded, now we only need reader */
}
if (newsz > MZAP_MAX_BLKSZ) {
dprintf("upgrading obj %llu: num_entries=%u\n",
if (err != 0)
return (err);
}
}
return (0);
}
static int
{
int err;
if (err != 0) {
return (err);
}
if (err != 0) {
}
return (err);
}
int
{
int err;
if (err != 0)
return (err);
if (err != 0)
return (err);
}
void
{
}
static int
{
int err = 0;
if (!flags) {
if (err) {
return (err);
}
}
dprintf("upgrading obj=%llu with %u chunks\n",
/* XXX destroy the avl later, so we can use the stored hash value */
for (i = 0; i < nchunks; i++) {
continue;
dprintf("adding %s=%llu\n",
if (err)
break;
}
return (err);
}
void
{
#ifdef ZFS_DEBUG
{
}
#endif
if (flags != 0) {
/* Only fat zap supports flags; upgrade immediately. */
}
}
int
{
}
int
{
int err;
if (err != 0)
return (err);
return (0);
}
{
}
{
return (obj);
}
{
return (obj);
}
int
{
/*
* dmu_object_free will free the object number and free the
* data. Freeing the data will cause our pageout function to be
* called, which will destroy our data (zap_leaf_t's and zap_t).
*/
}
void
{
if (zap->zap_ismicro)
else
}
int
{
int err;
if (err)
return (err);
if (!zap->zap_ismicro) {
} else {
}
return (err);
}
/*
* zn may be NULL; if not specified, it will be computed if needed.
* See also the comment above zap_entry_normalization_conflict().
*/
static boolean_t
{
if (zap->zap_normflags == 0)
return (B_FALSE);
MT_FIRST);
}
if (allocdzn)
return (B_TRUE);
}
}
if (direction == AVL_BEFORE) {
goto again;
}
if (allocdzn)
return (B_FALSE);
}
/*
* Routines for manipulating attributes.
*/
int
{
}
static int
{
int err = 0;
if (!zap->zap_ismicro) {
} else {
} else {
if (num_integers < 1) {
} else if (integer_size != 8) {
} else {
if (ncp) {
}
}
}
}
return (err);
}
int
{
int err;
if (err != 0)
return (err);
return (err);
}
int
{
}
int
{
int err;
if (err != 0)
return (err);
return (err);
}
int
int key_numints)
{
int err;
if (err)
return (err);
}
return (err);
}
int
{
int err;
if (err)
return (err);
}
return (err);
}
int
{
err = 0; /* found, but skipped reading the value */
return (err);
}
int
{
int err;
if (err)
return (err);
}
if (!zap->zap_ismicro) {
} else {
} else {
if (integer_size)
*integer_size = 8;
if (num_integers)
*num_integers = 1;
}
}
return (err);
}
int
{
int err;
if (err)
return (err);
}
return (err);
}
static void
{
int i;
#ifdef ZFS_DEBUG
}
#endif
/* given the limited size of the microzap, this can't happen */
return;
}
}
if (start != 0) {
start = 0;
goto again;
}
ASSERT(!"out of entries!");
}
int
{
int err;
if (err)
return (err);
}
if (!zap->zap_ismicro) {
if (err == 0) {
}
} else {
} else {
}
}
return (err);
}
int
{
int err;
if (err)
return (err);
}
return (err);
}
int
{
int err;
#ifdef ZFS_DEBUG
/*
* If there is an old value, it shouldn't change across the
* lockdir (eg, due to bprewrite's xlation).
*/
#endif
if (err)
return (err);
}
if (!zap->zap_ismicro) {
dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
if (err == 0) {
}
} else {
} else {
}
}
return (err);
}
int
int key_numints,
{
int err;
if (err)
return (err);
}
return (err);
}
int
{
}
int
{
int err;
if (err)
return (err);
}
if (!zap->zap_ismicro) {
} else {
} else {
sizeof (mzap_ent_phys_t));
}
}
return (err);
}
int
{
int err;
if (err)
return (err);
}
return (err);
}
/*
* Routines for iterating over the attributes.
*/
void
{
}
void
{
}
void
{
}
}
}
{
return (-1ULL);
return (zc->zc_serialized);
/*
* We want to keep the high 32 bits of the cursor zero if we can, so
* that 32-bit programs can access this. So usually use a small
* (28-bit) hash value so we can fit 4 bits of cd into the low 32-bits
* of the cursor.
*
* [ collision differentiator | zap_hashbits()-bit hash value ]
*/
}
int
{
int err;
int hb;
if (err)
return (err);
/*
* To support zap_cursor_init_serialized, advance, retrieve,
* we must add to the existing zc_cd, which may already
* be 1 due to the zap_cursor_advance.
*/
} else {
}
} else {
}
if (mze) {
err = 0;
} else {
}
}
return (err);
}
void
{
return;
}
int
{
int err;
if (err)
return (err);
if (zap->zap_ismicro) {
} else {
}
return (0);
}
int
{
int err = 0;
/*
* Since, we don't have a name, we cannot figure out which blocks will
* be affected in this operation. So, account for the worst case :
* - 3 blocks overwritten: target leaf, ptrtbl block, header block
* - 4 new blocks written if adding:
* - 2 blocks for possibly split leaves,
* - 2 grown ptrtbl blocks
*
* This also accommodates the case where an add operation to a fairly
* large microzap results in a promotion to fatzap.
*/
(void) refcount_add_many(towrite,
return (err);
}
/*
* We lock the zap with adding == FALSE. Because, if we pass
* the actual value of add, it could trigger a mzap_upgrade().
* At present we are just evaluating the possibility of this operation
* and hence we do not want to trigger an upgrade.
*/
if (err != 0)
return (err);
if (!zap->zap_ismicro) {
if (zn) {
} else {
/*
* We treat this case as similar to (name == NULL)
*/
(void) refcount_add_many(towrite,
}
} else {
/*
* We are here if (name != NULL) and this is a micro-zap.
* We account for the header block depending on whether it
* is freeable.
*
* Incase of an add-operation it is hard to find out
* if this add will promote this microzap to fatzap.
* Hence, we consider the worst case and account for the
* blocks assuming this microzap would be promoted to a
* fatzap.
*
* 1 block overwritten : header block
* 4 new blocks written : 2 new split leaf, 2 grown
* ptrtbl blocks
*/
(void) refcount_add_many(tooverwrite,
} else {
(void) refcount_add_many(towrite,
}
if (add) {
(void) refcount_add_many(towrite,
}
}
return (err);
}