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 authored and tuxoko committed Sep 24, 2016
1 parent 062f54f commit 44fb2b0
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
Expand Up @@ -732,6 +732,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
Expand Up @@ -920,6 +920,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 @@ -1377,7 +1420,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;

/* compressed bufs must always be assignable to their dbuf */
ASSERT3U(arc_get_compression(buf), ==, ZIO_COMPRESS_OFF);
Expand All @@ -1390,13 +1432,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
Expand Up @@ -2309,7 +2309,6 @@ receive_write_byref(struct receive_writer_arg *rwa,
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 @@ -2344,10 +2343,8 @@ receive_write_byref(struct receive_writer_arg *rwa,
dmu_tx_abort(tx);
return (err);
}
buf = abd_borrow_buf_copy(dbp->db_data, drrwbr->drr_length);
dmu_write(rwa->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(rwa->os, drrwbr->drr_object,
drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
dmu_buf_rele(dbp, FTAG);

/* See comment in restore_write. */
Expand Down

0 comments on commit 44fb2b0

Please sign in to comment.