Add linux compatibility
[zfs.git] / module / zfs / include / sys / dbuf.h
index 75ce272..cf1bbc0 100644 (file)
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef        _SYS_DBUF_H
 #include <sys/arc.h>
 #include <sys/zfs_context.h>
 #include <sys/refcount.h>
+#include <sys/zrlock.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define        DB_BONUS_BLKID (-1ULL)
 #define        IN_DMU_SYNC 2
 
 /*
@@ -75,7 +74,6 @@ typedef enum dbuf_states {
        DB_EVICTING
 } dbuf_states_t;
 
-struct objset_impl;
 struct dnode;
 struct dmu_tx;
 
@@ -85,9 +83,6 @@ struct dmu_tx;
  * etc.
  */
 
-#define        LIST_LINK_INACTIVE(link) \
-       ((link)->list_next == NULL && (link)->list_prev == NULL)
-
 struct dmu_buf_impl;
 
 typedef enum override_states {
@@ -134,6 +129,7 @@ typedef struct dbuf_dirty_record {
                        arc_buf_t *dr_data;
                        blkptr_t dr_overridden_by;
                        override_states_t dr_override_state;
+                       uint8_t dr_copies;
                } dl;
        } dt;
 } dbuf_dirty_record_t;
@@ -148,18 +144,20 @@ typedef struct dmu_buf_impl {
        dmu_buf_t db;
 
        /* the objset we belong to */
-       struct objset_impl *db_objset;
+       struct objset *db_objset;
 
        /*
-        * the dnode we belong to (NULL when evicted)
+        * handle to safely access the dnode we belong to (NULL when evicted)
         */
-       struct dnode *db_dnode;
+       struct dnode_handle *db_dnode_handle;
 
        /*
         * our parent buffer; if the dnode points to us directly,
-        * db_parent == db_dnode->dn_dbuf
+        * db_parent == db_dnode_handle->dnh_dnode->dn_dbuf
         * only accessed by sync thread ???
         * (NULL when evicted)
+        * May change from NULL to non-NULL under the protection of db_mtx
+        * (see dbuf_check_blkptr())
         */
        struct dmu_buf_impl *db_parent;
 
@@ -242,6 +240,10 @@ uint64_t dbuf_whichblock(struct dnode *di, uint64_t offset);
 
 dmu_buf_impl_t *dbuf_create_tlib(struct dnode *dn, char *data);
 void dbuf_create_bonus(struct dnode *dn);
+int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx);
+void dbuf_spill_hold(struct dnode *dn, dmu_buf_impl_t **dbp, void *tag);
+
+void dbuf_rm_spill(struct dnode *dn, dmu_tx_t *tx);
 
 dmu_buf_impl_t *dbuf_hold(struct dnode *dn, uint64_t blkid, void *tag);
 dmu_buf_impl_t *dbuf_hold_level(struct dnode *dn, int level, uint64_t blkid,
@@ -255,6 +257,7 @@ void dbuf_add_ref(dmu_buf_impl_t *db, void *tag);
 uint64_t dbuf_refcount(dmu_buf_impl_t *db);
 
 void dbuf_rele(dmu_buf_impl_t *db, void *tag);
+void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag);
 
 dmu_buf_impl_t *dbuf_find(struct dnode *dn, uint8_t level, uint64_t blkid);
 
@@ -264,7 +267,9 @@ void dbuf_fill_done(dmu_buf_impl_t *db, dmu_tx_t *tx);
 void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx);
 void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx);
 void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx);
+void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx);
 dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
+arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);
 
 void dbuf_clear(dmu_buf_impl_t *db);
 void dbuf_evict(dmu_buf_impl_t *db);
@@ -272,30 +277,53 @@ void dbuf_evict(dmu_buf_impl_t *db);
 void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 void dbuf_unoverride(dbuf_dirty_record_t *dr);
 void dbuf_sync_list(list_t *list, dmu_tx_t *tx);
+void dbuf_release_bp(dmu_buf_impl_t *db);
 
 void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end,
     struct dmu_tx *);
 
 void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx);
 
+#define        DB_DNODE(_db)           ((_db)->db_dnode_handle->dnh_dnode)
+#define        DB_DNODE_LOCK(_db)      ((_db)->db_dnode_handle->dnh_zrlock)
+#define        DB_DNODE_ENTER(_db)     (zrl_add(&DB_DNODE_LOCK(_db)))
+#define        DB_DNODE_EXIT(_db)      (zrl_remove(&DB_DNODE_LOCK(_db)))
+#define        DB_DNODE_HELD(_db)      (!zrl_is_zero(&DB_DNODE_LOCK(_db)))
+#define        DB_GET_SPA(_spa_p, _db) {               \
+       dnode_t *__dn;                          \
+       DB_DNODE_ENTER(_db);                    \
+       __dn = DB_DNODE(_db);                   \
+       *(_spa_p) = __dn->dn_objset->os_spa;    \
+       DB_DNODE_EXIT(_db);                     \
+}
+#define        DB_GET_OBJSET(_os_p, _db) {             \
+       dnode_t *__dn;                          \
+       DB_DNODE_ENTER(_db);                    \
+       __dn = DB_DNODE(_db);                   \
+       *(_os_p) = __dn->dn_objset;             \
+       DB_DNODE_EXIT(_db);                     \
+}
+
 void dbuf_init(void);
 void dbuf_fini(void);
 
-#define        DBUF_IS_METADATA(db)    \
-       ((db)->db_level > 0 || dmu_ot[(db)->db_dnode->dn_type].ot_metadata)
+boolean_t dbuf_is_metadata(dmu_buf_impl_t *db);
+
+#define        DBUF_IS_METADATA(_db)   \
+       (dbuf_is_metadata(_db))
 
-#define        DBUF_GET_BUFC_TYPE(db)  \
-       (DBUF_IS_METADATA(db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA)
+#define        DBUF_GET_BUFC_TYPE(_db) \
+       (DBUF_IS_METADATA(_db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA)
 
-#define        DBUF_IS_CACHEABLE(db)                                           \
-       ((db)->db_objset->os_primary_cache == ZFS_CACHE_ALL ||          \
-       (DBUF_IS_METADATA(db) &&                                        \
-       ((db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA)))
+#define        DBUF_IS_CACHEABLE(_db)                                          \
+       ((_db)->db_objset->os_primary_cache == ZFS_CACHE_ALL ||         \
+       (DBUF_IS_METADATA(_db) &&                                       \
+       ((_db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA)))
 
-#define        DBUF_IS_L2CACHEABLE(db)                                         \
-       ((db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL ||        \
-       (DBUF_IS_METADATA(db) &&                                        \
-       ((db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA)))
+#define        DBUF_IS_L2CACHEABLE(_db)                                        \
+       ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL ||       \
+       (DBUF_IS_METADATA(_db) &&                                       \
+       ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA)))
 
 #ifdef ZFS_DEBUG
 
@@ -323,10 +351,10 @@ _NOTE(CONSTCOND) } while (0)
 #define        dprintf_dbuf_bp(db, bp, fmt, ...) do {                  \
        if (zfs_flags & ZFS_DEBUG_DPRINTF) {                    \
        char *__blkbuf = kmem_alloc(BP_SPRINTF_LEN, KM_SLEEP);  \
-       sprintf_blkptr(__blkbuf, BP_SPRINTF_LEN, bp);           \
+       sprintf_blkptr(__blkbuf, bp);                           \
        dprintf_dbuf(db, fmt " %s\n", __VA_ARGS__, __blkbuf);   \
        kmem_free(__blkbuf, BP_SPRINTF_LEN);                    \
-       }                                                       \
+       }                                                       \
 _NOTE(CONSTCOND) } while (0)
 
 #define        DBUF_VERIFY(db) dbuf_verify(db)