]> granicus.if.org Git - zfs/commitdiff
Make zvol operations use _by_dnode routines
authorRichard Yao <ryao@gentoo.org>
Tue, 13 Jun 2017 16:18:08 +0000 (12:18 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 13 Jun 2017 16:18:08 +0000 (09:18 -0700)
This continues what was started in
0eef1bde31d67091d3deed23fe2394f5a8bf2276 by fully converting zvols
to avoid unnecessary dnode_hold() calls. This saves a small amount
of CPU time and slightly improves latencies of operations on zvols.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <richard.yao@prophetstor.com>
Closes #6058

include/sys/dmu.h
module/zfs/dmu.c
module/zfs/zvol.c

index ea1b116bed2e1a4facb626ef983b467c67ba2239..d24615262737912d1e88c18aecd30fc8c9105560 100644 (file)
@@ -751,10 +751,13 @@ void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
 #include <linux/blkdev_compat.h>
 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_read_uio_dnode(dnode_t *dn, 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,
        dmu_tx_t *tx);
+int dmu_write_uio_dnode(dnode_t *dn, struct uio *uio, uint64_t size,
+       dmu_tx_t *tx);
 #endif
 struct arc_buf *dmu_request_arcbuf(dmu_buf_t *handle, int size);
 void dmu_return_arcbuf(struct arc_buf *buf);
index 5cf09412f753bee4614473041b64609d3f72cabc..48e89eef4af31d8a22d5bdbea29910e9bae451d7 100644 (file)
@@ -1225,7 +1225,7 @@ xuio_stat_wbuf_nocopy(void)
 }
 
 #ifdef _KERNEL
-static int
+int
 dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size)
 {
        dmu_buf_t **dbp;
@@ -1334,7 +1334,7 @@ dmu_read_uio(objset_t *os, uint64_t object, uio_t *uio, uint64_t size)
        return (err);
 }
 
-static int
+int
 dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx)
 {
        dmu_buf_t **dbp;
index bf9f48adb2f3e1b0960e6c1e540e7f8327365542..72ea99af6357dee4deb0a46e5769ae45c8cd0909 100644 (file)
@@ -111,7 +111,7 @@ struct zvol_state {
        uint32_t                zv_changed;     /* disk changed */
        zilog_t                 *zv_zilog;      /* ZIL handle */
        zfs_rlock_t             zv_range_lock;  /* range lock */
-       dmu_buf_t               *zv_dbuf;       /* bonus handle */
+       dnode_t                 *zv_dn;         /* dnode hold */
        dev_t                   zv_dev;         /* device id */
        struct gendisk          *zv_disk;       /* generic disk */
        struct request_queue    *zv_queue;      /* request queue */
@@ -640,8 +640,8 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
                itx = zil_itx_create(TX_WRITE, sizeof (*lr) +
                    (wr_state == WR_COPIED ? len : 0));
                lr = (lr_write_t *)&itx->itx_lr;
-               if (wr_state == WR_COPIED && dmu_read(zv->zv_objset,
-                   ZVOL_OBJ, offset, len, lr+1, DMU_READ_NO_PREFETCH) != 0) {
+               if (wr_state == WR_COPIED && dmu_read_by_dnode(zv->zv_dn,
+                   offset, len, lr+1, DMU_READ_NO_PREFETCH) != 0) {
                        zil_itx_destroy(itx);
                        itx = zil_itx_create(TX_WRITE, sizeof (*lr));
                        lr = (lr_write_t *)&itx->itx_lr;
@@ -720,7 +720,7 @@ zvol_write(void *arg)
                        dmu_tx_abort(tx);
                        break;
                }
-               error = dmu_write_uio_dbuf(zv->zv_dbuf, &uio, bytes, tx);
+               error = dmu_write_uio_dnode(zv->zv_dn, &uio, bytes, tx);
                if (error == 0)
                        zvol_log_write(zv, tx, off, bytes, sync);
                dmu_tx_commit(tx);
@@ -845,7 +845,7 @@ zvol_read(void *arg)
                if (bytes > volsize - uio.uio_loffset)
                        bytes = volsize - uio.uio_loffset;
 
-               error = dmu_read_uio_dbuf(zv->zv_dbuf, &uio, bytes);
+               error = dmu_read_uio_dnode(zv->zv_dn, &uio, bytes);
                if (error) {
                        /* convert checksum errors into IO errors */
                        if (error == ECKSUM)
@@ -969,8 +969,6 @@ static int
 zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
 {
        zvol_state_t *zv = arg;
-       objset_t *os = zv->zv_objset;
-       uint64_t object = ZVOL_OBJ;
        uint64_t offset = lr->lr_offset;
        uint64_t size = lr->lr_length;
        blkptr_t *bp = &lr->lr_blkptr;
@@ -994,12 +992,12 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
         * we don't have to write the data twice.
         */
        if (buf != NULL) { /* immediate write */
-               error = dmu_read(os, object, offset, size, buf,
+               error = dmu_read_by_dnode(zv->zv_dn, offset, size, buf,
                    DMU_READ_NO_PREFETCH);
        } else {
                size = zv->zv_volblocksize;
                offset = P2ALIGN_TYPED(offset, size, uint64_t);
-               error = dmu_buf_hold(os, object, offset, zgd, &db,
+               error = dmu_buf_hold_by_dnode(zv->zv_dn, offset, zgd, &db,
                    DMU_READ_NO_PREFETCH);
                if (error == 0) {
                        blkptr_t *obp = dmu_buf_get_blkptr(db);
@@ -1070,7 +1068,7 @@ zvol_setup_zv(zvol_state_t *zv)
        if (error)
                return (SET_ERROR(error));
 
-       error = dmu_bonus_hold(os, ZVOL_OBJ, zv, &zv->zv_dbuf);
+       error = dnode_hold(os, ZVOL_OBJ, FTAG, &zv->zv_dn);
        if (error)
                return (SET_ERROR(error));
 
@@ -1099,8 +1097,8 @@ zvol_shutdown_zv(zvol_state_t *zv)
        zil_close(zv->zv_zilog);
        zv->zv_zilog = NULL;
 
-       dmu_buf_rele(zv->zv_dbuf, zv);
-       zv->zv_dbuf = NULL;
+       dnode_rele(zv->zv_dn, FTAG);
+       zv->zv_dn = NULL;
 
        /*
         * Evict cached data