Skip to content

Commit

Permalink
Add dmu_write_abd
Browse files Browse the repository at this point in the history
Add ABD version of dmu_write, which takes ABD as input buffer, to get rid of
some buffer borrowing.

Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
  • Loading branch information
Chunwei Chen committed May 13, 2016
1 parent f72997f commit 374fb74
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 13 deletions.
2 changes: 2 additions & 0 deletions include/sys/dmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ int dmu_read(objset_t *os, uint64_t object, 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_abd(objset_t *os, uint64_t object, uint64_t offset,
uint64_t size, abd_t *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
52 changes: 44 additions & 8 deletions module/zfs/dmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,49 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
dmu_buf_rele_array(dbp, numbufs, FTAG);
}

void
dmu_write_abd(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
abd_t *sabd, dmu_tx_t *tx)
{
dmu_buf_t **dbp;
int numbufs, i;
uint64_t soff = 0;

if (size == 0)
return;

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

for (i = 0; i < numbufs; i++) {
uint64_t tocpy;
int64_t dboff;
dmu_buf_t *db = dbp[i];

ASSERT(size > 0);

dboff = offset - db->db_offset;
tocpy = MIN(db->db_size - dboff, size);

ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size);

if (tocpy == db->db_size)
dmu_buf_will_fill(db, tx);
else
dmu_buf_will_dirty(db, tx);

abd_copy_off(db->db_data, sabd, tocpy, dboff, soff);

if (tocpy == db->db_size)
dmu_buf_fill_done(db, tx);

offset += tocpy;
size -= tocpy;
soff += tocpy;
}
dmu_buf_rele_array(dbp, numbufs, FTAG);
}

void
dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
dmu_tx_t *tx)
Expand Down Expand Up @@ -1482,7 +1525,6 @@ dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, arc_buf_t *buf,
} else {
objset_t *os;
uint64_t object;
void *tmp_buf;

DB_DNODE_ENTER(dbuf);
dn = DB_DNODE(dbuf);
Expand All @@ -1491,13 +1533,7 @@ dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, arc_buf_t *buf,
DB_DNODE_EXIT(dbuf);

dbuf_rele(db, FTAG);

tmp_buf = abd_borrow_buf_copy(buf->b_data, blksz);

dmu_write(os, object, offset, blksz, tmp_buf, tx);

abd_return_buf(buf->b_data, tmp_buf, blksz);

dmu_write_abd(os, object, offset, blksz, buf->b_data, tx);
dmu_return_arcbuf(buf);
XUIOSTAT_BUMP(xuiostat_wbuf_copied);
}
Expand Down
7 changes: 2 additions & 5 deletions module/zfs/dmu_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,7 +1705,6 @@ restore_write_byref(struct restorearg *ra, objset_t *os,
avl_index_t where;
objset_t *ref_os = NULL;
dmu_buf_t *dbp;
void *buf;

if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset)
return (SET_ERROR(EINVAL));
Expand Down Expand Up @@ -1740,10 +1739,8 @@ restore_write_byref(struct restorearg *ra, objset_t *os,
dmu_tx_abort(tx);
return (err);
}
buf = abd_borrow_buf_copy(dbp->db_data, drrwbr->drr_length);
dmu_write(os, drrwbr->drr_object,
drrwbr->drr_offset, drrwbr->drr_length, buf, tx);
abd_return_buf(dbp->db_data, buf, drrwbr->drr_length);
dmu_write_abd(os, drrwbr->drr_object,
drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
dmu_buf_rele(dbp, FTAG);
dmu_tx_commit(tx);
return (0);
Expand Down

0 comments on commit 374fb74

Please sign in to comment.