HAMMER VFS - Bump the default hammer rev to 6
[dragonfly.git] / sys / vfs / hammer / hammer_disk.h
index ef9127f..d0fed5a 100644 (file)
@@ -91,6 +91,8 @@
 #define HAMMER_OFF_LONG_REC_MASK 0x0FFFFFFFFF000000ULL /* recovery boundary */
 #define HAMMER_RECOVERY_BND    0x0000000001000000ULL
 
+#define HAMMER_OFF_BAD         ((hammer_off_t)-1)
+
 /*
  * The current limit of volumes that can make up a HAMMER FS
  */
@@ -287,12 +289,20 @@ typedef struct hammer_blockmap_layer1 *hammer_blockmap_layer1_t;
 #define HAMMER_LAYER1_CRCSIZE  \
        offsetof(struct hammer_blockmap_layer1, layer1_crc)
 
+/*
+ * layer2 entry for 8MB bigblock.
+ *
+ * NOTE: bytes_free is signed and can legally go negative if/when data
+ *      de-dup occurs.  This field will never go higher than
+ *      HAMMER_LARGEBLOCK_SIZE.  If exactly HAMMER_LARGEBLOCK_SIZE
+ *      the big-block is completely free.
+ */
 struct hammer_blockmap_layer2 {
        u_int8_t        zone;           /* typed allocation zone */
        u_int8_t        unused01;
        u_int16_t       unused02;
        u_int32_t       append_off;     /* allocatable space index */
-       u_int32_t       bytes_free;     /* bytes free within this bigblock */
+       int32_t         bytes_free;     /* bytes free within this bigblock */
        hammer_crc_t    entry_crc;
 };
 
@@ -386,6 +396,11 @@ typedef struct hammer_blockmap_layer2 *hammer_blockmap_layer2_t;
  * (3) Data overwrite for nohistory operations covered by REDO records
  *     can be supported (instead of rolling a new block allocation),
  *     by rolling UNDO for the prior contents of the data.
+ *
+ *                             HAMMER VERSION 5 CHANGES
+ *
+ * Hammer version 5 contains a minor adjustment making layer2's bytes_free
+ * field signed, allowing dedup to push it into the negative domain.
  */
 #define HAMMER_HEAD_ONDISK_SIZE                32
 #define HAMMER_HEAD_ALIGN              8
@@ -440,7 +455,7 @@ typedef struct hammer_fifo_tail *hammer_fifo_tail_t;
 /*
  * Misc FIFO structures.
  *
- * NOTE: redo records are for version 4+ filesystems.
+ * UNDO - Raw meta-data media updates.
  */
 struct hammer_fifo_undo {
        struct hammer_fifo_head head;
@@ -450,14 +465,61 @@ struct hammer_fifo_undo {
        /* followed by data */
 };
 
+/*
+ * REDO (HAMMER version 4+) - Logical file writes/truncates.
+ *
+ * REDOs contain information which will be duplicated in a later meta-data
+ * update, allowing fast write()+fsync() operations.  REDOs can be ignored
+ * without harming filesystem integrity but must be processed if fsync()
+ * semantics are desired.
+ *
+ * Unlike UNDOs which are processed backwards within the recovery span,
+ * REDOs must be processed forwards starting further back (starting outside
+ * the recovery span).
+ *
+ *     WRITE   - Write logical file (with payload).  Executed both
+ *               out-of-span and in-span.  Out-of-span WRITEs may be
+ *               filtered out by TERMs.
+ *
+ *     TRUNC   - Truncate logical file (no payload).  Executed both
+ *               out-of-span and in-span.  Out-of-span WRITEs may be
+ *               filtered out by TERMs.
+ *
+ *     TERM_*  - Indicates meta-data was committed (if out-of-span) or
+ *               will be rolled-back (in-span).  Any out-of-span TERMs
+ *               matching earlier WRITEs remove those WRITEs from
+ *               consideration as they might conflict with a later data
+ *               commit (which is not being rolled-back).
+ *
+ *     SYNC    - The earliest in-span SYNC (the last one when scanning
+ *               backwards) tells the recovery code how far out-of-span
+ *               it must go to run REDOs.
+ *
+ * NOTE: WRITEs do not always have matching TERMs even under
+ *      perfect conditions because truncations might remove the
+ *      buffers from consideration.  I/O problems can also remove
+ *      buffers from consideration.
+ *
+ *      TRUNCSs do not always have matching TERMs because several
+ *      truncations may be aggregated together into a single TERM.
+ */
 struct hammer_fifo_redo {
        struct hammer_fifo_head head;
        int64_t                 redo_objid;     /* file being written */
        hammer_off_t            redo_offset;    /* logical offset in file */
        int32_t                 redo_data_bytes;
-       int32_t                 redo_reserved01;
+       u_int32_t               redo_flags;
+       u_int32_t               redo_localization;
+       u_int32_t               redo_reserved;
+       u_int64_t               redo_mtime;     /* set mtime */
 };
 
+#define HAMMER_REDO_WRITE      0x00000001
+#define HAMMER_REDO_TRUNC      0x00000002
+#define HAMMER_REDO_TERM_WRITE 0x00000004
+#define HAMMER_REDO_TERM_TRUNC 0x00000008
+#define HAMMER_REDO_SYNC       0x00000010
+
 union hammer_fifo_any {
        struct hammer_fifo_head head;
        struct hammer_fifo_undo undo;
@@ -583,14 +645,16 @@ typedef struct hammer_volume_ondisk *hammer_volume_ondisk_t;
         sizeof(hammer_crc_t))
 
 #define HAMMER_VOL_VERSION_MIN         1       /* minimum supported version */
-#define HAMMER_VOL_VERSION_DEFAULT     4       /* newfs default version */
-#define HAMMER_VOL_VERSION_WIP         5       /* version >= this is WIP */
-#define HAMMER_VOL_VERSION_MAX         4       /* maximum supported version */
+#define HAMMER_VOL_VERSION_DEFAULT     6       /* newfs default version */
+#define HAMMER_VOL_VERSION_WIP         7       /* version >= this is WIP */
+#define HAMMER_VOL_VERSION_MAX         6       /* maximum supported version */
 
 #define HAMMER_VOL_VERSION_ONE         1
 #define HAMMER_VOL_VERSION_TWO         2       /* new dirent layout (2.3+) */
 #define HAMMER_VOL_VERSION_THREE       3       /* new snapshot layout (2.5+) */
 #define HAMMER_VOL_VERSION_FOUR                4       /* new undo/flush (2.5+) */
+#define HAMMER_VOL_VERSION_FIVE                5       /* dedup (2.9+) */
+#define HAMMER_VOL_VERSION_SIX         6       /* DIRHASH_ALG1 */
 
 /*
  * Record types are fairly straightforward.  The B-Tree includes the record
@@ -753,6 +817,14 @@ struct hammer_symlink_data {
  *
  * sync_low_tid is not yet used but will represent the highest pruning
  * end-point, after which full history is available.
+ *
+ * We need to pack this structure making it equally sized on both 32-bit and
+ * 64-bit machines as it is part of struct hammer_ioc_mrecord_pfs which is
+ * send over the wire in hammer mirror operations. Only on 64-bit machines
+ * the size of this struct differ when packed or not. This leads us to the
+ * situation where old 64-bit systems (using the non-packed structure),
+ * which were never able to mirror to/from 32-bit systems, are now no longer
+ * able to mirror to/from newer 64-bit systems (using the packed structure).
  */
 struct hammer_pseudofs_data {
        hammer_tid_t    sync_low_tid;   /* full history beyond this point */
@@ -774,7 +846,7 @@ struct hammer_pseudofs_data {
        int32_t         prune_min;      /* do not prune recent history */
        int32_t         prune_max;      /* do not retain history beyond here */
        int32_t         reserved[16];
-};
+} __packed;
 
 typedef struct hammer_pseudofs_data *hammer_pseudofs_data_t;