mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-24 16:10:11 +00:00
5175 implement dmu_read_uio_dbuf() to improve cached read performance
Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Alex Reece <alex.reece@delphix.com> Reviewed by: George Wilson <george@delphix.com> Reviewed by: Richard Elling <richard.elling@gmail.com> Approved by: Robert Mustacchi <rm@joyent.com> Author: Matthew Ahrens <mahrens@delphix.com> illumos/illumos-gate@f8554bb92b
This commit is contained in:
parent
def3a5442c
commit
578cf1706c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor-sys/illumos/dist/; revision=272803
@ -1015,8 +1015,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;
|
||||
@ -1026,8 +1026,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);
|
||||
|
||||
@ -1072,6 +1072,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)
|
||||
{
|
||||
@ -1124,6 +1176,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)
|
||||
@ -1143,6 +1204,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)
|
||||
|
@ -614,6 +614,7 @@ void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
|
||||
void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
|
||||
dmu_tx_t *tx);
|
||||
int dmu_read_uio(objset_t *os, uint64_t object, struct uio *uio, uint64_t size);
|
||||
int dmu_read_uio_dbuf(dmu_buf_t *zdb, 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_uio_dbuf(dmu_buf_t *zdb, struct uio *uio, uint64_t size,
|
||||
|
@ -406,7 +406,6 @@ static int
|
||||
mappedread(vnode_t *vp, int nbytes, uio_t *uio)
|
||||
{
|
||||
znode_t *zp = VTOZ(vp);
|
||||
objset_t *os = zp->z_zfsvfs->z_os;
|
||||
int64_t start, off;
|
||||
int len = nbytes;
|
||||
int error = 0;
|
||||
@ -425,7 +424,8 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio)
|
||||
zfs_unmap_page(pp, va);
|
||||
page_unlock(pp);
|
||||
} else {
|
||||
error = dmu_read_uio(os, zp->z_id, uio, bytes);
|
||||
error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
|
||||
uio, bytes);
|
||||
}
|
||||
len -= bytes;
|
||||
off = 0;
|
||||
@ -460,7 +460,6 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
|
||||
{
|
||||
znode_t *zp = VTOZ(vp);
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
objset_t *os;
|
||||
ssize_t n, nbytes;
|
||||
int error = 0;
|
||||
rl_t *rl;
|
||||
@ -468,7 +467,6 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
|
||||
|
||||
ZFS_ENTER(zfsvfs);
|
||||
ZFS_VERIFY_ZP(zp);
|
||||
os = zfsvfs->z_os;
|
||||
|
||||
if (zp->z_pflags & ZFS_AV_QUARANTINED) {
|
||||
ZFS_EXIT(zfsvfs);
|
||||
@ -558,10 +556,12 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
|
||||
nbytes = MIN(n, zfs_read_chunk_size -
|
||||
P2PHASE(uio->uio_loffset, zfs_read_chunk_size));
|
||||
|
||||
if (vn_has_cached_data(vp))
|
||||
if (vn_has_cached_data(vp)) {
|
||||
error = mappedread(vp, nbytes, uio);
|
||||
else
|
||||
error = dmu_read_uio(os, zp->z_id, uio, nbytes);
|
||||
} else {
|
||||
error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
|
||||
uio, nbytes);
|
||||
}
|
||||
if (error) {
|
||||
/* convert checksum errors into IO errors */
|
||||
if (error == ECKSUM)
|
||||
|
Loading…
Reference in New Issue
Block a user