diff options
author | Chunwei Chen <[email protected]> | 2015-12-08 12:37:24 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-12-15 16:21:43 -0800 |
commit | 2727b9d3b63a938c1797d31378e6a5a1dcd43573 (patch) | |
tree | f85bd88b0ab3c09fecf27f39af6e736f8ae20815 /module/zfs/dmu.c | |
parent | 502923bb447cdf4f9bc1271a46dfc11d5e0f2e9b (diff) |
Use uio for zvol_{read,write}
Since uio now supports bvec, we can convert bio into uio and reuse
dmu_{read,write}_uio. This way, we can remove some duplicate code.
Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #4078
Diffstat (limited to 'module/zfs/dmu.c')
-rw-r--r-- | module/zfs/dmu.c | 164 |
1 files changed, 0 insertions, 164 deletions
diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index 5e2a1db60..f4027af9c 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -1041,170 +1041,6 @@ xuio_stat_wbuf_nocopy() } #ifdef _KERNEL - -/* - * Copy up to size bytes between arg_buf and req based on the data direction - * described by the req. If an entire req's data cannot be transfered in one - * pass, you should pass in @req_offset to indicate where to continue. The - * return value is the number of bytes successfully copied to arg_buf. - */ -static int -dmu_bio_copy(void *arg_buf, int size, struct bio *bio, size_t bio_offset) -{ - struct bio_vec bv, *bvp = &bv; - bvec_iterator_t iter; - char *bv_buf; - int tocpy, bv_len, bv_offset; - int offset = 0; - - bio_for_each_segment4(bv, bvp, bio, iter) { - - /* - * Fully consumed the passed arg_buf. We use goto here because - * rq_for_each_segment is a double loop - */ - ASSERT3S(offset, <=, size); - if (size == offset) - goto out; - - /* Skip already copied bvp */ - if (bio_offset >= bvp->bv_len) { - bio_offset -= bvp->bv_len; - continue; - } - - bv_len = bvp->bv_len - bio_offset; - bv_offset = bvp->bv_offset + bio_offset; - bio_offset = 0; - - tocpy = MIN(bv_len, size - offset); - ASSERT3S(tocpy, >=, 0); - - bv_buf = page_address(bvp->bv_page) + bv_offset; - ASSERT3P(bv_buf, !=, NULL); - - if (bio_data_dir(bio) == WRITE) - memcpy(arg_buf + offset, bv_buf, tocpy); - else - memcpy(bv_buf, arg_buf + offset, tocpy); - - offset += tocpy; - } -out: - return (offset); -} - -int -dmu_read_bio(objset_t *os, uint64_t object, struct bio *bio) -{ - uint64_t offset = BIO_BI_SECTOR(bio) << 9; - uint64_t size = BIO_BI_SIZE(bio); - dmu_buf_t **dbp; - int numbufs, i, err; - size_t bio_offset; - - /* - * NB: we could do this block-at-a-time, but it's nice - * to be reading in parallel. - */ - err = dmu_buf_hold_array(os, object, offset, size, TRUE, FTAG, - &numbufs, &dbp); - if (err) - return (err); - - bio_offset = 0; - for (i = 0; i < numbufs; i++) { - uint64_t tocpy; - int64_t bufoff; - int didcpy; - dmu_buf_t *db = dbp[i]; - - bufoff = offset - db->db_offset; - ASSERT3S(bufoff, >=, 0); - - tocpy = MIN(db->db_size - bufoff, size); - if (tocpy == 0) - break; - - didcpy = dmu_bio_copy(db->db_data + bufoff, tocpy, bio, - bio_offset); - - if (didcpy < tocpy) - err = EIO; - - if (err) - break; - - size -= tocpy; - offset += didcpy; - bio_offset += didcpy; - err = 0; - } - dmu_buf_rele_array(dbp, numbufs, FTAG); - - return (err); -} - -int -dmu_write_bio(objset_t *os, uint64_t object, struct bio *bio, dmu_tx_t *tx) -{ - uint64_t offset = BIO_BI_SECTOR(bio) << 9; - uint64_t size = BIO_BI_SIZE(bio); - dmu_buf_t **dbp; - int numbufs, i, err; - size_t bio_offset; - - if (size == 0) - return (0); - - err = dmu_buf_hold_array(os, object, offset, size, FALSE, FTAG, - &numbufs, &dbp); - if (err) - return (err); - - bio_offset = 0; - for (i = 0; i < numbufs; i++) { - uint64_t tocpy; - int64_t bufoff; - int didcpy; - dmu_buf_t *db = dbp[i]; - - bufoff = offset - db->db_offset; - ASSERT3S(bufoff, >=, 0); - - tocpy = MIN(db->db_size - bufoff, size); - if (tocpy == 0) - break; - - 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); - - didcpy = dmu_bio_copy(db->db_data + bufoff, tocpy, bio, - bio_offset); - - if (tocpy == db->db_size) - dmu_buf_fill_done(db, tx); - - if (didcpy < tocpy) - err = EIO; - - if (err) - break; - - size -= tocpy; - offset += didcpy; - bio_offset += didcpy; - err = 0; - } - - dmu_buf_rele_array(dbp, numbufs, FTAG); - return (err); -} - static int dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size) { |