diff --git a/zfs/lib/libzpool/dmu.c b/zfs/lib/libzpool/dmu.c index 79ea277bbf..1033540c53 100644 --- a/zfs/lib/libzpool/dmu.c +++ b/zfs/lib/libzpool/dmu.c @@ -539,8 +539,8 @@ 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, - void *buf) +dmu_read_impl(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + void *buf, int flags) { dnode_t *dn; dmu_buf_t **dbp; @@ -584,7 +584,8 @@ dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, bufoff = offset - db->db_offset; tocpy = (int)MIN(db->db_size - bufoff, size); - bcopy((char *)db->db_data + bufoff, buf, tocpy); + if (!(flags & DMU_READ_ZEROCOPY)) + bcopy((char *)db->db_data + bufoff, buf, tocpy); offset += tocpy; size -= tocpy; @@ -596,9 +597,16 @@ dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, return (err); } +int +dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + void *buf) +{ + return dmu_read_impl(os, object, offset, size, buf, 0); +} + void -dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, - const void *buf, dmu_tx_t *tx) +dmu_write_impl(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + const void *buf, dmu_tx_t *tx, int flags) { dmu_buf_t **dbp; int numbufs, i; @@ -626,7 +634,8 @@ dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, else dmu_buf_will_dirty(db, tx); - bcopy(buf, (char *)db->db_data + bufoff, tocpy); + if (!(flags & DMU_WRITE_ZEROCOPY)) + bcopy(buf, (char *)db->db_data + bufoff, tocpy); if (tocpy == db->db_size) dmu_buf_fill_done(db, tx); @@ -659,7 +668,14 @@ dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_buf_rele_array(dbp, numbufs, FTAG); } -#ifdef _KERNEL +void +dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + const void *buf, dmu_tx_t *tx) +{ + dmu_write_impl(os, object, offset, size, buf, tx, 0); +} + +#if defined(_KERNEL) && defined(HAVE_UIO_RW) int dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size) { @@ -1229,7 +1245,9 @@ dmu_fini(void) #if defined(_KERNEL) && defined(HAVE_SPL) EXPORT_SYMBOL(dmu_bonus_hold); EXPORT_SYMBOL(dmu_free_range); +EXPORT_SYMBOL(dmu_read_impl); EXPORT_SYMBOL(dmu_read); +EXPORT_SYMBOL(dmu_write_impl); EXPORT_SYMBOL(dmu_write); /* Get information on a DMU object. */ diff --git a/zfs/lib/libzpool/include/sys/dmu.h b/zfs/lib/libzpool/include/sys/dmu.h index e4bcdfbe03..15da305d78 100644 --- a/zfs/lib/libzpool/include/sys/dmu.h +++ b/zfs/lib/libzpool/include/sys/dmu.h @@ -154,8 +154,10 @@ void zfs_znode_byteswap(void *buf, size_t size); * The maximum number of bytes that can be accessed as part of one * operation, including metadata. */ -#define DMU_MAX_ACCESS (10<<20) /* 10MB */ -#define DMU_MAX_DELETEBLKCNT (20480) /* ~5MB of indirect blocks */ +#define DMU_MAX_ACCESS (10<<20) /* 10MB */ +#define DMU_MAX_DELETEBLKCNT (20480) /* ~5MB of indirect blocks */ +#define DMU_WRITE_ZEROCOPY 0x0001 +#define DMU_READ_ZEROCOPY 0x0002 /* * Public routines to create, destroy, open, and close objsets. @@ -472,17 +474,23 @@ int dmu_free_object(objset_t *os, uint64_t object); * Canfail routines will return 0 on success, or an errno if there is a * nonrecoverable I/O error. */ +int dmu_read_impl(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + void *buf, int flags); int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, void *buf); +void dmu_write_impl(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, + const void *buf, dmu_tx_t *tx, int 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_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, dmu_tx_t *tx); +#if defined(_KERNEL) && defined(HAVE_UIO_RW) int dmu_read_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size); int dmu_write_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size, dmu_tx_t *tx); int dmu_write_pages(objset_t *os, uint64_t object, uint64_t offset, uint64_t size, struct page *pp, dmu_tx_t *tx); +#endif extern int zfs_prefetch_disable;