aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index 9f161f631c34..6815b6897412 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -94,6 +94,7 @@
#include <sys/zio_checksum.h>
#include <sys/zil_impl.h>
#include <sys/filio.h>
+#include <sys/zfs_rlock.h>
#include <geom/geom.h>
@@ -173,7 +174,7 @@ typedef struct zvol_state {
uint32_t zv_sync_cnt; /* synchronous 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 */
#ifndef illumos
int zv_state;
@@ -737,9 +738,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));
#ifdef illumos
@@ -809,8 +808,7 @@ zvol_remove_zv(zvol_state_t *zv)
}
#endif
- 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));
#ifdef illumos
@@ -1328,7 +1326,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));
}
@@ -1361,7 +1359,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);
@@ -1374,7 +1372,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);
@@ -1582,7 +1580,6 @@ zvol_strategy(struct bio *bp)
size_t resid;
char *addr;
objset_t *os;
- rl_t *rl;
int error = 0;
#ifdef illumos
boolean_t doread = bp->b_flags & B_READ;
@@ -1688,7 +1685,7 @@ zvol_strategy(struct bio *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);
#ifndef illumos
@@ -1745,7 +1742,7 @@ zvol_strategy(struct bio *bp)
#ifndef illumos
unlock:
#endif
- zfs_range_unlock(rl);
+ rangelock_exit(lr);
#ifdef illumos
if ((bp->b_resid = resid) == bp->b_bcount)
@@ -1836,7 +1833,6 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag)
#endif /* illumos */
zvol_state_t *zv;
uint64_t volsize;
- rl_t *rl;
int error = 0;
#ifdef illumos
@@ -1861,8 +1857,8 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag)
}
#endif
- 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);
@@ -1878,7 +1874,8 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag)
break;
}
}
- zfs_range_unlock(rl);
+ rangelock_exit(lr);
+
return (error);
}
@@ -1895,7 +1892,6 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
#endif /* illumos */
zvol_state_t *zv;
uint64_t volsize;
- rl_t *rl;
int error = 0;
boolean_t sync;
@@ -1926,8 +1922,8 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
#endif
(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;
@@ -1950,7 +1946,8 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
if (error)
break;
}
- zfs_range_unlock(rl);
+ rangelock_exit(lr);
+
if (sync)
zil_commit(zv->zv_zilog, ZVOL_OBJ);
return (error);
@@ -2042,7 +2039,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);
}
@@ -2123,7 +2120,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);
@@ -2240,19 +2237,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:
@@ -2295,7 +2292,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);
@@ -2309,7 +2306,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;
@@ -3166,7 +3163,7 @@ static int
zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
{
zvol_state_t *zv;
- rl_t *rl;
+ locked_range_t *lr;
off_t offset, length;
int i, error;
boolean_t sync;
@@ -3203,7 +3200,8 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa
break;
}
- rl = zfs_range_lock(&zv->zv_znode, offset, length, RL_WRITER);
+ lr = rangelock_enter(&zv->zv_rangelock, offset, length,
+ RL_WRITER);
dmu_tx_t *tx = dmu_tx_create(zv->zv_objset);
error = dmu_tx_assign(tx, TXG_WAIT);
if (error != 0) {
@@ -3216,7 +3214,7 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ,
offset, length);
}
- zfs_range_unlock(rl);
+ rangelock_exit(lr);
if (sync)
zil_commit(zv->zv_zilog, ZVOL_OBJ);
break;