Illumos #3006
[zfs.git] / module / zfs / zap.c
index fa7e617..a7bae5e 100644 (file)
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 /*
@@ -114,7 +115,7 @@ fzap_upgrade(zap_t *zap, dmu_tx_t *tx, zap_flags_t flags)
            1<<FZAP_BLOCK_SHIFT(zap), FTAG, &db, DMU_READ_NO_PREFETCH));
        dmu_buf_will_dirty(db, tx);
 
-       l = kmem_zalloc(sizeof (zap_leaf_t), KM_SLEEP);
+       l = kmem_zalloc(sizeof (zap_leaf_t), KM_PUSHPAGE);
        l->l_dbuf = db;
        l->l_phys = db->db_data;
 
@@ -161,7 +162,7 @@ zap_table_grow(zap_t *zap, zap_table_phys_t *tbl,
        } else {
                newblk = zap_allocate_blocks(zap, tbl->zt_numblks * 2);
                tbl->zt_nextblk = newblk;
-               ASSERT3U(tbl->zt_blks_copied, ==, 0);
+               ASSERT0(tbl->zt_blks_copied);
                dmu_prefetch(zap->zap_objset, zap->zap_object,
                    tbl->zt_blk << bs, tbl->zt_numblks << bs);
        }
@@ -338,7 +339,7 @@ zap_grow_ptrtbl(zap_t *zap, dmu_tx_t *tx)
 
                ASSERT3U(zap->zap_f.zap_phys->zap_ptrtbl.zt_shift, ==,
                    ZAP_EMBEDDED_PTRTBL_SHIFT(zap));
-               ASSERT3U(zap->zap_f.zap_phys->zap_ptrtbl.zt_blk, ==, 0);
+               ASSERT0(zap->zap_f.zap_phys->zap_ptrtbl.zt_blk);
 
                newblk = zap_allocate_blocks(zap, 1);
                err = dmu_buf_hold(zap->zap_objset, zap->zap_object,
@@ -390,7 +391,7 @@ static zap_leaf_t *
 zap_create_leaf(zap_t *zap, dmu_tx_t *tx)
 {
        void *winner;
-       zap_leaf_t *l = kmem_alloc(sizeof (zap_leaf_t), KM_SLEEP);
+       zap_leaf_t *l = kmem_alloc(sizeof (zap_leaf_t), KM_PUSHPAGE);
 
        ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
 
@@ -452,7 +453,7 @@ zap_open_leaf(uint64_t blkid, dmu_buf_t *db)
 
        ASSERT(blkid != 0);
 
-       l = kmem_alloc(sizeof (zap_leaf_t), KM_SLEEP);
+       l = kmem_alloc(sizeof (zap_leaf_t), KM_PUSHPAGE);
        rw_init(&l->l_rwlock, NULL, RW_DEFAULT, NULL);
        rw_enter(&l->l_rwlock, RW_WRITER);
        l->l_blkid = blkid;
@@ -474,7 +475,7 @@ zap_open_leaf(uint64_t blkid, dmu_buf_t *db)
         * chain.  There should be no chained leafs (as we have removed
         * support for them).
         */
-       ASSERT3U(l->l_phys->l_hdr.lh_pad1, ==, 0);
+       ASSERT0(l->l_phys->l_hdr.lh_pad1);
 
        /*
         * There should be more hash entries than there can be
@@ -657,9 +658,9 @@ zap_expand_leaf(zap_name_t *zn, zap_leaf_t *l, dmu_tx_t *tx, zap_leaf_t **lp)
        zap_leaf_split(l, nl, zap->zap_normflags != 0);
 
        /* set sibling pointers */
-       for (i = 0; i < (1ULL<<prefix_diff); i++) {
+       for (i = 0; i < (1ULL << prefix_diff); i++) {
                err = zap_set_idx_to_blk(zap, sibling+i, nl->l_blkid, tx);
-               ASSERT3U(err, ==, 0); /* we checked for i/o errors above */
+               ASSERT0(err); /* we checked for i/o errors above */
        }
 
        if (hash & (1ULL << (64 - l->l_phys->l_hdr.lh_prefix_len))) {
@@ -946,6 +947,19 @@ fzap_prefetch(zap_name_t *zn)
  * Helper functions for consumers.
  */
 
+uint64_t
+zap_create_link(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj,
+    const char *name, dmu_tx_t *tx)
+{
+       uint64_t new_obj;
+
+       VERIFY((new_obj = zap_create(os, ot, DMU_OT_NONE, 0, tx)) > 0);
+       VERIFY(zap_add(os, parent_obj, name, sizeof (uint64_t), 1, &new_obj,
+           tx) == 0);
+
+       return (new_obj);
+}
+
 int
 zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
     char *name)
@@ -957,7 +971,7 @@ zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask,
        if (mask == 0)
                mask = -1ULL;
 
-       za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
+       za = kmem_alloc(sizeof (zap_attribute_t), KM_PUSHPAGE);
        for (zap_cursor_init(&zc, os, zapobj);
            (err = zap_cursor_retrieve(&zc, za)) == 0;
            zap_cursor_advance(&zc)) {
@@ -1080,6 +1094,16 @@ zap_add_int_key(objset_t *os, uint64_t obj,
 }
 
 int
+zap_update_int_key(objset_t *os, uint64_t obj,
+    uint64_t key, uint64_t value, dmu_tx_t *tx)
+{
+       char name[20];
+
+       (void) snprintf(name, sizeof (name), "%llx", (longlong_t)key);
+       return (zap_update(os, obj, name, 8, 1, &value, tx));
+}
+
+int
 zap_lookup_int_key(objset_t *os, uint64_t obj, uint64_t key, uint64_t *valuep)
 {
        char name[20];
@@ -1233,13 +1257,13 @@ fzap_cursor_move_to_key(zap_cursor_t *zc, zap_name_t *zn)
                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;
+       if (err == 0) {
+               zc->zc_leaf = l;
+               zc->zc_hash = zeh.zeh_hash;
+               zc->zc_cd = zeh.zeh_cd;
+       }
 
+       rw_exit(&l->l_rwlock);
        return (err);
 }