Add *_by-dnode routines

Add *_by_dnode() routines for accessing objects given their
dnode_t *, this is more efficient than accessing the object by 
(objset_t *, uint64_t object).  This change converts some but
not all of the existing consumers.  As performance-sensitive
code paths are discovered they should be converted to use
these routines.

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alex Zhuravlev <bzzz@whamcloud.com>
Closes #5534 
Issue #4802
This commit is contained in:
bzzz77 2017-01-14 01:58:41 +03:00 committed by Brian Behlendorf
parent 38640550f2
commit 0eef1bde31
7 changed files with 276 additions and 76 deletions

View File

@ -674,10 +674,17 @@ boolean_t dmu_buf_freeable(dmu_buf_t *);
dmu_tx_t *dmu_tx_create(objset_t *os); dmu_tx_t *dmu_tx_create(objset_t *os);
void dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len); void dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len);
void dmu_tx_hold_write_by_dnode(dmu_tx_t *tx, dnode_t *dn, uint64_t off,
int len);
void dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, void dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off,
uint64_t len); uint64_t len);
void dmu_tx_hold_free_by_dnode(dmu_tx_t *tx, dnode_t *dn, uint64_t off,
uint64_t len);
void dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name); void dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name);
void dmu_tx_hold_zap_by_dnode(dmu_tx_t *tx, dnode_t *dn, int add,
const char *name);
void dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object); void dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object);
void dmu_tx_hold_bonus_by_dnode(dmu_tx_t *tx, dnode_t *dn);
void dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object); void dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object);
void dmu_tx_hold_sa(dmu_tx_t *tx, struct sa_handle *hdl, boolean_t may_grow); void dmu_tx_hold_sa(dmu_tx_t *tx, struct sa_handle *hdl, boolean_t may_grow);
void dmu_tx_hold_sa_create(dmu_tx_t *tx, int total_size); void dmu_tx_hold_sa_create(dmu_tx_t *tx, int total_size);
@ -727,8 +734,12 @@ int dmu_free_long_object(objset_t *os, uint64_t object);
#define DMU_READ_NO_PREFETCH 1 /* don't prefetch */ #define DMU_READ_NO_PREFETCH 1 /* don't prefetch */
int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
void *buf, uint32_t flags); void *buf, uint32_t flags);
int dmu_read_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size, void *buf,
uint32_t flags);
void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx); const void *buf, dmu_tx_t *tx);
void dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx);
void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
dmu_tx_t *tx); dmu_tx_t *tx);
#ifdef _KERNEL #ifdef _KERNEL

View File

@ -171,7 +171,7 @@ extern dmu_tx_t *dmu_tx_create_assigned(struct dsl_pool *dp, uint64_t txg);
dmu_tx_t *dmu_tx_create_dd(dsl_dir_t *dd); dmu_tx_t *dmu_tx_create_dd(dsl_dir_t *dd);
int dmu_tx_is_syncing(dmu_tx_t *tx); int dmu_tx_is_syncing(dmu_tx_t *tx);
int dmu_tx_private_ok(dmu_tx_t *tx); int dmu_tx_private_ok(dmu_tx_t *tx);
void dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object); void dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, dnode_t *dn);
void dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta); void dmu_tx_willuse_space(dmu_tx_t *tx, int64_t delta);
void dmu_tx_dirty_buf(dmu_tx_t *tx, struct dmu_buf_impl *db); void dmu_tx_dirty_buf(dmu_tx_t *tx, struct dmu_buf_impl *db);
int dmu_tx_holds(dmu_tx_t *tx, uint64_t object); int dmu_tx_holds(dmu_tx_t *tx, uint64_t object);

View File

@ -255,6 +255,9 @@ int zap_count_write_by_dnode(dnode_t *dn, const char *name,
int zap_add(objset_t *ds, uint64_t zapobj, const char *key, int zap_add(objset_t *ds, uint64_t zapobj, const char *key,
int integer_size, uint64_t num_integers, int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx); const void *val, dmu_tx_t *tx);
int zap_add_by_dnode(dnode_t *dn, const char *key,
int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx);
int zap_add_uint64(objset_t *ds, uint64_t zapobj, const uint64_t *key, int zap_add_uint64(objset_t *ds, uint64_t zapobj, const uint64_t *key,
int key_numints, int integer_size, uint64_t num_integers, int key_numints, int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx); const void *val, dmu_tx_t *tx);
@ -294,6 +297,7 @@ int zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int zap_remove(objset_t *ds, uint64_t zapobj, const char *name, dmu_tx_t *tx); int zap_remove(objset_t *ds, uint64_t zapobj, const char *name, dmu_tx_t *tx);
int zap_remove_norm(objset_t *ds, uint64_t zapobj, const char *name, int zap_remove_norm(objset_t *ds, uint64_t zapobj, const char *name,
matchtype_t mt, dmu_tx_t *tx); matchtype_t mt, dmu_tx_t *tx);
int zap_remove_by_dnode(dnode_t *dn, const char *name, dmu_tx_t *tx);
int zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
int key_numints, dmu_tx_t *tx); int key_numints, dmu_tx_t *tx);

View File

@ -822,17 +822,12 @@ dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
return (0); return (0);
} }
int static int
dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_read_impl(dnode_t *dn, uint64_t offset, uint64_t size,
void *buf, uint32_t flags) void *buf, uint32_t flags)
{ {
dnode_t *dn;
dmu_buf_t **dbp; dmu_buf_t **dbp;
int numbufs, err; int numbufs, err = 0;
err = dnode_hold(os, object, FTAG, &dn);
if (err)
return (err);
/* /*
* Deal with odd block sizes, where there can't be data past the first * Deal with odd block sizes, where there can't be data past the first
@ -877,22 +872,37 @@ dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
} }
dmu_buf_rele_array(dbp, numbufs, FTAG); dmu_buf_rele_array(dbp, numbufs, FTAG);
} }
return (err);
}
int
dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
void *buf, uint32_t flags)
{
dnode_t *dn;
int err;
err = dnode_hold(os, object, FTAG, &dn);
if (err != 0)
return (err);
err = dmu_read_impl(dn, offset, size, buf, flags);
dnode_rele(dn, FTAG); dnode_rele(dn, FTAG);
return (err); return (err);
} }
void int
dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_read_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size, void *buf,
uint32_t flags)
{
return (dmu_read_impl(dn, offset, size, buf, flags));
}
static void
dmu_write_impl(dmu_buf_t **dbp, int numbufs, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx) const void *buf, dmu_tx_t *tx)
{ {
dmu_buf_t **dbp; int i;
int numbufs, i;
if (size == 0)
return;
VERIFY0(dmu_buf_hold_array(os, object, offset, size,
FALSE, FTAG, &numbufs, &dbp));
for (i = 0; i < numbufs; i++) { for (i = 0; i < numbufs; i++) {
uint64_t tocpy; uint64_t tocpy;
@ -920,6 +930,37 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
size -= tocpy; size -= tocpy;
buf = (char *)buf + tocpy; buf = (char *)buf + tocpy;
} }
}
void
dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx)
{
dmu_buf_t **dbp;
int numbufs;
if (size == 0)
return;
VERIFY0(dmu_buf_hold_array(os, object, offset, size,
FALSE, FTAG, &numbufs, &dbp));
dmu_write_impl(dbp, numbufs, offset, size, buf, tx);
dmu_buf_rele_array(dbp, numbufs, FTAG);
}
void
dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx)
{
dmu_buf_t **dbp;
int numbufs;
if (size == 0)
return;
VERIFY0(dmu_buf_hold_array_by_dnode(dn, offset, size,
FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH));
dmu_write_impl(dbp, numbufs, offset, size, buf, tx);
dmu_buf_rele_array(dbp, numbufs, FTAG); dmu_buf_rele_array(dbp, numbufs, FTAG);
} }
@ -2102,7 +2143,9 @@ EXPORT_SYMBOL(dmu_free_range);
EXPORT_SYMBOL(dmu_free_long_range); EXPORT_SYMBOL(dmu_free_long_range);
EXPORT_SYMBOL(dmu_free_long_object); EXPORT_SYMBOL(dmu_free_long_object);
EXPORT_SYMBOL(dmu_read); EXPORT_SYMBOL(dmu_read);
EXPORT_SYMBOL(dmu_read_by_dnode);
EXPORT_SYMBOL(dmu_write); EXPORT_SYMBOL(dmu_write);
EXPORT_SYMBOL(dmu_write_by_dnode);
EXPORT_SYMBOL(dmu_prealloc); EXPORT_SYMBOL(dmu_prealloc);
EXPORT_SYMBOL(dmu_object_info); EXPORT_SYMBOL(dmu_object_info);
EXPORT_SYMBOL(dmu_object_info_from_dnode); EXPORT_SYMBOL(dmu_object_info_from_dnode);

View File

@ -129,11 +129,11 @@ dmu_object_alloc_dnsize(objset_t *os, dmu_object_type_t ot, int blocksize,
} }
dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, dn_slots, tx); dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, dn_slots, tx);
dnode_rele(dn, FTAG);
mutex_exit(&os->os_obj_lock); mutex_exit(&os->os_obj_lock);
dmu_tx_add_new_object(tx, os, object); dmu_tx_add_new_object(tx, os, dn);
dnode_rele(dn, FTAG);
return (object); return (object);
} }
@ -168,9 +168,10 @@ dmu_object_claim_dnsize(objset_t *os, uint64_t object, dmu_object_type_t ot,
return (err); return (err);
dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, dn_slots, tx); dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, dn_slots, tx);
dmu_tx_add_new_object(tx, os, dn);
dnode_rele(dn, FTAG); dnode_rele(dn, FTAG);
dmu_tx_add_new_object(tx, os, object);
return (0); return (0);
} }

View File

@ -113,21 +113,14 @@ dmu_tx_private_ok(dmu_tx_t *tx)
} }
static dmu_tx_hold_t * static dmu_tx_hold_t *
dmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object, dmu_tx_hold_dnode_impl(dmu_tx_t *tx, dnode_t *dn, enum dmu_tx_hold_type type,
enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2) uint64_t arg1, uint64_t arg2)
{ {
dmu_tx_hold_t *txh; dmu_tx_hold_t *txh;
dnode_t *dn = NULL;
int err;
if (object != DMU_NEW_OBJECT) { if (dn != NULL) {
err = dnode_hold(os, object, tx, &dn); refcount_add(&dn->dn_holds, tx);
if (err) { if (tx->tx_txg != 0) {
tx->tx_err = err;
return (NULL);
}
if (err == 0 && tx->tx_txg != 0) {
mutex_enter(&dn->dn_mtx); mutex_enter(&dn->dn_mtx);
/* /*
* dn->dn_assigned_txg == tx->tx_txg doesn't pose a * dn->dn_assigned_txg == tx->tx_txg doesn't pose a
@ -154,17 +147,36 @@ dmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object,
return (txh); return (txh);
} }
static dmu_tx_hold_t *
dmu_tx_hold_object_impl(dmu_tx_t *tx, objset_t *os, uint64_t object,
enum dmu_tx_hold_type type, uint64_t arg1, uint64_t arg2)
{
dnode_t *dn = NULL;
dmu_tx_hold_t *txh;
int err;
if (object != DMU_NEW_OBJECT) {
err = dnode_hold(os, object, FTAG, &dn);
if (err) {
tx->tx_err = err;
return (NULL);
}
}
txh = dmu_tx_hold_dnode_impl(tx, dn, type, arg1, arg2);
if (dn != NULL)
dnode_rele(dn, FTAG);
return (txh);
}
void void
dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, uint64_t object) dmu_tx_add_new_object(dmu_tx_t *tx, objset_t *os, dnode_t *dn)
{ {
/* /*
* If we're syncing, they can manipulate any object anyhow, and * If we're syncing, they can manipulate any object anyhow, and
* the hold on the dnode_t can cause problems. * the hold on the dnode_t can cause problems.
*/ */
if (!dmu_tx_is_syncing(tx)) { if (!dmu_tx_is_syncing(tx))
(void) dmu_tx_hold_object_impl(tx, os, (void) dmu_tx_hold_dnode_impl(tx, dn, THT_NEWOBJECT, 0, 0);
object, THT_NEWOBJECT, 0, 0);
}
} }
static int static int
@ -441,6 +453,23 @@ dmu_tx_hold_write(dmu_tx_t *tx, uint64_t object, uint64_t off, int len)
dmu_tx_count_dnode(txh); dmu_tx_count_dnode(txh);
} }
void
dmu_tx_hold_write_by_dnode(dmu_tx_t *tx, dnode_t *dn, uint64_t off, int len)
{
dmu_tx_hold_t *txh;
ASSERT(tx->tx_txg == 0);
ASSERT(len <= DMU_MAX_ACCESS);
ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
txh = dmu_tx_hold_dnode_impl(tx, dn, THT_WRITE, off, len);
if (txh == NULL)
return;
dmu_tx_count_write(txh, off, len);
dmu_tx_count_dnode(txh);
}
static void static void
dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
{ {
@ -636,20 +665,17 @@ dmu_tx_mark_netfree(dmu_tx_t *tx)
txh->txh_space_tofree = txh->txh_space_tounref = 1024 * 1024 * 1024; txh->txh_space_tofree = txh->txh_space_tounref = 1024 * 1024 * 1024;
} }
void static void
dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len) dmu_tx_hold_free_impl(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
{ {
dmu_tx_hold_t *txh; dmu_tx_t *tx;
dnode_t *dn; dnode_t *dn;
int err; int err;
zio_t *zio; zio_t *zio;
tx = txh->txh_tx;
ASSERT(tx->tx_txg == 0); ASSERT(tx->tx_txg == 0);
txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
object, THT_FREE, off, len);
if (txh == NULL)
return;
dn = txh->txh_dnode; dn = txh->txh_dnode;
dmu_tx_count_dnode(txh); dmu_tx_count_dnode(txh);
@ -731,9 +757,32 @@ dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
} }
void void
dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name) dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
{ {
dmu_tx_hold_t *txh; dmu_tx_hold_t *txh;
txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
object, THT_FREE, off, len);
if (txh == NULL)
return;
(void) dmu_tx_hold_free_impl(txh, off, len);
}
void
dmu_tx_hold_free_by_dnode(dmu_tx_t *tx, dnode_t *dn, uint64_t off, uint64_t len)
{
dmu_tx_hold_t *txh;
txh = dmu_tx_hold_dnode_impl(tx, dn, THT_FREE, off, len);
if (txh == NULL)
return;
(void) dmu_tx_hold_free_impl(txh, off, len);
}
static void
dmu_tx_hold_zap_impl(dmu_tx_hold_t *txh, int add, const char *name)
{
dmu_tx_t *tx = txh->txh_tx;
dnode_t *dn; dnode_t *dn;
dsl_dataset_phys_t *ds_phys; dsl_dataset_phys_t *ds_phys;
uint64_t nblocks; uint64_t nblocks;
@ -741,10 +790,6 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name)
ASSERT(tx->tx_txg == 0); ASSERT(tx->tx_txg == 0);
txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
object, THT_ZAP, add, (uintptr_t)name);
if (txh == NULL)
return;
dn = txh->txh_dnode; dn = txh->txh_dnode;
dmu_tx_count_dnode(txh); dmu_tx_count_dnode(txh);
@ -817,6 +862,34 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name)
txh->txh_space_tooverwrite += 3 << dn->dn_indblkshift; txh->txh_space_tooverwrite += 3 << dn->dn_indblkshift;
} }
void
dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name)
{
dmu_tx_hold_t *txh;
ASSERT(tx->tx_txg == 0);
txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
object, THT_ZAP, add, (uintptr_t)name);
if (txh == NULL)
return;
dmu_tx_hold_zap_impl(txh, add, name);
}
void
dmu_tx_hold_zap_by_dnode(dmu_tx_t *tx, dnode_t *dn, int add, const char *name)
{
dmu_tx_hold_t *txh;
ASSERT(tx->tx_txg == 0);
ASSERT(dn != NULL);
txh = dmu_tx_hold_dnode_impl(tx, dn, THT_ZAP, add, (uintptr_t)name);
if (txh == NULL)
return;
dmu_tx_hold_zap_impl(txh, add, name);
}
void void
dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object) dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
{ {
@ -830,6 +903,18 @@ dmu_tx_hold_bonus(dmu_tx_t *tx, uint64_t object)
dmu_tx_count_dnode(txh); dmu_tx_count_dnode(txh);
} }
void
dmu_tx_hold_bonus_by_dnode(dmu_tx_t *tx, dnode_t *dn)
{
dmu_tx_hold_t *txh;
ASSERT(tx->tx_txg == 0);
txh = dmu_tx_hold_dnode_impl(tx, dn, THT_BONUS, 0, 0);
if (txh)
dmu_tx_count_dnode(txh);
}
void void
dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space) dmu_tx_hold_space(dmu_tx_t *tx, uint64_t space)
{ {
@ -1704,9 +1789,13 @@ dmu_tx_fini(void)
#if defined(_KERNEL) && defined(HAVE_SPL) #if defined(_KERNEL) && defined(HAVE_SPL)
EXPORT_SYMBOL(dmu_tx_create); EXPORT_SYMBOL(dmu_tx_create);
EXPORT_SYMBOL(dmu_tx_hold_write); EXPORT_SYMBOL(dmu_tx_hold_write);
EXPORT_SYMBOL(dmu_tx_hold_write_by_dnode);
EXPORT_SYMBOL(dmu_tx_hold_free); EXPORT_SYMBOL(dmu_tx_hold_free);
EXPORT_SYMBOL(dmu_tx_hold_free_by_dnode);
EXPORT_SYMBOL(dmu_tx_hold_zap); EXPORT_SYMBOL(dmu_tx_hold_zap);
EXPORT_SYMBOL(dmu_tx_hold_zap_by_dnode);
EXPORT_SYMBOL(dmu_tx_hold_bonus); EXPORT_SYMBOL(dmu_tx_hold_bonus);
EXPORT_SYMBOL(dmu_tx_hold_bonus_by_dnode);
EXPORT_SYMBOL(dmu_tx_abort); EXPORT_SYMBOL(dmu_tx_abort);
EXPORT_SYMBOL(dmu_tx_assign); EXPORT_SYMBOL(dmu_tx_assign);
EXPORT_SYMBOL(dmu_tx_wait); EXPORT_SYMBOL(dmu_tx_wait);

View File

@ -1128,34 +1128,30 @@ again:
cmn_err(CE_PANIC, "out of entries!"); cmn_err(CE_PANIC, "out of entries!");
} }
int static int
zap_add(objset_t *os, uint64_t zapobj, const char *key, zap_add_impl(zap_t *zap, const char *key,
int integer_size, uint64_t num_integers, int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx) const void *val, dmu_tx_t *tx, void *tag)
{ {
zap_t *zap; int err = 0;
int err;
mzap_ent_t *mze; mzap_ent_t *mze;
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, FTAG, &zap);
if (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, FTAG); zap_unlockdir(zap, tag);
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, FTAG, tx); err = fzap_add(zn, integer_size, num_integers, val, tag, 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, FTAG, tx, 0); err = mzap_upgrade(&zn->zn_zap, tag, tx, 0);
if (err == 0) { if (err == 0) {
err = fzap_add(zn, integer_size, num_integers, val, err = fzap_add(zn, integer_size, num_integers, val,
FTAG, tx); tag, tx);
} }
zap = zn->zn_zap; /* fzap_add() may change zap */ zap = zn->zn_zap; /* fzap_add() may change zap */
} else { } else {
@ -1168,8 +1164,39 @@ 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 */ zap_unlockdir(zap, tag);
zap_unlockdir(zap, FTAG); return (err);
}
int
zap_add(objset_t *os, uint64_t zapobj, const char *key,
int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx)
{
zap_t *zap;
int err;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err != 0)
return (err);
err = zap_add_impl(zap, key, integer_size, num_integers, val, tx, FTAG);
/* zap_add_impl() calls zap_unlockdir() */
return (err);
}
int
zap_add_by_dnode(dnode_t *dn, const char *key,
int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx)
{
zap_t *zap;
int err;
err = zap_lockdir_by_dnode(dn, tx, RW_WRITER, TRUE, TRUE, FTAG, &zap);
if (err != 0)
return (err);
err = zap_add_impl(zap, key, integer_size, num_integers, val, tx, FTAG);
/* zap_add_impl() calls zap_unlockdir() */
return (err); return (err);
} }
@ -1288,23 +1315,17 @@ zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
return (zap_remove_norm(os, zapobj, name, MT_EXACT, tx)); return (zap_remove_norm(os, zapobj, name, MT_EXACT, tx));
} }
int static int
zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name, zap_remove_impl(zap_t *zap, const char *name,
matchtype_t mt, dmu_tx_t *tx) matchtype_t mt, dmu_tx_t *tx)
{ {
zap_t *zap;
int err;
mzap_ent_t *mze; mzap_ent_t *mze;
zap_name_t *zn; zap_name_t *zn;
int err = 0;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &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, FTAG);
return (SET_ERROR(ENOTSUP)); return (SET_ERROR(ENOTSUP));
}
if (!zap->zap_ismicro) { if (!zap->zap_ismicro) {
err = fzap_remove(zn, tx); err = fzap_remove(zn, tx);
} else { } else {
@ -1319,6 +1340,34 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
} }
} }
zap_name_free(zn); zap_name_free(zn);
return (err);
}
int
zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name,
matchtype_t mt, dmu_tx_t *tx)
{
zap_t *zap;
int err;
err = zap_lockdir(os, zapobj, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
if (err)
return (err);
err = zap_remove_impl(zap, name, mt, tx);
zap_unlockdir(zap, FTAG);
return (err);
}
int
zap_remove_by_dnode(dnode_t *dn, const char *name, dmu_tx_t *tx)
{
zap_t *zap;
int err;
err = zap_lockdir_by_dnode(dn, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap);
if (err)
return (err);
err = zap_remove_impl(zap, name, MT_EXACT, tx);
zap_unlockdir(zap, FTAG); zap_unlockdir(zap, FTAG);
return (err); return (err);
} }
@ -1589,6 +1638,7 @@ EXPORT_SYMBOL(zap_create_claim_norm);
EXPORT_SYMBOL(zap_create_claim_norm_dnsize); EXPORT_SYMBOL(zap_create_claim_norm_dnsize);
EXPORT_SYMBOL(zap_destroy); EXPORT_SYMBOL(zap_destroy);
EXPORT_SYMBOL(zap_lookup); EXPORT_SYMBOL(zap_lookup);
EXPORT_SYMBOL(zap_lookup_by_dnode);
EXPORT_SYMBOL(zap_lookup_norm); EXPORT_SYMBOL(zap_lookup_norm);
EXPORT_SYMBOL(zap_lookup_uint64); EXPORT_SYMBOL(zap_lookup_uint64);
EXPORT_SYMBOL(zap_contains); EXPORT_SYMBOL(zap_contains);
@ -1596,12 +1646,14 @@ EXPORT_SYMBOL(zap_prefetch);
EXPORT_SYMBOL(zap_prefetch_uint64); EXPORT_SYMBOL(zap_prefetch_uint64);
EXPORT_SYMBOL(zap_count_write_by_dnode); EXPORT_SYMBOL(zap_count_write_by_dnode);
EXPORT_SYMBOL(zap_add); EXPORT_SYMBOL(zap_add);
EXPORT_SYMBOL(zap_add_by_dnode);
EXPORT_SYMBOL(zap_add_uint64); EXPORT_SYMBOL(zap_add_uint64);
EXPORT_SYMBOL(zap_update); EXPORT_SYMBOL(zap_update);
EXPORT_SYMBOL(zap_update_uint64); EXPORT_SYMBOL(zap_update_uint64);
EXPORT_SYMBOL(zap_length); EXPORT_SYMBOL(zap_length);
EXPORT_SYMBOL(zap_length_uint64); EXPORT_SYMBOL(zap_length_uint64);
EXPORT_SYMBOL(zap_remove); EXPORT_SYMBOL(zap_remove);
EXPORT_SYMBOL(zap_remove_by_dnode);
EXPORT_SYMBOL(zap_remove_norm); EXPORT_SYMBOL(zap_remove_norm);
EXPORT_SYMBOL(zap_remove_uint64); EXPORT_SYMBOL(zap_remove_uint64);
EXPORT_SYMBOL(zap_count); EXPORT_SYMBOL(zap_count);