summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2016-10-14 07:35:43 +0000
committermav <mav@FreeBSD.org>2016-10-14 07:35:43 +0000
commit9d79919eb31d7b8124ebe1aaae900b0258ae67e1 (patch)
tree25ba6e8248864a7c2b65b036ac0e0e1ce0b1d277 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
parentd3c986dd741a3a45c2b672fab1e2ed924d6ee6b1 (diff)
downloadFreeBSD-src-9d79919eb31d7b8124ebe1aaae900b0258ae67e1.zip
FreeBSD-src-9d79919eb31d7b8124ebe1aaae900b0258ae67e1.tar.gz
MFC r305338: 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@0780b3eab5a2c13e04328b39ecd2a6d0d3c4f7cb
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c198
1 files changed, 116 insertions, 82 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
index fbd7e02..1634b62 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
@@ -20,7 +20,7 @@
*/
/*
* 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 Integros [integros.com]
*/
@@ -43,7 +43,8 @@
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
zap_getflags(zap_t *zap)
@@ -459,20 +460,18 @@ mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
return (zap);
}
-int
-zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
+static int
+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)
{
zap_t *zap;
- dmu_buf_t *db;
krw_t lt;
- int err;
- *zapp = NULL;
+ ASSERT0(db->db_offset);
+ objset_t *os = dmu_buf_get_objset(db);
+ uint64_t obj = db->db_object;
- err = dmu_buf_hold(os, obj, 0, NULL, &db, DMU_READ_NO_PREFETCH);
- if (err)
- return (err);
+ *zapp = NULL;
#ifdef ZFS_DEBUG
{
@@ -520,10 +519,12 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
dprintf("upgrading obj %llu: num_entries=%u\n",
obj, zap->zap_m.zap_num_entries);
*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);
- ASSERT0(err);
+ VERIFY0(dmu_object_set_blocksize(os, obj, newsz, 0, tx));
zap->zap_m.zap_num_chunks =
db->db_size / MZAP_ENT_LEN - 1;
}
@@ -532,15 +533,31 @@ zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
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
-zap_unlockdir(zap_t *zap)
+zap_unlockdir(zap_t *zap, void *tag)
{
rw_exit(&zap->zap_rwlock);
- dmu_buf_rele(zap->zap_dbuf, NULL);
+ dmu_buf_rele(zap->zap_dbuf, tag);
}
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;
int i, sz, nchunks;
@@ -578,7 +595,8 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, zap_flags_t flags)
dprintf("adding %s=%llu\n",
mze->mze_name, mze->mze_value);
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_name_free(zn);
if (err)
@@ -617,9 +635,9 @@ mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
zap_t *zap;
/* Only fat zap supports flags; upgrade immediately. */
VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
- B_FALSE, B_FALSE, &zap));
- VERIFY3U(0, ==, mzap_upgrade(&zap, tx, flags));
- zap_unlockdir(zap);
+ B_FALSE, B_FALSE, FTAG, &zap));
+ VERIFY3U(0, ==, mzap_upgrade(&zap, FTAG, tx, flags));
+ zap_unlockdir(zap, FTAG);
}
}
@@ -714,7 +732,7 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
zap_t *zap;
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)
return (err);
if (!zap->zap_ismicro) {
@@ -722,7 +740,7 @@ zap_count(objset_t *os, uint64_t zapobj, uint64_t *count)
} else {
*count = zap->zap_m.zap_num_entries;
}
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -779,25 +797,19 @@ zap_lookup(objset_t *os, uint64_t zapobj, const char *name,
num_integers, buf, MT_EXACT, NULL, 0, NULL));
}
-int
-zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
+static int
+zap_lookup_impl(zap_t *zap, 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;
+ int err = 0;
mzap_ent_t *mze;
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);
- if (zn == NULL) {
- zap_unlockdir(zap);
+ if (zn == NULL)
return (SET_ERROR(ENOTSUP));
- }
if (!zap->zap_ismicro) {
err = fzap_lookup(zn, integer_size, num_integers, buf,
@@ -824,7 +836,24 @@ zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name,
}
}
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);
}
@@ -836,18 +865,18 @@ zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err;
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)
return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
fzap_prefetch(zn);
zap_name_free(zn);
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -859,19 +888,19 @@ zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err;
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)
return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
err = fzap_lookup(zn, integer_size, num_integers, buf,
NULL, 0, NULL);
zap_name_free(zn);
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -894,12 +923,12 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
mzap_ent_t *mze;
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)
return (err);
zn = zap_name_alloc(zap, name, MT_EXACT);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
if (!zap->zap_ismicro) {
@@ -916,7 +945,7 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name,
}
}
zap_name_free(zn);
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -928,17 +957,17 @@ zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err;
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)
return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
err = fzap_length(zn, integer_size, num_integers);
zap_name_free(zn);
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -997,22 +1026,24 @@ zap_add(objset_t *os, uint64_t zapobj, const char *key,
const uint64_t *intval = val;
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)
return (err);
zn = zap_name_alloc(zap, key, MT_EXACT);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
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 */
} else if (integer_size != 8 || num_integers != 1 ||
strlen(key) >= MZAP_NAME_LEN) {
- err = mzap_upgrade(&zn->zn_zap, tx, 0);
- if (err == 0)
- err = fzap_add(zn, integer_size, num_integers, val, tx);
+ err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
+ if (err == 0) {
+ err = fzap_add(zn, integer_size, num_integers, val,
+ FTAG, tx);
+ }
zap = zn->zn_zap; /* fzap_add() may change zap */
} else {
mze = mze_find(zn);
@@ -1025,7 +1056,7 @@ zap_add(objset_t *os, uint64_t zapobj, const char *key,
ASSERT(zap == zn->zn_zap);
zap_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_add() failed */
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -1038,19 +1069,19 @@ zap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err;
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)
return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
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_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_add() failed */
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -1074,25 +1105,27 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
(void) zap_lookup(os, zapobj, name, 8, 1, &oldval);
#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)
return (err);
zn = zap_name_alloc(zap, name, MT_EXACT);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
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 */
} else if (integer_size != 8 || num_integers != 1 ||
strlen(name) >= MZAP_NAME_LEN) {
dprintf("upgrading obj %llu: intsz=%u numint=%llu name=%s\n",
zapobj, integer_size, num_integers, name);
- err = mzap_upgrade(&zn->zn_zap, tx, 0);
- if (err == 0)
+ err = mzap_upgrade(&zn->zn_zap, FTAG, tx, 0);
+ if (err == 0) {
err = fzap_update(zn, integer_size, num_integers,
- val, tx);
+ val, FTAG, tx);
+ }
zap = zn->zn_zap; /* fzap_update() may change zap */
} else {
mze = mze_find(zn);
@@ -1106,7 +1139,7 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name,
ASSERT(zap == zn->zn_zap);
zap_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_upgrade() failed */
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -1119,19 +1152,19 @@ zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
zap_name_t *zn;
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)
return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
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_name_free(zn);
if (zap != NULL) /* may be NULL if fzap_upgrade() failed */
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -1150,12 +1183,12 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
mzap_ent_t *mze;
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)
return (err);
zn = zap_name_alloc(zap, name, mt);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
if (!zap->zap_ismicro) {
@@ -1172,7 +1205,7 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
}
}
zap_name_free(zn);
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -1184,17 +1217,17 @@ zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int err;
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)
return (err);
zn = zap_name_alloc_uint64(zap, key, key_numints);
if (zn == NULL) {
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (SET_ERROR(ENOTSUP));
}
err = fzap_remove(zn, tx);
zap_name_free(zn);
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
@@ -1226,7 +1259,7 @@ zap_cursor_fini(zap_cursor_t *zc)
{
if (zc->zc_zap) {
rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
- zap_unlockdir(zc->zc_zap);
+ zap_unlockdir(zc->zc_zap, NULL);
zc->zc_zap = NULL;
}
if (zc->zc_leaf) {
@@ -1273,7 +1306,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
if (zc->zc_zap == NULL) {
int hb;
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)
return (err);
@@ -1377,7 +1410,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
int err;
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)
return (err);
@@ -1390,7 +1423,7 @@ zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
} else {
fzap_get_stats(zap, zs);
}
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (0);
}
@@ -1409,7 +1442,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
* - 2 blocks for possibly split leaves,
* - 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.
*/
if (name == NULL) {
@@ -1422,10 +1455,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
* 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 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);
- if (err)
+ err = zap_lockdir(os, zapobj, NULL, RW_READER, TRUE, FALSE,
+ FTAG, &zap);
+ if (err != 0)
return (err);
if (!zap->zap_ismicro) {
@@ -1471,6 +1505,6 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add,
}
}
- zap_unlockdir(zap);
+ zap_unlockdir(zap, FTAG);
return (err);
}
OpenPOWER on IntegriCloud