]> git.proxmox.com Git - mirror_zfs.git/blobdiff - include/sys/dbuf.h
dmu: Allow buffer fills to fail
[mirror_zfs.git] / include / sys / dbuf.h
index 959e111cee7ac18fa389edc32bfb8367f300189f..3808a04cba8011f517437baec1e83b66c3542f27 100644 (file)
@@ -6,7 +6,7 @@
  * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
  * See the License for the specific language governing permissions
  * and limitations under the License.
  *
@@ -55,26 +55,31 @@ extern "C" {
 #define        DB_RF_NEVERWAIT         (1 << 4)
 #define        DB_RF_CACHED            (1 << 5)
 #define        DB_RF_NO_DECRYPT        (1 << 6)
+#define        DB_RF_PARTIAL_FIRST     (1 << 7)
+#define        DB_RF_PARTIAL_MORE      (1 << 8)
 
 /*
  * The simplified state transition diagram for dbufs looks like:
  *
- *             +----> READ ----+
- *             |               |
- *             |               V
- *  (alloc)-->UNCACHED      CACHED-->EVICTING-->(free)
- *             |               ^        ^
- *             |               |        |
- *             +----> FILL ----+        |
- *             |                        |
- *             |                        |
- *             +--------> NOFILL -------+
+ *                  +--> READ --+
+ *                  |           |
+ *                  |           V
+ *  (alloc)-->UNCACHED       CACHED-->EVICTING-->(free)
+ *             ^    |           ^        ^
+ *             |    |           |        |
+ *             |    +--> FILL --+        |
+ *             |    |                    |
+ *             |    |                    |
+ *             |    +------> NOFILL -----+
+ *             |               |
+ *             +---------------+
  *
  * DB_SEARCH is an invalid state for a dbuf. It is used by dbuf_free_range
  * to find all dbufs in a range of a dnode and must be less than any other
  * dbuf_states_t (see comment on dn_dbufs in dnode.h).
  */
 typedef enum dbuf_states {
+       DB_MARKER = -2,
        DB_SEARCH = -1,
        DB_UNCACHED,
        DB_FILL,
@@ -170,6 +175,7 @@ typedef struct dbuf_dirty_record {
                        override_states_t dr_override_state;
                        uint8_t dr_copies;
                        boolean_t dr_nopwrite;
+                       boolean_t dr_brtwrite;
                        boolean_t dr_has_raw_params;
 
                        /*
@@ -190,7 +196,7 @@ typedef struct dbuf_dirty_record {
                        uint64_t dr_blkid;
                        abd_t *dr_abd;
                        zio_prop_t dr_props;
-                       enum zio_flag dr_flags;
+                       zio_flag_t dr_flags;
                } dll;
        } dt;
 } dbuf_dirty_record_t;
@@ -294,6 +300,8 @@ typedef struct dmu_buf_impl {
        /* Tells us which dbuf cache this dbuf is in, if any */
        dbuf_cached_state_t db_caching_status;
 
+       uint64_t db_hash;
+
        /* Data which is unique to data (leaf) blocks: */
 
        /* User callback information. */
@@ -319,14 +327,19 @@ typedef struct dmu_buf_impl {
        uint8_t db_pending_evict;
 
        uint8_t db_dirtycnt;
+
+       /* The buffer was partially read.  More reads may follow. */
+       uint8_t db_partial_read;
 } dmu_buf_impl_t;
 
-#define        DBUF_RWLOCKS 8192
-#define        DBUF_HASH_RWLOCK(h, idx) (&(h)->hash_rwlocks[(idx) & (DBUF_RWLOCKS-1)])
+#define        DBUF_HASH_MUTEX(h, idx) \
+       (&(h)->hash_mutexes[(idx) & ((h)->hash_mutex_mask)])
+
 typedef struct dbuf_hash_table {
        uint64_t hash_table_mask;
+       uint64_t hash_mutex_mask;
        dmu_buf_impl_t **hash_table;
-       krwlock_t hash_rwlocks[DBUF_RWLOCKS] ____cacheline_aligned;
+       kmutex_t *hash_mutexes;
 } dbuf_hash_table_t;
 
 typedef void (*dbuf_prefetch_fn)(void *, uint64_t, uint64_t, boolean_t);
@@ -362,23 +375,25 @@ void dbuf_rele_and_unlock(dmu_buf_impl_t *db, const void *tag,
     boolean_t evicting);
 
 dmu_buf_impl_t *dbuf_find(struct objset *os, uint64_t object, uint8_t level,
-    uint64_t blkid);
+    uint64_t blkid, uint64_t *hash_out);
 
 int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags);
+void dmu_buf_will_clone(dmu_buf_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 dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx, boolean_t canfail);
+boolean_t dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx, boolean_t failed);
 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);
 dbuf_dirty_record_t *dbuf_dirty_lightweight(dnode_t *dn, uint64_t blkid,
     dmu_tx_t *tx);
+boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);
 void dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data,
     bp_embedded_type_t etype, enum zio_compress comp,
     int uncompressed_size, int compressed_size, int byteorder, dmu_tx_t *tx);
 
 int dmu_lightweight_write_by_dnode(dnode_t *dn, uint64_t offset, abd_t *abd,
-    const struct zio_prop *zp, enum zio_flag flags, dmu_tx_t *tx);
+    const struct zio_prop *zp, zio_flag_t flags, dmu_tx_t *tx);
 
 void dmu_buf_redact(dmu_buf_t *dbuf, dmu_tx_t *tx);
 void dbuf_destroy(dmu_buf_impl_t *db);