summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2014-10-23 01:40:31 +0000
committerdelphij <delphij@FreeBSD.org>2014-10-23 01:40:31 +0000
commit7b171ea87602a17ebabc9fbbc823d2cfc32fb352 (patch)
tree1444c015beaaa223417e5980f11f15f67990ec3f /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
parent5295b89f11504e9cbe8d652778ee5fae7528fd72 (diff)
downloadFreeBSD-src-7b171ea87602a17ebabc9fbbc823d2cfc32fb352.zip
FreeBSD-src-7b171ea87602a17ebabc9fbbc823d2cfc32fb352.tar.gz
MFC r272809: MFV r272803:
Illumos issue: 5175 implement dmu_read_uio_dbuf() to improve cached read performance
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
index 8b04fdd..9b7f526 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
@@ -1022,8 +1022,8 @@ xuio_stat_wbuf_nocopy()
}
#ifdef _KERNEL
-int
-dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size)
+static int
+dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size)
{
dmu_buf_t **dbp;
int numbufs, i, err;
@@ -1033,8 +1033,8 @@ dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size)
* 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, uio->uio_loffset, size, TRUE, FTAG,
- &numbufs, &dbp);
+ err = dmu_buf_hold_array_by_dnode(dn, uio->uio_loffset, size,
+ TRUE, FTAG, &numbufs, &dbp, 0);
if (err)
return (err);
@@ -1081,6 +1081,58 @@ dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size)
return (err);
}
+/*
+ * Read 'size' bytes into the uio buffer.
+ * From object zdb->db_object.
+ * Starting at offset uio->uio_loffset.
+ *
+ * If the caller already has a dbuf in the target object
+ * (e.g. its bonus buffer), this routine is faster than dmu_read_uio(),
+ * because we don't have to find the dnode_t for the object.
+ */
+int
+dmu_read_uio_dbuf(dmu_buf_t *zdb, uio_t *uio, uint64_t size)
+{
+ dmu_buf_impl_t *db = (dmu_buf_impl_t *)zdb;
+ dnode_t *dn;
+ int err;
+
+ if (size == 0)
+ return (0);
+
+ DB_DNODE_ENTER(db);
+ dn = DB_DNODE(db);
+ err = dmu_read_uio_dnode(dn, uio, size);
+ DB_DNODE_EXIT(db);
+
+ return (err);
+}
+
+/*
+ * Read 'size' bytes into the uio buffer.
+ * From the specified object
+ * Starting at offset uio->uio_loffset.
+ */
+int
+dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size)
+{
+ dnode_t *dn;
+ int err;
+
+ if (size == 0)
+ return (0);
+
+ err = dnode_hold(os, object, FTAG, &dn);
+ if (err)
+ return (err);
+
+ err = dmu_read_uio_dnode(dn, uio, size);
+
+ dnode_rele(dn, FTAG);
+
+ return (err);
+}
+
static int
dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx)
{
@@ -1133,6 +1185,15 @@ dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx)
return (err);
}
+/*
+ * Write 'size' bytes from the uio buffer.
+ * To object zdb->db_object.
+ * Starting at offset uio->uio_loffset.
+ *
+ * If the caller already has a dbuf in the target object
+ * (e.g. its bonus buffer), this routine is faster than dmu_write_uio(),
+ * because we don't have to find the dnode_t for the object.
+ */
int
dmu_write_uio_dbuf(dmu_buf_t *zdb, uio_t *uio, uint64_t size,
dmu_tx_t *tx)
@@ -1152,6 +1213,11 @@ dmu_write_uio_dbuf(dmu_buf_t *zdb, uio_t *uio, uint64_t size,
return (err);
}
+/*
+ * Write 'size' bytes from the uio buffer.
+ * To the specified object.
+ * Starting at offset uio->uio_loffset.
+ */
int
dmu_write_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size,
dmu_tx_t *tx)
OpenPOWER on IntegriCloud