]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/zap_micro.c
Encrypted dnode blocks should be prefetched raw
[mirror_zfs.git] / module / zfs / zap_micro.c
index 28c80e5493dad92737661479341b183fc053d759..ad9a62161ed5d33566904d40895b1fde9b4ca24b 100644 (file)
@@ -363,6 +363,41 @@ mze_find_unused_cd(zap_t *zap, uint64_t hash)
        return (cd);
 }
 
+/*
+ * Each mzap entry requires at max : 4 chunks
+ * 3 chunks for names + 1 chunk for value.
+ */
+#define        MZAP_ENT_CHUNKS (1 + ZAP_LEAF_ARRAY_NCHUNKS(MZAP_NAME_LEN) + \
+       ZAP_LEAF_ARRAY_NCHUNKS(sizeof (uint64_t)))
+
+/*
+ * Check if the current entry keeps the colliding entries under the fatzap leaf
+ * size.
+ */
+static boolean_t
+mze_canfit_fzap_leaf(zap_name_t *zn, uint64_t hash)
+{
+       zap_t *zap = zn->zn_zap;
+       mzap_ent_t mze_tofind;
+       mzap_ent_t *mze;
+       avl_index_t idx;
+       avl_tree_t *avl = &zap->zap_m.zap_avl;
+       uint32_t mzap_ents = 0;
+
+       mze_tofind.mze_hash = hash;
+       mze_tofind.mze_cd = 0;
+
+       for (mze = avl_find(avl, &mze_tofind, &idx);
+           mze && mze->mze_hash == hash; mze = AVL_NEXT(avl, mze)) {
+               mzap_ents++;
+       }
+
+       /* Include the new entry being added */
+       mzap_ents++;
+
+       return (ZAP_LEAF_NUMCHUNKS_DEF > (mzap_ents * MZAP_ENT_CHUNKS));
+}
+
 static void
 mze_remove(zap_t *zap, mzap_ent_t *mze)
 {
@@ -404,7 +439,8 @@ mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
        zap->zap_dbuf = db;
 
        if (zap_block_type != ZBT_MICRO) {
-               mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, 0, 0);
+               mutex_init(&zap->zap_f.zap_num_entries_mtx, 0, MUTEX_DEFAULT,
+                   0);
                zap->zap_f.zap_block_shift = highbit64(db->db_size) - 1;
                if (zap_block_type != ZBT_HEADER || zap_magic != ZAP_MAGIC) {
                        winner = NULL;  /* No actual winner here... */
@@ -540,11 +576,10 @@ zap_lockdir_impl(dmu_buf_t *db, void *tag, dmu_tx_t *tx,
            zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) {
                uint64_t newsz = db->db_size + SPA_MINBLOCKSIZE;
                if (newsz > MZAP_MAX_BLKSZ) {
-                       int err;
                        dprintf("upgrading obj %llu: num_entries=%u\n",
                            obj, zap->zap_m.zap_num_entries);
                        *zapp = zap;
-                       err = mzap_upgrade(zapp, tag, tx, 0);
+                       int err = mzap_upgrade(zapp, tag, tx, 0);
                        if (err != 0)
                                rw_exit(&zap->zap_rwlock);
                        return (err);
@@ -674,7 +709,7 @@ mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags,
        dmu_buf_t *db;
        mzap_phys_t *zp;
 
-       VERIFY(0 == dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
+       VERIFY0(dmu_buf_hold(os, obj, 0, FTAG, &db, DMU_READ_NO_PREFETCH));
 
 #ifdef ZFS_DEBUG
        {
@@ -1190,7 +1225,8 @@ zap_add_impl(zap_t *zap, const char *key,
                err = fzap_add(zn, integer_size, num_integers, val, tag, tx);
                zap = zn->zn_zap;       /* fzap_add() may change zap */
        } else if (integer_size != 8 || num_integers != 1 ||
-           strlen(key) >= MZAP_NAME_LEN) {
+           strlen(key) >= MZAP_NAME_LEN ||
+           !mze_canfit_fzap_leaf(zn, zn->zn_hash)) {
                err = mzap_upgrade(&zn->zn_zap, tag, tx, 0);
                if (err == 0) {
                        err = fzap_add(zn, integer_size, num_integers, val,