summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zap_micro.c
diff options
context:
space:
mode:
authorahrens <none@none>2005-11-10 18:43:50 -0800
committerahrens <none@none>2005-11-10 18:43:50 -0800
commit87e5029a3226958edab1512d6182bc74d8d80c9a (patch)
treeb922544f2d2e7ee6d88bb31496f6e64e7de283d6 /usr/src/uts/common/fs/zfs/zap_micro.c
parentcbcb6089bf49be7bed77b8c9c1727b26f2e9c913 (diff)
downloadillumos-gate-87e5029a3226958edab1512d6182bc74d8d80c9a.tar.gz
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
6348409 'zfs rename' process hangs after assigning a very long name ... 6348464 a few DMU object type macros are misnamed
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zap_micro.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zap_micro.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/usr/src/uts/common/fs/zfs/zap_micro.c b/usr/src/uts/common/fs/zfs/zap_micro.c
index 998b67c50f..404f1afb36 100644
--- a/usr/src/uts/common/fs/zfs/zap_micro.c
+++ b/usr/src/uts/common/fs/zfs/zap_micro.c
@@ -31,6 +31,7 @@
#include <sys/zfs_context.h>
#include <sys/zap.h>
#include <sys/zap_impl.h>
+#include <sys/zap_leaf.h>
#include <sys/avl.h>
@@ -694,15 +695,6 @@ zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx)
* Routines for iterating over the attributes.
*/
-void
-zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
-{
- zc->zc_objset = os;
- zc->zc_zapobj = zapobj;
- zc->zc_hash = 0;
- zc->zc_cd = 0;
-}
-
/*
* We want to keep the high 32 bits of the cursor zero if we can, so
* that 32-bit programs can access this. So use a small hash value so
@@ -715,6 +707,8 @@ zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
uint64_t serialized)
{
zc->zc_objset = os;
+ zc->zc_zap = NULL;
+ zc->zc_leaf = NULL;
zc->zc_zapobj = zapobj;
if (serialized == -1ULL) {
zc->zc_hash = -1ULL;
@@ -727,6 +721,28 @@ zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj,
}
}
+void
+zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj)
+{
+ zap_cursor_init_serialized(zc, os, zapobj, 0);
+}
+
+void
+zap_cursor_fini(zap_cursor_t *zc)
+{
+ if (zc->zc_zap) {
+ rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
+ zap_unlockdir(zc->zc_zap);
+ zc->zc_zap = NULL;
+ }
+ if (zc->zc_leaf) {
+ rw_enter(&zc->zc_leaf->l_rwlock, RW_READER);
+ zap_put_leaf(zc->zc_leaf);
+ zc->zc_leaf = NULL;
+ }
+ zc->zc_objset = NULL;
+}
+
uint64_t
zap_cursor_serialize(zap_cursor_t *zc)
{
@@ -741,7 +757,6 @@ zap_cursor_serialize(zap_cursor_t *zc)
int
zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
{
- zap_t *zap;
int err;
avl_index_t idx;
mzap_ent_t mze_tofind;
@@ -750,25 +765,30 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
if (zc->zc_hash == -1ULL)
return (ENOENT);
- err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
- RW_READER, TRUE, &zap);
- if (err)
- return (err);
- if (!zap->zap_ismicro) {
- err = fzap_cursor_retrieve(zap, zc, za);
+ if (zc->zc_zap == NULL) {
+ err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
+ RW_READER, TRUE, &zc->zc_zap);
+ if (err)
+ return (err);
+ } else {
+ rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
+ }
+ if (!zc->zc_zap->zap_ismicro) {
+ err = fzap_cursor_retrieve(zc->zc_zap, zc, za);
} else {
err = ENOENT;
mze_tofind.mze_hash = zc->zc_hash;
mze_tofind.mze_phys.mze_cd = zc->zc_cd;
- mze = avl_find(&zap->zap_m.zap_avl, &mze_tofind, &idx);
+ mze = avl_find(&zc->zc_zap->zap_m.zap_avl, &mze_tofind, &idx);
ASSERT(mze == NULL || 0 == bcmp(&mze->mze_phys,
- &zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
+ &zc->zc_zap->zap_m.zap_phys->mz_chunk[mze->mze_chunkid],
sizeof (mze->mze_phys)));
- if (mze == NULL)
- mze = avl_nearest(&zap->zap_m.zap_avl, idx, AVL_AFTER);
-
+ if (mze == NULL) {
+ mze = avl_nearest(&zc->zc_zap->zap_m.zap_avl,
+ idx, AVL_AFTER);
+ }
if (mze) {
za->za_integer_length = 8;
za->za_num_integers = 1;
@@ -781,7 +801,7 @@ zap_cursor_retrieve(zap_cursor_t *zc, zap_attribute_t *za)
zc->zc_hash = -1ULL;
}
}
- zap_unlockdir(zap);
+ rw_exit(&zc->zc_zap->zap_rwlock);
return (err);
}