summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zvol.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zvol.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zvol.c52
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;