diff options
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zvol.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/zvol.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c index 1e787f31b2..196c98c602 100644 --- a/usr/src/uts/common/fs/zfs/zvol.c +++ b/usr/src/uts/common/fs/zfs/zvol.c @@ -92,6 +92,7 @@ #include <sys/zil_impl.h> #include <sys/ht.h> #include <sys/dkioc_free_util.h> +#include <sys/zfs_rlock.h> #include "zfs_namecheck.h" @@ -130,7 +131,7 @@ typedef struct zvol_state { uint32_t zv_total_opens; /* total open count */ zilog_t *zv_zilog; /* ZIL handle */ list_t zv_extents; /* List of extents for dump */ - znode_t zv_znode; /* for range locking */ + rangelock_t zv_rangelock; dnode_t *zv_dn; /* dnode hold */ } zvol_state_t; @@ -560,9 +561,7 @@ zvol_create_minor(const char *name) zv->zv_objset = os; if (dmu_objset_is_snapshot(os) || !spa_writeable(dmu_objset_spa(os))) zv->zv_flags |= ZVOL_RDONLY; - mutex_init(&zv->zv_znode.z_range_lock, NULL, MUTEX_DEFAULT, NULL); - avl_create(&zv->zv_znode.z_range_avl, zfs_range_compare, - sizeof (rl_t), offsetof(rl_t, r_node)); + rangelock_init(&zv->zv_rangelock, NULL, NULL); list_create(&zv->zv_extents, sizeof (zvol_extent_t), offsetof(zvol_extent_t, ze_node)); /* get and cache the blocksize */ @@ -605,8 +604,7 @@ zvol_remove_zv(zvol_state_t *zv) (void) snprintf(nmbuf, sizeof (nmbuf), "%u", minor); ddi_remove_minor_node(zfs_dip, nmbuf); - avl_destroy(&zv->zv_znode.z_range_avl); - mutex_destroy(&zv->zv_znode.z_range_lock); + rangelock_fini(&zv->zv_rangelock); kmem_free(zv, sizeof (zvol_state_t)); @@ -987,7 +985,7 @@ zvol_get_done(zgd_t *zgd, int error) if (zgd->zgd_db) dmu_buf_rele(zgd->zgd_db, zgd); - zfs_range_unlock(zgd->zgd_rl); + rangelock_exit(zgd->zgd_lr); kmem_free(zgd, sizeof (zgd_t)); } @@ -1020,7 +1018,7 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio) * we don't have to write the data twice. */ if (buf != NULL) { /* immediate write */ - zgd->zgd_rl = zfs_range_lock(&zv->zv_znode, offset, size, + zgd->zgd_lr = rangelock_enter(&zv->zv_rangelock, offset, size, RL_READER); error = dmu_read_by_dnode(zv->zv_dn, offset, size, buf, DMU_READ_NO_PREFETCH); @@ -1033,7 +1031,7 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio) */ size = zv->zv_volblocksize; offset = P2ALIGN(offset, size); - zgd->zgd_rl = zfs_range_lock(&zv->zv_znode, offset, size, + zgd->zgd_lr = rangelock_enter(&zv->zv_rangelock, offset, size, RL_READER); error = dmu_buf_hold_by_dnode(zv->zv_dn, offset, zgd, &db, DMU_READ_NO_PREFETCH); @@ -1229,7 +1227,6 @@ zvol_strategy(buf_t *bp) size_t resid; char *addr; objset_t *os; - rl_t *rl; int error = 0; boolean_t doread = bp->b_flags & B_READ; boolean_t is_dumpified; @@ -1287,7 +1284,7 @@ zvol_strategy(buf_t *bp) * There must be no buffer changes when doing a dmu_sync() because * we can't change the data whilst calculating the checksum. */ - rl = zfs_range_lock(&zv->zv_znode, off, resid, + locked_range_t *lr = rangelock_enter(&zv->zv_rangelock, off, resid, doread ? RL_READER : RL_WRITER); while (resid != 0 && off < volsize) { @@ -1321,7 +1318,7 @@ zvol_strategy(buf_t *bp) addr += size; resid -= size; } - zfs_range_unlock(rl); + rangelock_exit(lr); if ((bp->b_resid = resid) == bp->b_bcount) bioerror(bp, off > volsize ? EINVAL : error); @@ -1392,7 +1389,6 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr) minor_t minor = getminor(dev); zvol_state_t *zv; uint64_t volsize; - rl_t *rl; int error = 0; zone_t *zonep = curzone; uint64_t tot_bytes; @@ -1423,8 +1419,8 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr) start = gethrtime(); tot_bytes = 0; - rl = zfs_range_lock(&zv->zv_znode, uio->uio_loffset, uio->uio_resid, - RL_READER); + locked_range_t *lr = rangelock_enter(&zv->zv_rangelock, + uio->uio_loffset, uio->uio_resid, RL_READER); while (uio->uio_resid > 0 && uio->uio_loffset < volsize) { uint64_t bytes = MIN(uio->uio_resid, DMU_MAX_ACCESS >> 1); @@ -1441,7 +1437,7 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr) break; } } - zfs_range_unlock(rl); + rangelock_exit(lr); mutex_enter(&zonep->zone_vfs_lock); zonep->zone_vfs_rwstats.reads++; @@ -1487,7 +1483,6 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) minor_t minor = getminor(dev); zvol_state_t *zv; uint64_t volsize; - rl_t *rl; int error = 0; boolean_t sync; zone_t *zonep = curzone; @@ -1527,8 +1522,8 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) sync = !(zv->zv_flags & ZVOL_WCE) || (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS); - rl = zfs_range_lock(&zv->zv_znode, uio->uio_loffset, uio->uio_resid, - RL_WRITER); + locked_range_t *lr = rangelock_enter(&zv->zv_rangelock, + uio->uio_loffset, uio->uio_resid, RL_WRITER); while (uio->uio_resid > 0 && uio->uio_loffset < volsize) { uint64_t bytes = MIN(uio->uio_resid, DMU_MAX_ACCESS >> 1); uint64_t off = uio->uio_loffset; @@ -1552,7 +1547,8 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr) if (error) break; } - zfs_range_unlock(rl); + rangelock_exit(lr); + if (sync) zil_commit(zv->zv_zilog, ZVOL_OBJ); @@ -1678,7 +1674,7 @@ zvol_get_volume_params(minor_t minor, uint64_t *blksize, *minor_hdl = zv; *objset_hdl = zv->zv_objset; *zil_hdl = zv->zv_zilog; - *rl_hdl = &zv->zv_znode; + *rl_hdl = &zv->zv_rangelock; *dnode_hdl = zv->zv_dn; return (0); } @@ -1757,7 +1753,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) zvol_state_t *zv; struct dk_callback *dkc; int error = 0; - rl_t *rl; + locked_range_t *lr; mutex_enter(&zfsdev_state_lock); @@ -1882,19 +1878,19 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) break; case DKIOCDUMPINIT: - rl = zfs_range_lock(&zv->zv_znode, 0, zv->zv_volsize, + lr = rangelock_enter(&zv->zv_rangelock, 0, zv->zv_volsize, RL_WRITER); error = zvol_dumpify(zv); - zfs_range_unlock(rl); + rangelock_exit(lr); break; case DKIOCDUMPFINI: if (!(zv->zv_flags & ZVOL_DUMPIFIED)) break; - rl = zfs_range_lock(&zv->zv_znode, 0, zv->zv_volsize, + lr = rangelock_enter(&zv->zv_rangelock, 0, zv->zv_volsize, RL_WRITER); error = zvol_dump_fini(zv); - zfs_range_unlock(rl); + rangelock_exit(lr); break; case DKIOCFREE: @@ -1939,7 +1935,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) length = end - start; } - rl = zfs_range_lock(&zv->zv_znode, start, length, + lr = rangelock_enter(&zv->zv_rangelock, start, length, RL_WRITER); tx = dmu_tx_create(zv->zv_objset); error = dmu_tx_assign(tx, TXG_WAIT); @@ -1953,7 +1949,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) ZVOL_OBJ, start, length); } - zfs_range_unlock(rl); + rangelock_exit(lr); if (error != 0) break; |