/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright 2017 Nexenta Systems, Inc.
*/
return (winner);
}
+/*
+ * This routine "consumes" the caller's hold on the dbuf, which must
+ * have the specified tag.
+ */
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)
if (err != 0) {
return (err);
}
+#ifdef ZFS_DEBUG
+ {
+ dmu_object_info_t doi;
+ dmu_object_info_from_db(db, &doi);
+ ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
+ }
+#endif
+
err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp);
if (err != 0) {
dmu_buf_rele(db, tag);
int err = dmu_buf_hold(os, obj, 0, tag, &db, DMU_READ_NO_PREFETCH);
if (err != 0)
return (err);
+#ifdef ZFS_DEBUG
+ {
+ dmu_object_info_t doi;
+ dmu_object_info_from_db(db, &doi);
+ ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
+ }
+#endif
err = zap_lockdir_impl(db, tag, tx, lti, fatreader, adding, zapp);
if (err != 0)
dmu_buf_rele(db, tag);
* of them may be supplied.
*/
void
-mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
- dmu_tx_t *tx)
+mzap_create_impl(dnode_t *dn, int normflags, zap_flags_t flags, dmu_tx_t *tx)
{
dmu_buf_t *db;
- VERIFY0(dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
-
-#ifdef ZFS_DEBUG
- {
- dmu_object_info_t doi;
- dmu_object_info_from_db(db, &doi);
- ASSERT3U(DMU_OT_BYTESWAP(doi.doi_type), ==, DMU_BSWAP_ZAP);
- }
-#endif
+ VERIFY0(dmu_buf_hold_by_dnode(dn, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
dmu_buf_will_dirty(db, tx);
mzap_phys_t *zp = db->db_data;
zp->mz_block_type = ZBT_MICRO;
- zp->mz_salt = ((uintptr_t)db ^ (uintptr_t)tx ^ (obj << 1)) | 1ULL;
+ zp->mz_salt =
+ ((uintptr_t)db ^ (uintptr_t)tx ^ (dn->dn_object << 1)) | 1ULL;
zp->mz_normflags = normflags;
- dmu_buf_rele(db, FTAG);
if (flags != 0) {
zap_t *zap;
/* Only fat zap supports flags; upgrade immediately. */
- VERIFY(0 == zap_lockdir(os, obj, tx, RW_WRITER,
- B_FALSE, B_FALSE, FTAG, &zap));
+ VERIFY0(zap_lockdir_impl(db, FTAG, tx, RW_WRITER,
+ B_FALSE, B_FALSE, &zap));
VERIFY0(mzap_upgrade(&zap, FTAG, tx, flags));
zap_unlockdir(zap, FTAG);
+ } else {
+ dmu_buf_rele(db, FTAG);
}
}
+static uint64_t
+zap_create_impl(objset_t *os, int normflags, zap_flags_t flags,
+ dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
+ dmu_object_type_t bonustype, int bonuslen, int dnodesize,
+ dnode_t **allocated_dnode, void *tag, dmu_tx_t *tx)
+{
+ uint64_t obj;
+
+ ASSERT3U(DMU_OT_BYTESWAP(ot), ==, DMU_BSWAP_ZAP);
+
+ if (allocated_dnode == NULL) {
+ dnode_t *dn;
+ obj = dmu_object_alloc_hold(os, ot, 1ULL << leaf_blockshift,
+ indirect_blockshift, bonustype, bonuslen, dnodesize,
+ &dn, FTAG, tx);
+ mzap_create_impl(dn, normflags, flags, tx);
+ dnode_rele(dn, FTAG);
+ } else {
+ obj = dmu_object_alloc_hold(os, ot, 1ULL << leaf_blockshift,
+ indirect_blockshift, bonustype, bonuslen, dnodesize,
+ allocated_dnode, tag, tx);
+ mzap_create_impl(*allocated_dnode, normflags, flags, tx);
+ }
+
+ return (obj);
+}
+
int
zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot,
dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx)
dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen,
int dnodesize, dmu_tx_t *tx)
{
- int err = dmu_object_claim_dnsize(os, obj, ot, 0, bonustype, bonuslen,
+ dnode_t *dn;
+ int error;
+
+ ASSERT3U(DMU_OT_BYTESWAP(ot), ==, DMU_BSWAP_ZAP);
+ error = dmu_object_claim_dnsize(os, obj, ot, 0, bonustype, bonuslen,
dnodesize, tx);
- if (err != 0)
- return (err);
- mzap_create_impl(os, obj, normflags, 0, tx);
+ if (error != 0)
+ return (error);
+
+ error = dnode_hold(os, obj, FTAG, &dn);
+ if (error != 0)
+ return (error);
+
+ mzap_create_impl(dn, normflags, 0, tx);
+
+ dnode_rele(dn, FTAG);
+
return (0);
}
zap_create_norm_dnsize(objset_t *os, int normflags, dmu_object_type_t ot,
dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx)
{
- uint64_t obj = dmu_object_alloc_dnsize(os, ot, 0, bonustype, bonuslen,
- dnodesize, tx);
-
- mzap_create_impl(os, obj, normflags, 0, tx);
- return (obj);
+ return (zap_create_impl(os, normflags, 0, ot, 0, 0,
+ bonustype, bonuslen, dnodesize, NULL, NULL, tx));
}
uint64_t
dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx)
{
- uint64_t obj = dmu_object_alloc_dnsize(os, ot, 0, bonustype, bonuslen,
- dnodesize, tx);
-
- ASSERT(leaf_blockshift >= SPA_MINBLOCKSHIFT &&
- leaf_blockshift <= SPA_OLD_MAXBLOCKSHIFT &&
- indirect_blockshift >= SPA_MINBLOCKSHIFT &&
- indirect_blockshift <= SPA_OLD_MAXBLOCKSHIFT);
-
- VERIFY(dmu_object_set_blocksize(os, obj,
- 1ULL << leaf_blockshift, indirect_blockshift, tx) == 0);
+ return (zap_create_impl(os, normflags, flags, ot, leaf_blockshift,
+ indirect_blockshift, bonustype, bonuslen, dnodesize, NULL, NULL,
+ tx));
+}
- mzap_create_impl(os, obj, normflags, flags, tx);
- return (obj);
+/*
+ * Create a zap object and return a pointer to the newly allocated dnode via
+ * the allocated_dnode argument. The returned dnode will be held and the
+ * caller is responsible for releasing the hold by calling dnode_rele().
+ */
+uint64_t
+zap_create_hold(objset_t *os, int normflags, zap_flags_t flags,
+ dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift,
+ dmu_object_type_t bonustype, int bonuslen, int dnodesize,
+ dnode_t **allocated_dnode, void *tag, dmu_tx_t *tx)
+{
+ return (zap_create_impl(os, normflags, flags, ot, leaf_blockshift,
+ indirect_blockshift, bonustype, bonuslen, dnodesize,
+ allocated_dnode, tag, tx));
}
int
int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx)
{
zap_t *zap;
- ASSERTV(uint64_t oldval);
const uint64_t *intval = val;
-#ifdef ZFS_DEBUG
-
- /*
- * If there is an old value, it shouldn't change across the
- * lockdir (eg, due to bprewrite's xlation).
- */
- if (integer_size == 8 && num_integers == 1)
- (void) zap_lookup(os, zapobj, name, 8, 1, &oldval);
-#endif
-
int err =
zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err != 0)
} else {
mzap_ent_t *mze = mze_find(zn);
if (mze != NULL) {
- ASSERT3U(MZE_PHYS(zap, mze)->mze_value, ==, oldval);
MZE_PHYS(zap, mze)->mze_value = *intval;
} else {
mzap_addent(zn, *intval);
EXPORT_SYMBOL(zap_create_claim);
EXPORT_SYMBOL(zap_create_claim_norm);
EXPORT_SYMBOL(zap_create_claim_norm_dnsize);
+EXPORT_SYMBOL(zap_create_hold);
EXPORT_SYMBOL(zap_destroy);
EXPORT_SYMBOL(zap_lookup);
EXPORT_SYMBOL(zap_lookup_by_dnode);