116 lines
3.2 KiB
Diff
116 lines
3.2 KiB
Diff
Add a ZAP API to move a ZAP cursor to a given key.
|
|
|
|
Index: zfs+chaos4/lib/libzfscommon/include/sys/zap.h
|
|
===================================================================
|
|
--- zfs+chaos4.orig/lib/libzfscommon/include/sys/zap.h
|
|
+++ zfs+chaos4/lib/libzfscommon/include/sys/zap.h
|
|
@@ -302,6 +302,11 @@ void zap_cursor_advance(zap_cursor_t *zc
|
|
uint64_t zap_cursor_serialize(zap_cursor_t *zc);
|
|
|
|
/*
|
|
+ * Advance the cursor to the attribute having the key.
|
|
+ */
|
|
+int zap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt);
|
|
+
|
|
+/*
|
|
* Initialize a zap cursor pointing to the position recorded by
|
|
* zap_cursor_serialize (in the "serialized" argument). You can also
|
|
* use a "serialized" argument of 0 to start at the beginning of the
|
|
Index: zfs+chaos4/lib/libzfscommon/include/sys/zap_impl.h
|
|
===================================================================
|
|
--- zfs+chaos4.orig/lib/libzfscommon/include/sys/zap_impl.h
|
|
+++ zfs+chaos4/lib/libzfscommon/include/sys/zap_impl.h
|
|
@@ -210,6 +210,7 @@ int fzap_add_cd(zap_name_t *zn,
|
|
uint64_t integer_size, uint64_t num_integers,
|
|
const void *val, uint32_t cd, dmu_tx_t *tx);
|
|
void fzap_upgrade(zap_t *zap, dmu_tx_t *tx);
|
|
+int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: zfs+chaos4/lib/libzpool/zap.c
|
|
===================================================================
|
|
--- zfs+chaos4.orig/lib/libzpool/zap.c
|
|
+++ zfs+chaos4/lib/libzpool/zap.c
|
|
@@ -1029,6 +1029,30 @@ zap_stats_ptrtbl(zap_t *zap, uint64_t *t
|
|
}
|
|
}
|
|
|
|
+int fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn)
|
|
+{
|
|
+ int err;
|
|
+ zap_leaf_t *l;
|
|
+ zap_entry_handle_t zeh;
|
|
+ uint64_t hash;
|
|
+
|
|
+ if (zn->zn_name_orij && strlen(zn->zn_name_orij) > ZAP_MAXNAMELEN)
|
|
+ return (E2BIG);
|
|
+
|
|
+ err = zap_deref_leaf(zc->zc_zap, zn->zn_hash, NULL, RW_READER, &l);
|
|
+ if (err != 0)
|
|
+ return (err);
|
|
+
|
|
+ err = zap_leaf_lookup(l, zn, &zeh);
|
|
+ if (err != 0)
|
|
+ return (err);
|
|
+
|
|
+ zc->zc_leaf = l;
|
|
+ zc->zc_hash = zeh.zeh_hash;
|
|
+ zc->zc_cd = zeh.zeh_cd;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
void
|
|
fzap_get_stats(zap_t *zap, zap_stats_t *zs)
|
|
{
|
|
Index: zfs+chaos4/lib/libzpool/zap_micro.c
|
|
===================================================================
|
|
--- zfs+chaos4.orig/lib/libzpool/zap_micro.c
|
|
+++ zfs+chaos4/lib/libzpool/zap_micro.c
|
|
@@ -1045,6 +1045,45 @@ zap_cursor_advance(zap_cursor_t *zc)
|
|
}
|
|
}
|
|
|
|
+int zap_cursor_move_to_key(zap_cursor_t *zc, const char *name, matchtype_t mt)
|
|
+{
|
|
+ int err = 0;
|
|
+ mzap_ent_t *mze;
|
|
+ zap_name_t *zn;
|
|
+
|
|
+ if (zc->zc_zap == NULL) {
|
|
+ err = zap_lockdir(zc->zc_objset, zc->zc_zapobj, NULL,
|
|
+ RW_READER, TRUE, FALSE, &zc->zc_zap);
|
|
+ if (err)
|
|
+ return (err);
|
|
+ } else {
|
|
+ rw_enter(&zc->zc_zap->zap_rwlock, RW_READER);
|
|
+ }
|
|
+
|
|
+ zn = zap_name_alloc(zc->zc_zap, name, mt);
|
|
+ if (zn == NULL) {
|
|
+ rw_exit(&zc->zc_zap->zap_rwlock);
|
|
+ return (ENOTSUP);
|
|
+ }
|
|
+
|
|
+ if (!zc->zc_zap->zap_ismicro) {
|
|
+ err = fzap_cursor_move_to_key(zc, zn);
|
|
+ } else {
|
|
+ mze = mze_find(zn);
|
|
+ if (mze == NULL) {
|
|
+ err = (ENOENT);
|
|
+ goto out;
|
|
+ }
|
|
+ zc->zc_hash = mze->mze_hash;
|
|
+ zc->zc_cd = mze->mze_phys.mze_cd;
|
|
+ }
|
|
+
|
|
+out:
|
|
+ zap_name_free(zn);
|
|
+ rw_exit(&zc->zc_zap->zap_rwlock);
|
|
+ return (err);
|
|
+}
|
|
+
|
|
int
|
|
zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)
|
|
{
|