diff options
author | Tim Haley <Tim.Haley@Sun.COM> | 2010-04-09 22:09:40 -0600 |
---|---|---|
committer | Tim Haley <Tim.Haley@Sun.COM> | 2010-04-09 22:09:40 -0600 |
commit | 94d1a2100edbb6781ea1c047a6334bb3f15640f5 (patch) | |
tree | ff19c4d03a79a57558c9fffff414d12d8286dd47 /usr/src/uts/common/fs/zfs/zvol.c | |
parent | 6fe5d52278c2b2ca5ebc807f72538e34fa43f584 (diff) | |
download | illumos-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.c | 10 |
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); |