Print this page
3752 want more verifiable dbuf user eviction
Submitted by:   Justin Gibbs <justing@spectralogic.com>
Submitted by:   Will Andrews <willa@spectralogic.com>

@@ -60,19 +60,24 @@
         uint64_t mz_pad[5];
         mzap_ent_phys_t mz_chunk[1];
         /* actually variable size depending on block size */
 } mzap_phys_t;
 
+typedef struct mzap_dbuf {
+        uint8_t mzdb_pad[offsetof(dmu_buf_t, db_data)];
+        mzap_phys_t *mzdb_data;
+} mzap_dbuf_t;
+
 typedef struct mzap_ent {
         avl_node_t mze_node;
         int mze_chunkid;
         uint64_t mze_hash;
         uint32_t mze_cd; /* copy from mze_phys->mze_cd */
 } mzap_ent_t;
 
 #define MZE_PHYS(zap, mze) \
-        (&(zap)->zap_m.zap_phys->mz_chunk[(mze)->mze_chunkid])
+        (&(zap)->zap_m_phys->mz_chunk[(mze)->mze_chunkid])
 
 /*
  * The (fat) zap is stored in one object. It is an array of
  * 1<<FZAP_BLOCK_SHIFT byte blocks. The layout looks like one of:
  *

@@ -102,11 +107,11 @@
  * The embedded pointer table starts half-way through the block.  Since
  * the pointer table itself is half the block, it starts at (64-bit)
  * word number (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap)).
  */
 #define ZAP_EMBEDDED_PTRTBL_ENT(zap, idx) \
-        ((uint64_t *)(zap)->zap_f.zap_phys) \
+        ((uint64_t *)(zap)->zap_f_phys) \
         [(idx) + (1<<ZAP_EMBEDDED_PTRTBL_SHIFT(zap))]
 
 /*
  * TAKE NOTE:
  * If zap_phys_t is modified, zap_byteswap() must be modified.

@@ -137,39 +142,50 @@
          */
 } zap_phys_t;
 
 typedef struct zap_table_phys zap_table_phys_t;
 
+typedef struct fzap_dbuf {
+        uint8_t fzdb_pad[offsetof(dmu_buf_t, db_data)];
+        zap_phys_t *fzdb_data;
+} fzap_dbuf_t;
+
 typedef struct zap {
+        dmu_buf_user_t db_evict;
         objset_t *zap_objset;
         uint64_t zap_object;
-        struct dmu_buf *zap_dbuf;
+        union {
+                dmu_buf_t *zap_dmu_db;
+                mzap_dbuf_t *mzap_db;
+                fzap_dbuf_t *fzap_db;
+        } zap_db_u;
         krwlock_t zap_rwlock;
         boolean_t zap_ismicro;
         int zap_normflags;
         uint64_t zap_salt;
         union {
                 struct {
-                        zap_phys_t *zap_phys;
-
-                        /*
-                         * zap_num_entries_mtx protects
-                         * zap_num_entries
-                         */
+                        /* protects zap_num_entries */
                         kmutex_t zap_num_entries_mtx;
                         int zap_block_shift;
                 } zap_fat;
                 struct {
-                        mzap_phys_t *zap_phys;
                         int16_t zap_num_entries;
                         int16_t zap_num_chunks;
                         int16_t zap_alloc_next;
                         avl_tree_t zap_avl;
                 } zap_micro;
         } zap_u;
 } zap_t;
 
+/* See sys/dmu.h:dmu_buf_user_t for why we have these. */
+#define zap_dbuf        zap_db_u.zap_dmu_db
+#define zap_f           zap_u.zap_fat
+#define zap_m           zap_u.zap_micro
+#define zap_f_phys      zap_db_u.fzap_db->fzdb_data
+#define zap_m_phys      zap_db_u.mzap_db->mzdb_data
+
 typedef struct zap_name {
         zap_t *zn_zap;
         int zn_key_intlen;
         const void *zn_key_orig;
         int zn_key_orig_numints;

@@ -178,18 +194,15 @@
         uint64_t zn_hash;
         matchtype_t zn_matchtype;
         char zn_normbuf[ZAP_MAXNAMELEN];
 } zap_name_t;
 
-#define zap_f   zap_u.zap_fat
-#define zap_m   zap_u.zap_micro
-
 boolean_t zap_match(zap_name_t *zn, const char *matchname);
 int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx,
     krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp);
 void zap_unlockdir(zap_t *zap);
-void zap_evict(dmu_buf_t *db, void *vmzap);
+void zap_evict(dmu_buf_user_t *dbu);
 zap_name_t *zap_name_alloc(zap_t *zap, const char *key, matchtype_t mt);
 void zap_name_free(zap_name_t *zn);
 int zap_hashbits(zap_t *zap);
 uint32_t zap_maxcd(zap_t *zap);
 uint64_t zap_getflags(zap_t *zap);