MFV r305335: 7003 zap_lockdir() should tag hold

zap_lockdir() / zap_unlockdir() should take a "void *tag" argument which
tags the hold on the zap. This will help diagnose programming errors
which misuse the hold on the ZAP.

Sponsored by: Intel Corp.

Closes #108

Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed by: Steve Gonczi <steve.gonczi@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Author: Matthew Ahrens <mahrens@delphix.com>

openzfs/openzfs@0780b3eab5
This commit is contained in:
Alexander Motin 2016-09-03 10:58:14 +00:00
commit 070da3f779
5 changed files with 152 additions and 106 deletions

View File

@ -21,7 +21,7 @@
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
@ -2903,6 +2903,13 @@ dmu_buf_get_blkptr(dmu_buf_t *db)
return (dbi->db_blkptr); return (dbi->db_blkptr);
} }
objset_t *
dmu_buf_get_objset(dmu_buf_t *db)
{
dmu_buf_impl_t *dbi = (dmu_buf_impl_t *)db;
return (dbi->db_objset);
}
static void static void
dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db) dbuf_check_blkptr(dnode_t *dn, dmu_buf_impl_t *db)
{ {

View File

@ -21,7 +21,7 @@
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved. * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright 2013 DEY Storage Systems, Inc. * Copyright 2013 DEY Storage Systems, Inc.
@ -617,6 +617,8 @@ void *dmu_buf_remove_user(dmu_buf_t *db, dmu_buf_user_t *user);
*/ */
void *dmu_buf_get_user(dmu_buf_t *db); void *dmu_buf_get_user(dmu_buf_t *db);
objset_t *dmu_buf_get_objset(dmu_buf_t *db);
/* Block until any in-progress dmu buf user evictions complete. */ /* Block until any in-progress dmu buf user evictions complete. */
void dmu_buf_user_evict_wait(void); void dmu_buf_user_evict_wait(void);

View File

@ -20,7 +20,7 @@
*/ */
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright (c) 2013, 2016 by Delphix. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright (c) 2014 Integros [integros.com] * Copyright (c) 2014 Integros [integros.com]
*/ */
@ -197,8 +197,8 @@ typedef struct zap_name {
boolean_t zap_match(zap_name_t *zn, const char *matchname); boolean_t zap_match(zap_name_t *zn, const char *matchname);
int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp); krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp);
void zap_unlockdir(zap_t *zap); void zap_unlockdir(zap_t *zap, void *tag);
void zap_evict(void *dbu); void zap_evict(void *dbu);
zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt); zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt);
void zap_name_free(zap_name_t *zn); void zap_name_free(zap_name_t *zn);
@ -217,9 +217,10 @@ void fzap_prefetch(zap_name_t *zn);
int fzap_count_write(zap_name_t *zn, int add, refcount_t *towrite, int fzap_count_write(zap_name_t *zn, int add, refcount_t *towrite,
refcount_t *tooverwrite); refcount_t *tooverwrite);
int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, int fzap_add(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx); const void *val, void *tag, dmu_tx_t *tx);
int fzap_update(zap_name_t *zn, int fzap_update(zap_name_t *zn,
int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); int integer_size, uint64_t num_integers, const void *val,
void *tag, dmu_tx_t *tx);
int fzap_length(zap_name_t *zn, int fzap_length(zap_name_t *zn,
uint64_t *integer_size, uint64_t *num_integers); uint64_t *integer_size, uint64_t *num_integers);
int fzap_remove(zap_name_t *zn, dmu_tx_t *tx); int fzap_remove(zap_name_t *zn, dmu_tx_t *tx);
@ -229,7 +230,7 @@ void zap_put_leaf(struct zap_leaf *l);
int fzap_add_cd(zap_name_t *zn, int fzap_add_cd(zap_name_t *zn,
uint64_t integer_size, uint64_t num_integers, uint64_t integer_size, uint64_t num_integers,
const void *val, uint32_t cd, dmu_tx_t *tx); const void *val, uint32_t cd, void *tag, dmu_tx_t *tx);
void fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags); void fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags);
int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn); int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn);

View File

@ -20,7 +20,7 @@
*/ */
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
*/ */
@ -596,7 +596,8 @@ zap_deref_leaf(zap_t *zap, uint64_t h, dmu_tx_t *tx, krw_t lt, zap_leaf_t **lp)
} }
static int static int
zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp) zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l,
void *tag, dmu_tx_t *tx, zap_leaf_t **lp)
{ {
zap_t *zap = zn->zn_zap; zap_t *zap = zn->zn_zap;
uint64_t hash = zn->zn_hash; uint64_t hash = zn->zn_hash;
@ -618,9 +619,9 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
uint64_t object = zap->zap_object; uint64_t object = zap->zap_object;
zap_put_leaf(l); zap_put_leaf(l);
zap_unlockdir(zap); zap_unlockdir(zap, tag);
err = zap_lockdir(os, object, tx, RW_WRITER, err = zap_lockdir(os, object, tx, RW_WRITER,
FALSE, FALSE, &zn->zn_zap); FALSE, FALSE, tag, &zn->zn_zap);
zap = zn->zn_zap; zap = zn->zn_zap;
if (err) if (err)
return (err); return (err);
@ -683,7 +684,8 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
} }
static void static void
zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx) zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l,
void *tag, dmu_tx_t *tx)
{ {
zap_t *zap = zn->zn_zap; zap_t *zap = zn->zn_zap;
int shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift; int shift = zap_f_phys(zap)->zap_ptrtbl.zt_shift;
@ -703,9 +705,9 @@ zap_put_leaf_maybe_grow_ptrtbl(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx)
objset_t *os = zap->zap_objset; objset_t *os = zap->zap_objset;
uint64_t zapobj = zap->zap_object; uint64_t zapobj = zap->zap_object;
zap_unlockdir(zap); zap_unlockdir(zap, tag);
err = zap_lockdir(os, zapobj, tx, err = zap_lockdir(os, zapobj, tx,
RW_WRITER, FALSE, FALSE, &zn->zn_zap); RW_WRITER, FALSE, FALSE, tag, &zn->zn_zap);
zap = zn->zn_zap; zap = zn->zn_zap;
if (err) if (err)
return; return;
@ -795,7 +797,7 @@ fzap_lookup(zap_name_t *zn,
int int
fzap_add_cd(zap_name_t *zn, fzap_add_cd(zap_name_t *zn,
uint64_t integer_size, uint64_t num_integers, uint64_t integer_size, uint64_t num_integers,
const void *val, uint32_t cd, dmu_tx_t *tx) const void *val, uint32_t cd, void *tag, dmu_tx_t *tx)
{ {
zap_leaf_t *l; zap_leaf_t *l;
int err; int err;
@ -824,7 +826,7 @@ fzap_add_cd(zap_name_t *zn,
if (err == 0) { if (err == 0) {
zap_increment_num_entries(zap, 1, tx); zap_increment_num_entries(zap, 1, tx);
} else if (err == EAGAIN) { } else if (err == EAGAIN) {
err = zap_expand_leaf(zn, l, tx, &l); err = zap_expand_leaf(zn, l, tag, tx, &l);
zap = zn->zn_zap; /* zap_expand_leaf() may change zap */ zap = zn->zn_zap; /* zap_expand_leaf() may change zap */
if (err == 0) if (err == 0)
goto retry; goto retry;
@ -832,26 +834,27 @@ fzap_add_cd(zap_name_t *zn,
out: out:
if (zap != NULL) if (zap != NULL)
zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx); zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
return (err); return (err);
} }
int int
fzap_add(zap_name_t *zn, fzap_add(zap_name_t *zn,
uint64_t integer_size, uint64_t num_integers, uint64_t integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx) const void *val, void *tag, dmu_tx_t *tx)
{ {
int err = fzap_check(zn, integer_size, num_integers); int err = fzap_check(zn, integer_size, num_integers);
if (err != 0) if (err != 0)
return (err); return (err);
return (fzap_add_cd(zn, integer_size, num_integers, return (fzap_add_cd(zn, integer_size, num_integers,
val, ZAP_NEED_CD, tx)); val, ZAP_NEED_CD, tag, tx));
} }
int int
fzap_update(zap_name_t *zn, fzap_update(zap_name_t *zn,
int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx) int integer_size, uint64_t num_integers, const void *val,
void *tag, dmu_tx_t *tx)
{ {
zap_leaf_t *l; zap_leaf_t *l;
int err, create; int err, create;
@ -881,14 +884,14 @@ fzap_update(zap_name_t *zn,
} }
if (err == EAGAIN) { if (err == EAGAIN) {
err = zap_expand_leaf(zn, l, tx, &l); err = zap_expand_leaf(zn, l, tag, tx, &l);
zap = zn->zn_zap; /* zap_expand_leaf() may change zap */ zap = zn->zn_zap; /* zap_expand_leaf() may change zap */
if (err == 0) if (err == 0)
goto retry; goto retry;
} }
if (zap != NULL) if (zap != NULL)
zap_put_leaf_maybe_grow_ptrtbl(zn, l, tx); zap_put_leaf_maybe_grow_ptrtbl(zn, l, tag, tx);
return (err); return (err);
} }

View File

@ -20,7 +20,7 @@
*/ */
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright (c) 2014 Integros [integros.com] * Copyright (c) 2014 Integros [integros.com]
*/ */
@ -43,7 +43,8 @@
extern inline mzap_phys_t *zap_m_phys(zap_t *zap); extern inline mzap_phys_t *zap_m_phys(zap_t *zap);
static int mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags); static int mzap_upgrade(zap_t **zapp,
void *tag, dmu_tx_t *tx, zap_flags_t flags);
uint64_t uint64_t
zap_getflags(zap_t *zap) zap_getflags(zap_t *zap)
@ -468,21 +469,19 @@ mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
return (winner); return (winner);
} }
int static int
zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, zap_lockdir_impl(dmu_buf_t *db, void *tag, dmu_tx_t *tx,
krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp) krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp)
{ {
zap_t *zap; zap_t *zap;
dmu_buf_t *db;
krw_t lt; krw_t lt;
int err;
ASSERT0(db->db_offset);
objset_t *os = dmu_buf_get_objset(db);
uint64_t obj = db->db_object;
*zapp = NULL; *zapp = NULL;
err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH);
if (err)
return (err);
#ifdef ZFS_DEBUG #ifdef ZFS_DEBUG
{ {
dmu_object_info_t doi; dmu_object_info_t doi;
@ -499,7 +498,6 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
* mzap_open() didn't like what it saw on-disk. * mzap_open() didn't like what it saw on-disk.
* Check for corruption! * Check for corruption!
*/ */
dmu_buf_rele(db, NULL);
return (SET_ERROR(EIO)); return (SET_ERROR(EIO));
} }
} }
@ -538,10 +536,12 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
dprintf("upgrading obj %llu: num_entries=%u\n", dprintf("upgrading obj %llu: num_entries=%u\n",
obj, zap->zap_m.zap_num_entries); obj, zap->zap_m.zap_num_entries);
*zapp = zap; *zapp = zap;
return (mzap_upgrade(zapp, tx, 0)); int err = mzap_upgrade(zapp, tag, tx, 0);
if (err != 0)
rw_exit(&zap->zap_rwlock);
return (err);
} }
err = dmu_object_set_blocksize(os, obj, newsz, 0, tx); VERIFY0(dmu_object_set_blocksize(os, obj, newsz, 0, tx));
ASSERT0(err);
zap->zap_m.zap_num_chunks = zap->zap_m.zap_num_chunks =
db->db_size / MZAP_ENT_LEN - 1; db->db_size / MZAP_ENT_LEN - 1;
} }
@ -550,15 +550,31 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
return (0); return (0);
} }
int
zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
krw_t lti, boolean_t fatreader, boolean_t adding, void *tag, zap_t **zapp)
{
dmu_buf_t *db;
int err;
err = dmu_buf_hold(os, obj, 0, tag, &db, DMU_READ_NO_PREFETCH);
if (err != 0)
return (err);
err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp);
if (err != 0)
dmu_buf_rele(db, tag);
return (err);
}
void void
zap_unlockdir(zap_t *zap) zap_unlockdir(zap_t *zap, void *tag)
{ {
rw_exit(&zap->zap_rwlock); rw_exit(&zap->zap_rwlock);
dmu_buf_rele(zap->zap_dbuf, NULL); dmu_buf_rele(zap->zap_dbuf, tag);
} }
static int static int
mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags) mzap_upgrade(zap_t **zapp, void *tag, dmu_tx_t *tx, zap_flags_t flags)
{ {
mzap_phys_t *mzp; mzap_phys_t *mzp;
int i, sz, nchunks; int i, sz, nchunks;
@ -596,7 +612,8 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
dprintf("adding %s=%llu\n", dprintf("adding %s=%llu\n",
mze->mze_name, mze->mze_value); mze->mze_name, mze->mze_value);
zn = zap_name_alloc(zap, mze->mze_name, MT_EXACT); zn = zap_name_alloc(zap, mze->mze_name, MT_EXACT);
err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd, tx); err = fzap_add_cd(zn, 8, 1, &mze->mze_value, mze->mze_cd,
tag, tx);
zap = zn->zn_zap; /* fzap_add_cd() may change zap */ zap = zn->zn_zap; /* fzap_add_cd() may change zap */
zap_name_free(zn); zap_name_free(zn);
if (err) if (err)
@ -635,9 +652,9 @@ mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
zap_t *zap; zap_t *zap;
/* Only fat zap supports flags; upgrade immediately. */ /* Only fat zap supports flags; upgrade immediately. */
VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER, VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
B_FALSE, B_FALSE, &zap)); B_FALSE, B_FALSE, FTAG, &zap));
VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags)); VERIFY3U(0, ==, mzap_upgrade(&zap, FTAG, tx, flags));
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
} }
} }
@ -732,7 +749,7 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
zap_t *zap; zap_t *zap;
int err; int err;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
@ -740,7 +757,7 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
} else { } else {
*count = zap->zap_m.zap_num_entries; *count = zap->zap_m.zap_num_entries;
} }
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -797,25 +814,19 @@ zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
num_integers, buf, MT_EXACT, NULL, 0, NULL)); num_integers, buf, MT_EXACT, NULL, 0, NULL));
} }
int static int
zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name, zap_lookup_impl(zap_t *zap, const char *name,
uint64_t integer_size, uint64_t num_integers, void *buf, uint64_t integer_size, uint64_t num_integers, void *buf,
matchtype_t mt, char *realname, int rn_len, matchtype_t mt, char *realname, int rn_len,
boolean_t *ncp) boolean_t *ncp)
{ {
zap_t *zap; int err = 0;
int err;
mzap_ent_t *mze; mzap_ent_t *mze;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap);
if (err)
return (err);
zn = zap_name_alloc(zap, name, mt); zn = zap_name_alloc(zap, name, mt);
if (zn == NULL) { if (zn == NULL)
zap_unlockdir(zap);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
}
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
err = fzap_lookup(zn, integer_size, num_integers, buf, err = fzap_lookup(zn, integer_size, num_integers, buf,
@ -842,7 +853,24 @@ zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
} }
} }
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); return (err);
}
int
zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
uint64_t integer_size, uint64_t num_integers, void *buf,
matchtype_t mt, char *realname, int rn_len,
boolean_t *ncp)
{
zap_t *zap;
int err;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err != 0)
return (err);
err = zap_lookup_impl(zap, name, integer_size,
num_integers, buf, mt, realname, rn_len, ncp);
zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -854,18 +882,18 @@ zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err; int err;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints); zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
fzap_prefetch(zn); fzap_prefetch(zn);
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -877,19 +905,19 @@ zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err; int err;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints); zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
err = fzap_lookup(zn, integer_size, num_integers, buf, err = fzap_lookup(zn, integer_size, num_integers, buf,
NULL, 0, NULL); NULL, 0, NULL);
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -912,12 +940,12 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
mzap_ent_t *mze; mzap_ent_t *mze;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc(zap, name, MT_EXACT); zn = zap_name_alloc(zap, name, MT_EXACT);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
@ -934,7 +962,7 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
} }
} }
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -946,17 +974,17 @@ zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err; int err;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints); zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
err = fzap_length(zn, integer_size, num_integers); err = fzap_length(zn, integer_size, num_integers);
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1015,22 +1043,24 @@ zap_add(objset_t *os, uint64_t zapobj, const char *key,
const uint64_t *intval = val; const uint64_t *intval = val;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc(zap, key, MT_EXACT); zn = zap_name_alloc(zap, key, MT_EXACT);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
err = fzap_add(zn, integer_size, num_integers, val, tx); err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx);
zap = zn->zn_zap; /* fzap_add() may change zap */ zap = zn->zn_zap; /* fzap_add() may change zap */
} else if (integer_size != 8 || num_integers != 1 || } else if (integer_size != 8 || num_integers != 1 ||
strlen(key) >= MZAP_NAME_LEN) { strlen(key) >= MZAP_NAME_LEN) {
err = mzap_upgrade(&zn->zn_zap, tx, 0); err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
if (err == 0) if (err == 0) {
err = fzap_add(zn, integer_size, num_integers, val, tx); err = fzap_add(zn, integer_size, num_integers, val,
FTAG, tx);
}
zap = zn->zn_zap; /* fzap_add() may change zap */ zap = zn->zn_zap; /* fzap_add() may change zap */
} else { } else {
mze = mze_find(zn); mze = mze_find(zn);
@ -1043,7 +1073,7 @@ zap_add(objset_t *os, uint64_t zapobj, const char *key,
ASSERT(zap == zn->zn_zap); ASSERT(zap == zn->zn_zap);
zap_name_free(zn); zap_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_add() failed */ if (zap != NULL) /* may be NULL if fzap_add() failed */
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1056,19 +1086,19 @@ zap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err; int err;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints); zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
err = fzap_add(zn, integer_size, num_integers, val, tx); err = fzap_add(zn, integer_size, num_integers, val, FTAG, tx);
zap = zn->zn_zap; /* fzap_add() may change zap */ zap = zn->zn_zap; /* fzap_add() may change zap */
zap_name_free(zn); zap_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_add() failed */ if (zap != NULL) /* may be NULL if fzap_add() failed */
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1092,25 +1122,27 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
(void) zap_lookup(os, zapobj, name, 8, 1, &oldval); (void) zap_lookup(os, zapobj, name, 8, 1, &oldval);
#endif #endif
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc(zap, name, MT_EXACT); zn = zap_name_alloc(zap, name, MT_EXACT);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
err = fzap_update(zn, integer_size, num_integers, val, tx); err = fzap_update(zn, integer_size, num_integers, val,
FTAG, tx);
zap = zn->zn_zap; /* fzap_update() may change zap */ zap = zn->zn_zap; /* fzap_update() may change zap */
} else if (integer_size != 8 || num_integers != 1 || } else if (integer_size != 8 || num_integers != 1 ||
strlen(name) >= MZAP_NAME_LEN) { strlen(name) >= MZAP_NAME_LEN) {
dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n", dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
zapobj, integer_size, num_integers, name); zapobj, integer_size, num_integers, name);
err = mzap_upgrade(&zn->zn_zap, tx, 0); err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
if (err == 0) if (err == 0) {
err = fzap_update(zn, integer_size, num_integers, err = fzap_update(zn, integer_size, num_integers,
val, tx); val, FTAG, tx);
}
zap = zn->zn_zap; /* fzap_update() may change zap */ zap = zn->zn_zap; /* fzap_update() may change zap */
} else { } else {
mze = mze_find(zn); mze = mze_find(zn);
@ -1124,7 +1156,7 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
ASSERT(zap == zn->zn_zap); ASSERT(zap == zn->zn_zap);
zap_name_free(zn); zap_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_upgrade() failed */ if (zap != NULL) /* may be NULL if fzap_upgrade() failed */
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1137,19 +1169,19 @@ zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
zap_name_t *zn; zap_name_t *zn;
int err; int err;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, &zap); err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints); zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
err = fzap_update(zn, integer_size, num_integers, val, tx); err = fzap_update(zn, integer_size, num_integers, val, FTAG, tx);
zap = zn->zn_zap; /* fzap_update() may change zap */ zap = zn->zn_zap; /* fzap_update() may change zap */
zap_name_free(zn); zap_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_upgrade() failed */ if (zap != NULL) /* may be NULL if fzap_upgrade() failed */
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1168,12 +1200,12 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
mzap_ent_t *mze; mzap_ent_t *mze;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc(zap, name, mt); zn = zap_name_alloc(zap, name, mt);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
@ -1190,7 +1222,7 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
} }
} }
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1202,17 +1234,17 @@ zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err; int err;
zap_name_t *zn; zap_name_t *zn;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints); zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) { if (zn == NULL) {
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
} }
err = fzap_remove(zn, tx); err = fzap_remove(zn, tx);
zap_name_free(zn); zap_name_free(zn);
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1244,7 +1276,7 @@ zap_cursor_fini(zap_cursor_t *zc)
{ {
if (zc->zc_zap) { if (zc->zc_zap) {
rw_enter(&zc->zc_zap->zap_rwlock, RW_READER); rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
zap_unlockdir(zc->zc_zap); zap_unlockdir(zc->zc_zap, NULL);
zc->zc_zap = NULL; zc->zc_zap = NULL;
} }
if (zc->zc_leaf) { if (zc->zc_leaf) {
@ -1291,7 +1323,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
if (zc->zc_zap == NULL) { if (zc->zc_zap == NULL) {
int hb; int hb;
err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL, err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
RW_READER, TRUE, FALSE, &zc->zc_zap); RW_READER, TRUE, FALSE, NULL, &zc->zc_zap);
if (err) if (err)
return (err); return (err);
@ -1395,7 +1427,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
int err; int err;
zap_t *zap; zap_t *zap;
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, FTAG, &zap);
if (err) if (err)
return (err); return (err);
@ -1408,7 +1440,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
} else { } else {
fzap_get_stats(zap, zs); fzap_get_stats(zap, zs);
} }
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (0); return (0);
} }
@ -1427,7 +1459,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
* - 2 blocks for possibly split leaves, * - 2 blocks for possibly split leaves,
* - 2 grown ptrtbl blocks * - 2 grown ptrtbl blocks
* *
* This also accomodates the case where an add operation to a fairly * This also accommodates the case where an add operation to a fairly
* large microzap results in a promotion to fatzap. * large microzap results in a promotion to fatzap.
*/ */
if (name == NULL) { if (name == NULL) {
@ -1440,10 +1472,11 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
* We lock the zap with adding == FALSE. Because, if we pass * We lock the zap with adding == FALSE. Because, if we pass
* the actual value of add, it could trigger a mzap_upgrade(). * the actual value of add, it could trigger a mzap_upgrade().
* At present we are just evaluating the possibility of this operation * At present we are just evaluating the possibility of this operation
* and hence we donot want to trigger an upgrade. * and hence we do not want to trigger an upgrade.
*/ */
err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE, &zap); err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE,
if (err) FTAG, &zap);
if (err != 0)
return (err); return (err);
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
@ -1489,6 +1522,6 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
} }
} }
zap_unlockdir(zap); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }