Skip to content

Commit

Permalink
by-dnode methods let the caller save on dnode#->dnode_t lookup and im…
Browse files Browse the repository at this point in the history
…prove performance (especially multithread metadata ops)
  • Loading branch information
Alex Zhuravlev authored and Alex Zhuravlev committed Jan 9, 2017
1 parent 42b64e5 commit 1af2daa
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 69 deletions.
11 changes: 11 additions & 0 deletions include/sys/dmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,10 +674,17 @@ boolean_t dmu_buf_freeable(dmu_buf_t *);

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_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,
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_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_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_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);
Expand Down Expand Up @@ -727,8 +734,12 @@ int dmu_free_long_object(objset_t *os, uint64_t object);
#define DMU_READ_NO_PREFETCH 1 /* don't prefetch */
int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
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,
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,
dmu_tx_t *tx);
#ifdef _KERNEL
Expand Down
2 changes: 1 addition & 1 deletion include/sys/dmu_tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
int dmu_tx_is_syncing(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_dirty_buf(dmu_tx_t *tx, struct dmu_buf_impl *db);
int dmu_tx_holds(dmu_tx_t *tx, uint64_t object);
Expand Down
4 changes: 4 additions & 0 deletions include/sys/zap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 integer_size, uint64_t num_integers,
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 key_numints, int integer_size, uint64_t num_integers,
const void *val, dmu_tx_t *tx);
Expand Down Expand Up @@ -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_norm(objset_t *ds, uint64_t zapobj, const char *name,
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 key_numints, dmu_tx_t *tx);

Expand Down
77 changes: 62 additions & 15 deletions module/zfs/dmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -823,17 +823,12 @@ dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
}

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)
{
dnode_t *dn;
dmu_buf_t **dbp;
int numbufs, err;

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
* block. If we ever do the tail block optimization, we will need to
Expand Down Expand Up @@ -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);
}
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);
return (err);
}

int
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));
}

void
dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
dmu_write_impl(dmu_buf_t **dbp, int numbufs, uint64_t offset, uint64_t size,
const void *buf, dmu_tx_t *tx)
{
dmu_buf_t **dbp;
int numbufs, i;

if (size == 0)
return;

VERIFY0(dmu_buf_hold_array(os, object, offset, size,
FALSE, FTAG, &numbufs, &dbp));
int i;

for (i = 0; i < numbufs; i++) {
uint64_t tocpy;
Expand Down Expand Up @@ -920,6 +930,41 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
size -= 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);
}

Expand Down Expand Up @@ -2102,7 +2147,9 @@ EXPORT_SYMBOL(dmu_free_range);
EXPORT_SYMBOL(dmu_free_long_range);
EXPORT_SYMBOL(dmu_free_long_object);
EXPORT_SYMBOL(dmu_read);
EXPORT_SYMBOL(dmu_read_by_dnode);
EXPORT_SYMBOL(dmu_write);
EXPORT_SYMBOL(dmu_write_by_dnode);
EXPORT_SYMBOL(dmu_prealloc);
EXPORT_SYMBOL(dmu_object_info);
EXPORT_SYMBOL(dmu_object_info_from_dnode);
Expand Down
9 changes: 5 additions & 4 deletions module/zfs/dmu_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_rele(dn, FTAG);

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);
}

Expand Down Expand Up @@ -168,9 +168,10 @@ dmu_object_claim_dnsize(objset_t *os, uint64_t object, dmu_object_type_t ot,
return (err);

dnode_allocate(dn, ot, blocksize, 0, bonustype, bonuslen, dn_slots, tx);
dmu_tx_add_new_object(tx, os, dn);

dnode_rele(dn, FTAG);

dmu_tx_add_new_object(tx, os, object);
return (0);
}

Expand Down
Loading

0 comments on commit 1af2daa

Please sign in to comment.