summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zvol.c
diff options
context:
space:
mode:
authorTim Haley <Tim.Haley@Sun.COM>2010-04-09 22:09:40 -0600
committerTim Haley <Tim.Haley@Sun.COM>2010-04-09 22:09:40 -0600
commit94d1a2100edbb6781ea1c047a6334bb3f15640f5 (patch)
treeff19c4d03a79a57558c9fffff414d12d8286dd47 /usr/src/uts/common/fs/zfs/zvol.c
parent6fe5d52278c2b2ca5ebc807f72538e34fa43f584 (diff)
downloadillumos-gate-94d1a2100edbb6781ea1c047a6334bb3f15640f5.tar.gz
6572591 meta dnode lookup causes bucket lock contention in dbuf hash
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zvol.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zvol.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c
index d957796344..08bacad8b6 100644
--- a/usr/src/uts/common/fs/zfs/zvol.c
+++ b/usr/src/uts/common/fs/zfs/zvol.c
@@ -114,6 +114,7 @@ typedef struct zvol_state {
zilog_t *zv_zilog; /* ZIL handle */
list_t zv_extents; /* List of extents for dump */
znode_t zv_znode; /* for range locking */
+ dmu_buf_t *zv_dbuf; /* bonus handle */
} zvol_state_t;
/*
@@ -599,6 +600,11 @@ zvol_first_open(zvol_state_t *zv)
return (error);
}
zv->zv_objset = os;
+ error = dmu_bonus_hold(os, ZVOL_OBJ, zvol_tag, &zv->zv_dbuf);
+ if (error) {
+ dmu_objset_disown(os, zvol_tag);
+ return (error);
+ }
zv->zv_volsize = volsize;
zv->zv_zilog = zil_open(os, zvol_get_data);
zvol_size_changed(zv->zv_volsize, ddi_driver_major(zfs_dip),
@@ -618,6 +624,8 @@ zvol_last_close(zvol_state_t *zv)
{
zil_close(zv->zv_zilog);
zv->zv_zilog = NULL;
+ dmu_buf_rele(zv->zv_dbuf, zvol_tag);
+ zv->zv_dbuf = NULL;
dmu_objset_disown(zv->zv_objset, zvol_tag);
zv->zv_objset = NULL;
}
@@ -1372,7 +1380,7 @@ zvol_write(dev_t dev, uio_t *uio, cred_t *cr)
dmu_tx_abort(tx);
break;
}
- error = dmu_write_uio(zv->zv_objset, ZVOL_OBJ, uio, bytes, tx);
+ error = dmu_write_uio_dbuf(zv->zv_dbuf, uio, bytes, tx);
if (error == 0)
zvol_log_write(zv, tx, off, bytes, sync);
dmu_tx_commit(tx);