Illumos 5175 - implement dmu_read_uio_dbuf() to improve cached read performance
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> References: https://www.illumos.org/issues/5175 https://github.com/illumos/illumos-gate/commit/f8554bb Porting notes: This patch doesn't include the changes for the COMSTAR (Common Multiprotocol SCSI Target) - since it's not available for ZoL. http://thegreyblog.blogspot.co.at/2010/02/setting-up-solaris-comstar-and.html Ported by: kernelOfTruth <kerneloftruth@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3392
This commit is contained in:
parent
d6c9ff0a6b
commit
804e050457
|
@ -714,6 +714,7 @@ int dmu_read_req(objset_t *os, uint64_t object, struct request *req);
|
|||
int dmu_write_req(objset_t *os, uint64_t object, struct request *req,
|
||||
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,
|
||||
|
|
|
@ -1199,8 +1199,8 @@ dmu_write_req(objset_t *os, uint64_t object, struct request *req, dmu_tx_t *tx)
|
|||
return (err);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -1210,8 +1210,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);
|
||||
|
||||
|
@ -1253,6 +1253,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)
|
||||
{
|
||||
|
@ -1305,6 +1357,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)
|
||||
|
@ -1324,6 +1385,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)
|
||||
|
|
|
@ -376,7 +376,6 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
|
|||
struct address_space *mp = ip->i_mapping;
|
||||
struct page *pp;
|
||||
znode_t *zp = ITOZ(ip);
|
||||
objset_t *os = ITOZSB(ip)->z_os;
|
||||
int64_t start, off;
|
||||
uint64_t bytes;
|
||||
int len = nbytes;
|
||||
|
@ -403,7 +402,8 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
|
|||
unlock_page(pp);
|
||||
page_cache_release(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;
|
||||
|
@ -440,7 +440,6 @@ zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
|
|||
{
|
||||
znode_t *zp = ITOZ(ip);
|
||||
zfs_sb_t *zsb = ITOZSB(ip);
|
||||
objset_t *os;
|
||||
ssize_t n, nbytes;
|
||||
int error = 0;
|
||||
rl_t *rl;
|
||||
|
@ -450,7 +449,6 @@ zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
|
|||
|
||||
ZFS_ENTER(zsb);
|
||||
ZFS_VERIFY_ZP(zp);
|
||||
os = zsb->z_os;
|
||||
|
||||
if (zp->z_pflags & ZFS_AV_QUARANTINED) {
|
||||
ZFS_EXIT(zsb);
|
||||
|
@ -531,10 +529,12 @@ zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
|
|||
nbytes = MIN(n, zfs_read_chunk_size -
|
||||
P2PHASE(uio->uio_loffset, zfs_read_chunk_size));
|
||||
|
||||
if (zp->z_is_mapped && !(ioflag & O_DIRECT))
|
||||
if (zp->z_is_mapped && !(ioflag & O_DIRECT)) {
|
||||
error = mappedread(ip, 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 */
|
||||
|
|
Loading…
Reference in New Issue