aboutsummaryrefslogtreecommitdiffstats
path: root/uts/common/fs/zfs/zvol.c
diff options
context:
space:
mode:
Diffstat (limited to 'uts/common/fs/zfs/zvol.c')
-rw-r--r--uts/common/fs/zfs/zvol.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/uts/common/fs/zfs/zvol.c b/uts/common/fs/zfs/zvol.c
index ff892aa6c795..3566984ab4b0 100644
--- a/uts/common/fs/zfs/zvol.c
+++ b/uts/common/fs/zfs/zvol.c
@@ -90,6 +90,7 @@
#include <sys/zio_checksum.h>
#include <sys/zil_impl.h>
#include <sys/dkioc_free_util.h>
+#include <sys/zfs_rlock.h>
#include "zfs_namecheck.h"
@@ -128,7 +129,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;
@@ -553,9 +554,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 */
@@ -598,8 +597,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));
@@ -980,7 +978,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));
}
@@ -1013,7 +1011,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);
@@ -1026,7 +1024,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);
@@ -1222,7 +1220,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;
@@ -1278,7 +1275,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) {
@@ -1312,7 +1309,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);
@@ -1381,7 +1378,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;
zv = zfsdev_get_soft_state(minor, ZSST_ZVOL);
@@ -1399,8 +1395,8 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr)
return (error);
}
- 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);
@@ -1416,7 +1412,8 @@ zvol_read(dev_t dev, uio_t *uio, cred_t *cr)
break;
}
}
- zfs_range_unlock(rl);
+ rangelock_exit(lr);
+
return (error);
}
@@ -1427,7 +1424,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;
@@ -1449,8 +1445,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;
@@ -1473,7 +1469,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);
return (error);
@@ -1564,7 +1561,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);
}
@@ -1643,7 +1640,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);
@@ -1760,19 +1757,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:
@@ -1815,7 +1812,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);
@@ -1829,7 +1826,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;