hammer - HAMMER Version 7
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 17 Mar 2017 21:06:24 +0000 (14:06 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 27 Mar 2017 06:43:09 +0000 (23:43 -0700)
* Add support for version 7 which changes the CRC mechanic from the
  old slow CRC code to the faster ISCSI CRC code.  We don't use the CRC
  instruction yet but ths base ISCSI CRC from FreeBSD is 6x faster than
  the CRC code we were using before.

* Change newfs_hammer default to version 7 (for master).

32 files changed:
sbin/hammer/blockmap.c
sbin/hammer/cmd_blockmap.c
sbin/hammer/cmd_cleanup.c
sbin/hammer/cmd_config.c
sbin/hammer/cmd_mirror.c
sbin/hammer/cmd_pfs.c
sbin/hammer/cmd_recover.c
sbin/hammer/cmd_show.c
sbin/hammer/cmd_snapshot.c
sbin/hammer/cmd_softprune.c
sbin/hammer/cmd_strip.c
sbin/hammer/cmd_version.c
sbin/hammer/hammer.8
sbin/hammer/hammer.c
sbin/hammer/hammer_util.h
sbin/hammer/ondisk.c
sbin/newfs_hammer/newfs_hammer.c
sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_blockmap.c
sys/vfs/hammer/hammer_btree.c
sys/vfs/hammer/hammer_crc.h
sys/vfs/hammer/hammer_disk.h
sys/vfs/hammer/hammer_flusher.c
sys/vfs/hammer/hammer_io.c
sys/vfs/hammer/hammer_ioctl.c
sys/vfs/hammer/hammer_object.c
sys/vfs/hammer/hammer_ondisk.c
sys/vfs/hammer/hammer_reblock.c
sys/vfs/hammer/hammer_recover.c
sys/vfs/hammer/hammer_redo.c
sys/vfs/hammer/hammer_undo.c
sys/vfs/hammer/hammer_volume.c

index 1ff4eb2..48690dc 100644 (file)
@@ -82,7 +82,7 @@ alloc_undo_bigblock(struct volume_info *volume)
        layer1 = get_buffer_data(layer1_offset, &buffer1, 0);
        assert(layer1->phys_offset != HAMMER_BLOCKMAP_UNAVAIL);
        --layer1->blocks_free;
-       hammer_crc_set_layer1(layer1);
+       hammer_crc_set_layer1(HammerVersion, layer1);
        buffer1->cache.modified = 1;
 
        /*
@@ -95,7 +95,7 @@ alloc_undo_bigblock(struct volume_info *volume)
        layer2->zone = HAMMER_ZONE_UNDO_INDEX;
        layer2->append_off = HAMMER_BIGBLOCK_SIZE;
        layer2->bytes_free = 0;
-       hammer_crc_set_layer2(layer2);
+       hammer_crc_set_layer2(HammerVersion, layer2);
        buffer2->cache.modified = 1;
 
        --volume->ondisk->vol0_stat_freebigblocks;
@@ -175,7 +175,7 @@ again:
         */
        if (layer2->zone == 0) {
                --layer1->blocks_free;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(HammerVersion, layer1);
                layer2->zone = zone;
                --volume->ondisk->vol0_stat_freebigblocks;
                assert(layer2->bytes_free == HAMMER_BIGBLOCK_SIZE);
@@ -192,7 +192,7 @@ again:
        *result_offp = blockmap->next_offset;
        blockmap->next_offset += bytes;
        layer2->append_off = (int)blockmap->next_offset & HAMMER_BIGBLOCK_MASK;
-       hammer_crc_set_layer2(layer2);
+       hammer_crc_set_layer2(HammerVersion, layer2);
 
        ptr = get_buffer_data(*result_offp, bufferp, 0);
        (*bufferp)->cache.modified = 1;
index 5ea245c..ddc1ca4 100644 (file)
@@ -130,7 +130,7 @@ dump_blockmap(int zone)
                layer1 = get_buffer_data(layer1_offset, &buffer1, 0);
 
                xerr = ' ';  /* good */
-               if (!hammer_crc_test_layer1(layer1)) {
+               if (!hammer_crc_test_layer1(HammerVersion, layer1)) {
                        xerr = 'B';
                        ++num_bad_layer1;
                }
@@ -156,7 +156,7 @@ dump_blockmap(int zone)
                        layer2 = get_buffer_data(layer2_offset, &buffer2, 0);
 
                        xerr = aerr = ferr = ' ';  /* good */
-                       if (!hammer_crc_test_layer2(layer2)) {
+                       if (!hammer_crc_test_layer2(HammerVersion, layer2)) {
                                xerr = 'B';
                                ++num_bad_layer2;
                        }
@@ -288,7 +288,7 @@ check_btree_node(hammer_off_t node_offset, int depth)
        if (node == NULL) {
                badc = 'B';
                badm = 'I';
-       } else if (!hammer_crc_test_btree(node)) {
+       } else if (!hammer_crc_test_btree(HammerVersion, node)) {
                badc = 'B';
        }
 
index aa339bd..7b97fed 100644 (file)
@@ -197,6 +197,7 @@ do_cleanup(const char *path)
                close(fd);
                return;
        }
+       HammerVersion = version.cur_version;
 
        bzero(&config, sizeof(config));
        if (version.cur_version >= 3) {
index 9f84e01..c1e308b 100644 (file)
@@ -206,6 +206,7 @@ config_get(const char *dirpath, struct hammer_ioc_config *config)
                err(2, "hammer config: unable to open directory %s", dirpath);
        if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                errx(2, "hammer config: not a HAMMER filesystem!");
+       HammerVersion = version.cur_version;
        if (ioctl(fd, HAMMERIOC_GET_CONFIG, config) < 0)
                errx(2, "hammer config: config_get");
        close(fd);
@@ -222,6 +223,7 @@ config_set(const char *dirpath, struct hammer_ioc_config *config)
                errx(2, "hammer config: unable to open directory %s", dirpath);
        if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                errx(2, "hammer config: not a HAMMER filesystem!");
+       HammerVersion = version.cur_version;
        if (ioctl(fd, HAMMERIOC_SET_CONFIG, config) < 0)
                err(2, "hammer config");
        close(fd);
index 8fd69c1..7bfffd1 100644 (file)
@@ -1343,7 +1343,7 @@ read_mrecords(int fd, char *buf, u_int size, hammer_ioc_mrecord_head_t pickup)
                        }
                        if (mrec->rec.leaf.data_len &&
                            mrec->rec.leaf.data_offset &&
-                           hammer_crc_test_leaf(&mrec->rec + 1, &mrec->rec.leaf) == 0) {
+                           hammer_crc_test_leaf(HammerVersion, &mrec->rec + 1, &mrec->rec.leaf) == 0) {
                                fprintf(stderr,
                                        "read_mrecords: data_crc did not "
                                        "match data! obj=%016jx key=%016jx\n",
index bee829b..40b3231 100644 (file)
@@ -541,6 +541,7 @@ dump_pfsd(hammer_pseudofs_data_t pfsd, int fd)
                bzero(&version, sizeof(version));
                if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                        return;
+               HammerVersion = version.cur_version;
                if (version.cur_version < 3) {
                        if (hammer_is_pfs_slave(pfsd)) {
                                printf("    snapshots directory not set for "
index d714c04..a4189da 100644 (file)
@@ -225,8 +225,10 @@ hammer_cmd_recover(char **av, int ac)
                        }
 
                        if (b) {
-                               if (hammer_crc_test_layer1(&b->layer1) &&
-                                   hammer_crc_test_layer2(&b->layer2) &&
+                               if (hammer_crc_test_layer1(HammerVersion,
+                                                          &b->layer1) &&
+                                   hammer_crc_test_layer2(HammerVersion,
+                                                          &b->layer2) &&
                                    off_blk >= b->layer2.append_off) {
                                        off = HAMMER_ZONE_LAYER2_NEXT_OFFSET(off);
                                        continue;
@@ -281,7 +283,7 @@ recover_top(char *ptr, hammer_off_t offset)
        int isnode;
 
        for (node = (void *)ptr; (char *)node < ptr + HAMMER_BUFSIZE; ++node) {
-               isnode = hammer_crc_test_btree(node);
+               isnode = hammer_crc_test_btree(HammerVersion, node);
                maxcount = hammer_node_max_elements(node->type);
 
                if (DebugOpt) {
@@ -774,7 +776,7 @@ scan_raw_limit(void)
                                HAMMER_BLOCKMAP_LAYER1_OFFSET(phys_offset);
                layer1 = get_buffer_data(layer1_offset, &buffer1, 0);
 
-               if (!hammer_crc_test_layer1(layer1)) {
+               if (!hammer_crc_test_layer1(HammerVersion, layer1)) {
                        offset = 0; /* failed */
                        goto end;
                }
@@ -791,7 +793,7 @@ scan_raw_limit(void)
                                        HAMMER_BLOCKMAP_LAYER2_OFFSET(block_offset);
                        layer2 = get_buffer_data(layer2_offset, &buffer2, 0);
 
-                       if (!hammer_crc_test_layer2(layer2)) {
+                       if (!hammer_crc_test_layer2(HammerVersion, layer2)) {
                                offset = 0; /* failed */
                                goto end;
                        }
@@ -841,7 +843,7 @@ scan_bigblocks(int target_zone)
                layer1 = get_buffer_data(layer1_offset, &buffer1, 0);
 
                /*
-               if (!hammer_crc_test_layer1(layer1)) {
+               if (!hammer_crc_test_layer1(HammerVersion, layer1)) {
                }
                */
                if (layer1->phys_offset == HAMMER_BLOCKMAP_UNAVAIL)
@@ -859,7 +861,7 @@ scan_bigblocks(int target_zone)
                        layer2 = get_buffer_data(layer2_offset, &buffer2, 0);
 
                        /*
-                       if (!hammer_crc_test_layer2(layer2)) {
+                       if (!hammer_crc_test_layer2(HammerVersion, layer2)) {
                        }
                        */
                        if (layer2->zone == target_zone) {
index 0fadf28..d00bb9b 100644 (file)
@@ -63,8 +63,11 @@ static int get_elm_flags(hammer_node_ondisk_t node, hammer_off_t node_offset,
 static int test_lr(hammer_btree_elm_t elm, hammer_btree_elm_t lbe);
 static int test_rbn_lr(hammer_btree_elm_t elm, hammer_btree_elm_t lbe);
 static void print_bigblock_fill(hammer_off_t offset);
-static const char *check_data_crc(hammer_btree_elm_t elm);
-static uint32_t get_buf_crc(hammer_off_t buf_offset, int32_t buf_len);
+static const char *check_data_crc(hammer_btree_elm_t elm, const char **whichp);
+static hammer_crc_t get_leaf_crc(uint32_t vol_version, void *data,
+       hammer_btree_leaf_elm_t leaf, const char **whichp);
+static uint32_t get_buf_crc(hammer_off_t buf_offset, int32_t buf_len,
+       uint32_t leaf_crc, const char **whichp);
 static void print_record(hammer_btree_elm_t elm);
 static int init_btree_search(const char *arg);
 static int test_btree_search(hammer_btree_elm_t elm);
@@ -189,7 +192,7 @@ print_btree_node(hammer_off_t node_offset, hammer_tid_t mirror_tid,
                badc = 'B';
                badm = 'I';
        } else {
-               if (!hammer_crc_test_btree(node))
+               if (!hammer_crc_test_btree(HammerVersion, node))
                        badc = 'B';
                if (node->mirror_tid > mirror_tid) {
                        badc = 'B';
@@ -340,6 +343,7 @@ print_btree_elm(hammer_node_ondisk_t node, hammer_off_t node_offset,
        char rootelm;
        const char *label;
        const char *p;
+       const char *which;
        int flags;
        int i = ((char*)elm - (char*)node) / (int)sizeof(*elm) - 1;
 
@@ -406,8 +410,8 @@ print_btree_elm(hammer_node_ondisk_t node, hammer_off_t node_offset,
                        printf(" dataoff=%016jx/%d",
                               (uintmax_t)elm->leaf.data_offset,
                               elm->leaf.data_len);
-                       p = check_data_crc(elm);
-                       printf(" crc=%08x", elm->leaf.data_crc);
+                       p = check_data_crc(elm, &which);
+                       printf(" %scrc=%08x", which, elm->leaf.data_crc);
                        if (p) {
                                printf(" error=%s", p);
                                ++num_bad_rec;
@@ -620,7 +624,7 @@ print_bigblock_fill(hammer_off_t offset)
  */
 static
 const char *
-check_data_crc(hammer_btree_elm_t elm)
+check_data_crc(hammer_btree_elm_t elm, const char **whichp)
 {
        struct buffer_info *data_buffer;
        hammer_off_t data_offset;
@@ -628,11 +632,13 @@ check_data_crc(hammer_btree_elm_t elm)
        uint32_t crc;
        char *ptr;
 
+       *whichp = "";
        data_offset = elm->leaf.data_offset;
        data_len = elm->leaf.data_len;
        data_buffer = NULL;
-       if (data_offset == 0 || data_len == 0)
+       if (data_offset == 0 || data_len == 0) {
                return("ZO");  /* zero offset or length */
+       }
 
        crc = 0;
        switch (elm->leaf.base.rec_type) {
@@ -640,11 +646,12 @@ check_data_crc(hammer_btree_elm_t elm)
                if (data_len != sizeof(struct hammer_inode_data))
                        return("BI");  /* bad inode size */
                ptr = get_buffer_data(data_offset, &data_buffer, 0);
-               crc = hammer_crc_get_leaf(ptr, &elm->leaf);
+               crc = get_leaf_crc(HammerVersion, ptr, &elm->leaf, whichp);
                rel_buffer(data_buffer);
                break;
        default:
-               crc = get_buf_crc(data_offset, data_len);
+               crc = get_buf_crc(data_offset, data_len, elm->leaf.data_crc,
+                                 whichp);
                break;
        }
 
@@ -657,11 +664,13 @@ check_data_crc(hammer_btree_elm_t elm)
 
 static
 uint32_t
-get_buf_crc(hammer_off_t buf_offset, int32_t buf_len)
+get_buf_crc(hammer_off_t buf_offset, int32_t buf_len, uint32_t leaf_crc,
+           const char **whichp)
 {
        struct buffer_info *data_buffer = NULL;
        int32_t len;
        uint32_t crc = 0;
+       uint32_t ncrc = 0;
        char *ptr;
 
        while (buf_len) {
@@ -671,12 +680,59 @@ get_buf_crc(hammer_off_t buf_offset, int32_t buf_len)
                        len = (int)buf_len;
                assert(len <= HAMMER_BUFSIZE);
                crc = crc32_ext(ptr, len, crc);
+               ncrc = iscsi_crc32_ext(ptr, len, ncrc);
                buf_len -= len;
                buf_offset += len;
        }
        rel_buffer(data_buffer);
 
-       return(crc);
+       if (leaf_crc == crc) {
+               *whichp = "o";
+               return crc;
+       }
+       *whichp = "i";
+       return ncrc;
+}
+
+static hammer_crc_t
+get_leaf_crc(uint32_t vol_version, void *data, hammer_btree_leaf_elm_t leaf,
+            const char **whichp)
+{
+        hammer_crc_t crc;
+
+       *whichp = "";
+        if (leaf->data_len == 0)
+                return(0);
+
+        switch(leaf->base.rec_type) {
+        case HAMMER_RECTYPE_INODE:
+                if (leaf->data_len != sizeof(struct hammer_inode_data))
+                        return(0);  /* This shouldn't happen */
+               if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+                       crc = iscsi_crc32(data, HAMMER_INODE_CRCSIZE);
+                       if (crc == leaf->data_crc) {
+                               *whichp = "i";
+                               break;
+                       }
+               }
+               crc = crc32(data, HAMMER_INODE_CRCSIZE);
+               if (crc == leaf->data_crc)
+                       *whichp = "o";
+                break;
+        default:
+               if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+                       crc = iscsi_crc32(data, leaf->data_len);
+                       if (crc == leaf->data_crc) {
+                               *whichp = "i";
+                               break;
+                       }
+               }
+               crc = crc32(data, leaf->data_len);
+               if (crc == leaf->data_crc)
+                       *whichp = "o";
+                break;
+        }
+        return(crc);
 }
 
 static
index 3c7d3e7..bf98c48 100644 (file)
@@ -120,6 +120,7 @@ hammer_cmd_snap(char **av, int ac, int tostdout, int fsbase)
                        "Use 'hammer snapshot' for legacy operation.");
                /* not reached */
        }
+       HammerVersion = version.cur_version;
 
        /*
         * Synctid to get a transaction id for the snapshot.
@@ -440,6 +441,7 @@ snapshot_add(int fd, const char *fsym, const char *tsym, const char *label,
         */
         if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) == 0 &&
            version.cur_version >= 3) {
+               HammerVersion = version.cur_version;
                snapshot.index = 0;
                snapshot.count = 1;
                snapshot.snaps[0].tid = tid;
@@ -540,6 +542,7 @@ snapshot_del(int fsfd, hammer_tid_t tid)
         if (ioctl(fsfd, HAMMERIOC_GET_VERSION, &version) < 0) {
                err(2, "hammer snaprm 0x%016jx", (uintmax_t)tid);
        }
+       HammerVersion = version.cur_version;
        if (version.cur_version < 3) {
                errx(2, "hammer snaprm 0x%016jx: You must upgrade to version "
                        " 3 to use this directive", (uintmax_t)tid);
index 656ee44..99ceb1f 100644 (file)
@@ -328,6 +328,7 @@ hammer_softprune_scanmeta(int fd, struct softprune *scan, int delete_all)
        bzero(&version, sizeof(version));
        if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                return(-1);
+       HammerVersion = version.cur_version;
        if (version.cur_version < 3)
                return(0);
 
index aa3218c..040e12c 100644 (file)
@@ -89,7 +89,7 @@ hammer_cmd_strip(void)
                                layer2->zone = HAMMER_ZONE_UNAVAIL_INDEX;
                                layer2->append_off = HAMMER_BIGBLOCK_SIZE;
                                layer2->bytes_free = 0;
-                               hammer_crc_set_layer2(layer2);
+                               hammer_crc_set_layer2(HammerVersion, layer2);
                                buffer2->cache.modified = 1;
                        } else if (layer2->zone == HAMMER_ZONE_UNAVAIL_INDEX) {
                                break;
index 605a68e..6879d5e 100644 (file)
@@ -62,6 +62,7 @@ hammer_cmd_get_version(char **av, int ac)
        bzero(&version, sizeof(version));
        if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                err(1, "hammer version ioctl");
+       HammerVersion = version.cur_version;
 
        snprintf(wip, 16, "%d", version.wip_version);
        printf("min=%d wip=%s max=%d current=%d description=\"%s\"\n",
@@ -111,6 +112,7 @@ hammer_cmd_set_version(char **av, int ac)
        bzero(&version, sizeof(version));
        if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                err(1, "hammer ioctl");
+       HammerVersion = version.cur_version;
        overs = version.cur_version;
 
        version.cur_version = strtol(av[1], NULL, 0);
@@ -118,6 +120,7 @@ hammer_cmd_set_version(char **av, int ac)
 
        if (ioctl(fd, HAMMERIOC_GET_VERSION, &version) < 0)
                err(1, "hammer ioctl");
+       HammerVersion = version.cur_version;
        if (version.cur_version >= version.wip_version && ac != 3)
                errx(1, "The requested version is a work-in-progress"
                        " and requires the 'force' directive");
index 6720ae6..74c559b 100644 (file)
@@ -1599,6 +1599,11 @@ Deduplication support.
 Directory hash ALG1.
 Tends to maintain inode number / directory name entry ordering better
 for files after minor renaming.
+.It 7
+.Dx 4.8 .
+Use the ISCSI crc32 algorithm instead of our custom polynomial.  This makes
+it easier to use faster cpu implementation of the crc algorithm.  CPU
+overhead is reduced but performance is unlikely to be impacted a whole lot.
 .El
 .El
 .Sh PSEUDO-FILESYSTEM (PFS) NOTES
@@ -1801,6 +1806,12 @@ field a signed value instead of unsigned, allowing it to go negative.
 A version 5 filesystem is required for dedup operation.
 .Sh UPGRADE INSTRUCTIONS HAMMER V5 TO V6
 It is possible to upgrade a V5 file system to V6 in place.
+.Sh UPGRADE INSTRUCTIONS HAMMER V6 TO V7
+It is possible to upgrade a V6 file system to V7 in place.
+After upgrading any new files will use the new, faster CRC.
+You can convert all existing files to use the new CRC by issuing
+a full reblock via 'hammer reblock <fs>'.
+You only have to do this once.
 .Sh FSYNC FLUSH MODES
 .Nm HAMMER
 implements five different fsync flush modes via the
index 19880c5..e9c4cdb 100644 (file)
@@ -586,9 +586,9 @@ __hammer_parsedevs(const char *blkdevs, int oflags, int verify)
                if ((copy = strchr(copy, ':')) != NULL)
                        *copy++ = 0;
                volname = getdevpath(volname, 0);
-               if (strchr(volname, ':'))
+               if (strchr(volname, ':')) {
                        __hammer_parsedevs(volname, oflags, verify);
-               else {
+               else {
                        volume = load_volume(volname, oflags, verify);
                        assert(volume);
                        ++volnum;
index 3de4266..5981923 100644 (file)
@@ -116,6 +116,7 @@ extern uuid_t Hammer_FSId;
 extern int UseReadBehind;
 extern int UseReadAhead;
 extern int DebugOpt;
+extern uint32_t HammerVersion;
 extern const char *zone_labels[];
 
 struct volume_info *init_volume(const char *filename, int oflags, int32_t vol_no);
index 3cca713..4d20587 100644 (file)
@@ -49,6 +49,7 @@ uuid_t Hammer_FSId;
 int UseReadBehind = -4;
 int UseReadAhead = 4;
 int DebugOpt;
+uint32_t HammerVersion = -1;
 
 TAILQ_HEAD(volume_list, volume_info);
 static struct volume_list VolList = TAILQ_HEAD_INITIALIZER(VolList);
@@ -185,9 +186,11 @@ load_volume(const char *filename, int oflags, int verify)
 
        n = readhammervol(volume);
        if (n == -1) {
-               err(1, "load_volume: %s: Read failed at offset 0", volume->name);
+               err(1, "load_volume: %s: Read failed at offset 0",
+                   volume->name);
        }
        volume->vol_no = volume->ondisk->vol_no;
+       HammerVersion = volume->ondisk->vol_version;
 
        if (valid_hammer_volumes++ == 0)
                Hammer_FSId = volume->ondisk->vol_fsid;
@@ -498,7 +501,7 @@ format_blockmap(struct volume_info *root_vol, int zone, hammer_off_t offset)
        blockmap->first_offset = zone_base;
        blockmap->next_offset = zone_base;
        blockmap->alloc_offset = HAMMER_ENCODE(zone, 255, -1);
-       hammer_crc_set_blockmap(blockmap);
+       hammer_crc_set_blockmap(HammerVersion, blockmap);
 }
 
 /*
@@ -524,7 +527,7 @@ format_freemap(struct volume_info *root_vol)
                bzero(layer1, sizeof(*layer1));
                layer1->phys_offset = HAMMER_BLOCKMAP_UNAVAIL;
                layer1->blocks_free = 0;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(HammerVersion, layer1);
        }
        assert(i == HAMMER_BIGBLOCK_SIZE);
        rel_buffer(buffer);
@@ -535,7 +538,7 @@ format_freemap(struct volume_info *root_vol)
        blockmap->first_offset = 0;
        blockmap->next_offset = HAMMER_ENCODE_RAW_BUFFER(0, 0);
        blockmap->alloc_offset = HAMMER_ENCODE_RAW_BUFFER(255, -1);
-       hammer_crc_set_blockmap(blockmap);
+       hammer_crc_set_blockmap(HammerVersion, blockmap);
 }
 
 /*
@@ -584,7 +587,7 @@ initialize_freemap(struct volume_info *volume)
                        layer1->phys_offset = bootstrap_bigblock(volume);
                        layer1->blocks_free = 0;
                        buffer1->cache.modified = 1;
-                       hammer_crc_set_layer1(layer1);
+                       hammer_crc_set_layer1(HammerVersion, layer1);
                }
        }
 
@@ -627,12 +630,12 @@ initialize_freemap(struct volume_info *volume)
                                layer2->append_off = HAMMER_BIGBLOCK_SIZE;
                                layer2->bytes_free = 0;
                        }
-                       hammer_crc_set_layer2(layer2);
+                       hammer_crc_set_layer2(HammerVersion, layer2);
                        buffer2->cache.modified = 1;
                }
 
                layer1->blocks_free += layer1_count;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(HammerVersion, layer1);
                buffer1->cache.modified = 1;
        }
 
@@ -729,7 +732,7 @@ format_undomap(struct volume_info *root_vol, int64_t *undo_buffer_size)
        blockmap->first_offset = HAMMER_ENCODE_UNDO(0);
        blockmap->next_offset = blockmap->first_offset;
        blockmap->alloc_offset = HAMMER_ENCODE_UNDO(undo_limit);
-       hammer_crc_set_blockmap(blockmap);
+       hammer_crc_set_blockmap(HammerVersion, blockmap);
 
        limit_index = undo_limit / HAMMER_BIGBLOCK_SIZE;
        assert(limit_index <= HAMMER_MAX_UNDO_BIGBLOCKS);
@@ -772,7 +775,7 @@ format_undomap(struct volume_info *root_vol, int64_t *undo_buffer_size)
                tail->tail_type = HAMMER_HEAD_TYPE_DUMMY;
                tail->tail_size = bytes;
 
-               hammer_crc_set_fifo_head(head, bytes);
+               hammer_crc_set_fifo_head(HammerVersion, head, bytes);
 
                scan += bytes;
        }
index 7640312..8effec0 100644 (file)
@@ -54,7 +54,6 @@ static int64_t HeaderJunkSize = -1;
 static int64_t BootAreaSize = -1;
 static int64_t MemoryLogSize = -1;
 static int64_t UndoBufferSize;
-static int HammerVersion = -1;
 
 #define GIG    (1024LL*1024*1024)
 
@@ -139,7 +138,7 @@ main(int ac, char **av)
        av += optind;
        nvols = ac;
 
-       if (HammerVersion < 0) {
+       if (HammerVersion == (uint32_t)-1) {
                size_t olen = sizeof(HammerVersion);
                HammerVersion = HAMMER_VOL_VERSION_DEFAULT;
 
@@ -711,7 +710,7 @@ format_root_directory(const char *label)
 
        elm->leaf.data_offset = idata_off;
        elm->leaf.data_len = sizeof(*idata);
-       hammer_crc_set_leaf(idata, &elm->leaf);
+       hammer_crc_set_leaf(HammerVersion, idata, &elm->leaf);
 
        /*
         * Create the second node element for the PFS data.
@@ -732,9 +731,9 @@ format_root_directory(const char *label)
 
        elm->leaf.data_offset = pfsd_off;
        elm->leaf.data_len = sizeof(*pfsd);
-       hammer_crc_set_leaf(pfsd, &elm->leaf);
+       hammer_crc_set_leaf(HammerVersion, pfsd, &elm->leaf);
 
-       hammer_crc_set_btree(bnode);
+       hammer_crc_set_btree(HammerVersion, bnode);
 
        rel_buffer(data_buffer0);
        rel_buffer(data_buffer1);
index afe7bd4..1f743e0 100644 (file)
@@ -1256,7 +1256,7 @@ void hammer_generate_redo_sync(hammer_transaction_t trans);
 void hammer_redo_fifo_start_flush(hammer_inode_t ip);
 void hammer_redo_fifo_end_flush(hammer_inode_t ip);
 
-void hammer_format_undo(void *base, uint32_t seqno);
+void hammer_format_undo(hammer_mount_t hmp, void *base, uint32_t seqno);
 int hammer_upgrade_undo_4(hammer_transaction_t trans);
 
 hammer_off_t hammer_freemap_alloc(hammer_transaction_t trans,
index e95ef46..0a88dbd 100644 (file)
@@ -179,9 +179,9 @@ again:
        /*
         * Check CRC.
         */
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -227,9 +227,9 @@ again:
         * Check CRC.  This can race another thread holding the lock
         * and in the middle of modifying layer2.
         */
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -315,7 +315,7 @@ again:
                 */
                hammer_modify_buffer(trans, buffer1, layer1, sizeof(*layer1));
                --layer1->blocks_free;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(hmp->version, layer1);
                hammer_modify_buffer_done(buffer1);
                hammer_modify_buffer(trans, buffer2, layer2, sizeof(*layer2));
                layer2->zone = zone;
@@ -338,7 +338,7 @@ again:
        layer2->bytes_free -= bytes;
        KKASSERT(layer2->append_off <= offset);
        layer2->append_off = offset + bytes;
-       hammer_crc_set_layer2(layer2);
+       hammer_crc_set_layer2(hmp->version, layer2);
        hammer_modify_buffer_done(buffer2);
 
        /*
@@ -492,9 +492,9 @@ again:
        /*
         * Check CRC.
         */
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -526,9 +526,9 @@ again:
         * Check CRC if not allocating into uninitialized space (which we
         * aren't when reserving space).
         */
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -679,9 +679,9 @@ hammer_blockmap_reserve_dedup(hammer_mount_t hmp, int zone, int bytes,
        /*
         * Check CRC.
         */
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -699,9 +699,9 @@ hammer_blockmap_reserve_dedup(hammer_mount_t hmp, int zone, int bytes,
        /*
         * Check CRC.
         */
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -980,9 +980,9 @@ hammer_blockmap_free(hammer_transaction_t trans,
                goto failed;
        KKASSERT(layer1->phys_offset &&
                 layer1->phys_offset != HAMMER_BLOCKMAP_UNAVAIL);
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -995,9 +995,9 @@ hammer_blockmap_free(hammer_transaction_t trans,
        layer2 = hammer_bread(hmp, layer2_offset, &error, &buffer2);
        if (error)
                goto failed;
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1044,7 +1044,7 @@ hammer_blockmap_free(hammer_transaction_t trans,
                        hammer_modify_buffer(trans, buffer1,
                                             layer1, sizeof(*layer1));
                        ++layer1->blocks_free;
-                       hammer_crc_set_layer1(layer1);
+                       hammer_crc_set_layer1(hmp->version, layer1);
                        hammer_modify_buffer_done(buffer1);
                        hammer_modify_volume_field(trans,
                                        trans->rootvol,
@@ -1055,7 +1055,7 @@ hammer_blockmap_free(hammer_transaction_t trans,
                        hammer_modify_volume_done(trans->rootvol);
                }
        }
-       hammer_crc_set_layer2(layer2);
+       hammer_crc_set_layer2(hmp->version, layer2);
        hammer_modify_buffer_done(buffer2);
        hammer_unlock(&hmp->blkmap_lock);
 
@@ -1113,9 +1113,9 @@ hammer_blockmap_dedup(hammer_transaction_t trans,
                goto failed;
        KKASSERT(layer1->phys_offset &&
                 layer1->phys_offset != HAMMER_BLOCKMAP_UNAVAIL);
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1128,9 +1128,9 @@ hammer_blockmap_dedup(hammer_transaction_t trans,
        layer2 = hammer_bread(hmp, layer2_offset, &error, &buffer2);
        if (error)
                goto failed;
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1156,7 +1156,7 @@ hammer_blockmap_dedup(hammer_transaction_t trans,
 
        KKASSERT(layer2->bytes_free <= HAMMER_BIGBLOCK_SIZE);
 
-       hammer_crc_set_layer2(layer2);
+       hammer_crc_set_layer2(hmp->version, layer2);
 underflow:
        hammer_modify_buffer_done(buffer2);
        hammer_unlock(&hmp->blkmap_lock);
@@ -1222,9 +1222,9 @@ hammer_blockmap_finalize(hammer_transaction_t trans,
                goto failed;
        KKASSERT(layer1->phys_offset &&
                 layer1->phys_offset != HAMMER_BLOCKMAP_UNAVAIL);
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1237,9 +1237,9 @@ hammer_blockmap_finalize(hammer_transaction_t trans,
        layer2 = hammer_bread(hmp, layer2_offset, &error, &buffer2);
        if (error)
                goto failed;
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1256,7 +1256,7 @@ hammer_blockmap_finalize(hammer_transaction_t trans,
        if (layer2->zone == 0) {
                hammer_modify_buffer(trans, buffer1, layer1, sizeof(*layer1));
                --layer1->blocks_free;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(hmp->version, layer1);
                hammer_modify_buffer_done(buffer1);
                layer2->zone = zone;
                KKASSERT(layer2->bytes_free == HAMMER_BIGBLOCK_SIZE);
@@ -1287,7 +1287,7 @@ hammer_blockmap_finalize(hammer_transaction_t trans,
        if (layer2->append_off < offset)
                layer2->append_off = offset;
 
-       hammer_crc_set_layer2(layer2);
+       hammer_crc_set_layer2(hmp->version, layer2);
        hammer_modify_buffer_done(buffer2);
        hammer_unlock(&hmp->blkmap_lock);
 
@@ -1346,9 +1346,9 @@ hammer_blockmap_getfree(hammer_mount_t hmp, hammer_off_t zone_offset,
                goto failed;
        }
        KKASSERT(layer1->phys_offset);
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1366,9 +1366,9 @@ hammer_blockmap_getfree(hammer_mount_t hmp, hammer_off_t zone_offset,
                bytes = 0;
                goto failed;
        }
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1438,9 +1438,9 @@ hammer_blockmap_lookup_verify(hammer_mount_t hmp, hammer_off_t zone_offset,
        if (*errorp)
                goto failed;
        KKASSERT(layer1->phys_offset != HAMMER_BLOCKMAP_UNAVAIL);
-       if (!hammer_crc_test_layer1(layer1)) {
+       if (!hammer_crc_test_layer1(hmp->version, layer1)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer1(layer1))
+               if (!hammer_crc_test_layer1(hmp->version, layer1))
                        hpanic("CRC FAILED: LAYER1");
                hammer_unlock(&hmp->blkmap_lock);
        }
@@ -1464,9 +1464,9 @@ hammer_blockmap_lookup_verify(hammer_mount_t hmp, hammer_off_t zone_offset,
        } else if (layer2->zone != zone) {
                hpanic("bad zone %d/%d", layer2->zone, zone);
        }
-       if (!hammer_crc_test_layer2(layer2)) {
+       if (!hammer_crc_test_layer2(hmp->version, layer2)) {
                hammer_lock_ex(&hmp->blkmap_lock);
-               if (!hammer_crc_test_layer2(layer2))
+               if (!hammer_crc_test_layer2(hmp->version, layer2))
                        hpanic("CRC FAILED: LAYER2");
                hammer_unlock(&hmp->blkmap_lock);
        }
index 8552f86..9636dac 100644 (file)
@@ -762,7 +762,7 @@ hammer_btree_extract(hammer_cursor_t cursor, int flags)
         * Deal with CRC errors on the extracted data.
         */
        if (error == 0 &&
-           hammer_crc_test_leaf(cursor->data, &elm->leaf) == 0) {
+           hammer_crc_test_leaf(hmp->version, cursor->data, &elm->leaf) == 0) {
                hdkprintf("CRC DATA @ %016jx/%d FAILED\n",
                        (intmax_t)elm->leaf.data_offset, elm->leaf.data_len);
                if (hammer_debug_critical)
index 052f683..6a982f7 100644 (file)
  */
 uint32_t crc32(const void *buf, size_t size);
 uint32_t crc32_ext(const void *buf, size_t size, uint32_t ocrc);
+uint32_t iscsi_crc32(const void *buf, size_t size);
+uint32_t iscsi_crc32_ext(const void *buf, size_t size, uint32_t ocrc);
 #endif
 
+#define hammer_datacrc(vers, buf, size)                \
+       (((vers) >= HAMMER_VOL_VERSION_SEVEN) ? iscsi_crc32(buf, size) : crc32(buf, size))
+#define hammer_datacrc_ext(vers, buf, size, ocrc)      \
+       (((vers) >= HAMMER_VOL_VERSION_SEVEN) ? iscsi_crc32_ext(buf, size, ocrc) : \
+                                               crc32_ext(buf, size, ocrc))
+
 static __inline hammer_crc_t
-hammer_crc_get_blockmap(hammer_blockmap_t blockmap)
+hammer_crc_get_blockmap(uint32_t vol_version, hammer_blockmap_t blockmap)
 {
-       return(crc32(blockmap, HAMMER_BLOCKMAP_CRCSIZE));
+       return(hammer_datacrc(vol_version, blockmap, HAMMER_BLOCKMAP_CRCSIZE));
 }
 
 static __inline void
-hammer_crc_set_blockmap(hammer_blockmap_t blockmap)
+hammer_crc_set_blockmap(uint32_t vol_version, hammer_blockmap_t blockmap)
 {
-       blockmap->entry_crc = hammer_crc_get_blockmap(blockmap);
+       blockmap->entry_crc = hammer_crc_get_blockmap(vol_version, blockmap);
 }
 
 static __inline int
-hammer_crc_test_blockmap(hammer_blockmap_t blockmap)
+hammer_crc_test_blockmap(uint32_t vol_version, hammer_blockmap_t blockmap)
 {
-       return(blockmap->entry_crc == hammer_crc_get_blockmap(blockmap));
+       if (blockmap->entry_crc == hammer_crc_get_blockmap(vol_version, blockmap))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (blockmap->entry_crc == hammer_crc_get_blockmap(HAMMER_VOL_VERSION_SIX,
+                                                                  blockmap)) {
+                       return 1;
+               }
+       }
+       return 0;
 }
 
 static __inline hammer_crc_t
-hammer_crc_get_layer1(hammer_blockmap_layer1_t layer1)
+hammer_crc_get_layer1(uint32_t vol_version, hammer_blockmap_layer1_t layer1)
 {
-       return(crc32(layer1, HAMMER_LAYER1_CRCSIZE));
+       return(hammer_datacrc(vol_version, layer1, HAMMER_LAYER1_CRCSIZE));
 }
 
 static __inline void
-hammer_crc_set_layer1(hammer_blockmap_layer1_t layer1)
+hammer_crc_set_layer1(uint32_t vol_version, hammer_blockmap_layer1_t layer1)
 {
-       layer1->layer1_crc = hammer_crc_get_layer1(layer1);
+       layer1->layer1_crc = hammer_crc_get_layer1(vol_version, layer1);
 }
 
 static __inline int
-hammer_crc_test_layer1(hammer_blockmap_layer1_t layer1)
+hammer_crc_test_layer1(uint32_t vol_version, hammer_blockmap_layer1_t layer1)
 {
-       return(layer1->layer1_crc == hammer_crc_get_layer1(layer1));
+       if (layer1->layer1_crc == hammer_crc_get_layer1(vol_version, layer1))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (layer1->layer1_crc == hammer_crc_get_layer1(HAMMER_VOL_VERSION_SIX, layer1))
+                       return 1;
+       }
+       return 0;
 }
 
 static __inline hammer_crc_t
-hammer_crc_get_layer2(hammer_blockmap_layer2_t layer2)
+hammer_crc_get_layer2(uint32_t vol_version, hammer_blockmap_layer2_t layer2)
 {
-       return(crc32(layer2, HAMMER_LAYER2_CRCSIZE));
+       return(hammer_datacrc(vol_version, layer2, HAMMER_LAYER2_CRCSIZE));
 }
 
 static __inline void
-hammer_crc_set_layer2(hammer_blockmap_layer2_t layer2)
+hammer_crc_set_layer2(uint32_t vol_version, hammer_blockmap_layer2_t layer2)
 {
-       layer2->entry_crc = hammer_crc_get_layer2(layer2);
+       layer2->entry_crc = hammer_crc_get_layer2(vol_version, layer2);
 }
 
 static __inline int
-hammer_crc_test_layer2(hammer_blockmap_layer2_t layer2)
+hammer_crc_test_layer2(uint32_t vol_version, hammer_blockmap_layer2_t layer2)
 {
-       return(layer2->entry_crc == hammer_crc_get_layer2(layer2));
+       if (layer2->entry_crc == hammer_crc_get_layer2(vol_version, layer2))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (layer2->entry_crc == hammer_crc_get_layer2(HAMMER_VOL_VERSION_SIX, layer2))
+                       return 1;
+       }
+       return 0;
 }
 
 static __inline hammer_crc_t
-hammer_crc_get_volume(hammer_volume_ondisk_t ondisk)
+hammer_crc_get_volume(uint32_t vol_version, hammer_volume_ondisk_t ondisk)
 {
-       return(crc32(ondisk, HAMMER_VOL_CRCSIZE1) ^
-               crc32(&ondisk->vol_crc + 1, HAMMER_VOL_CRCSIZE2));
+       return (hammer_datacrc(vol_version, ondisk, HAMMER_VOL_CRCSIZE1) ^
+               hammer_datacrc(vol_version, &ondisk->vol_crc + 1, HAMMER_VOL_CRCSIZE2));
 }
 
 static __inline void
-hammer_crc_set_volume(hammer_volume_ondisk_t ondisk)
+hammer_crc_set_volume(uint32_t vol_version, hammer_volume_ondisk_t ondisk)
 {
-       ondisk->vol_crc = hammer_crc_get_volume(ondisk);
+       ondisk->vol_crc = hammer_crc_get_volume(vol_version, ondisk);
 }
 
 static __inline int
-hammer_crc_test_volume(hammer_volume_ondisk_t ondisk)
+hammer_crc_test_volume(uint32_t vol_version, hammer_volume_ondisk_t ondisk)
 {
-       return(ondisk->vol_crc == hammer_crc_get_volume(ondisk));
+       if (ondisk->vol_crc == hammer_crc_get_volume(vol_version, ondisk))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (ondisk->vol_crc == hammer_crc_get_volume(HAMMER_VOL_VERSION_SIX, ondisk))
+                       return 1;
+       }
+       return 0;
 }
 
 static __inline hammer_crc_t
-hammer_crc_get_fifo_head(hammer_fifo_head_t head, int bytes)
+hammer_crc_get_fifo_head(uint32_t vol_version, hammer_fifo_head_t head, int bytes)
 {
-       return(crc32(head, HAMMER_FIFO_HEAD_CRCOFF) ^
-               crc32(head + 1, bytes - sizeof(*head)));
+       return(hammer_datacrc(vol_version, head, HAMMER_FIFO_HEAD_CRCOFF) ^
+               hammer_datacrc(vol_version, head + 1, bytes - sizeof(*head)));
 }
 
 static __inline void
-hammer_crc_set_fifo_head(hammer_fifo_head_t head, int bytes)
+hammer_crc_set_fifo_head(uint32_t vol_version, hammer_fifo_head_t head, int bytes)
 {
-       head->hdr_crc = hammer_crc_get_fifo_head(head, bytes);
+       head->hdr_crc = hammer_crc_get_fifo_head(vol_version, head, bytes);
 }
 
 static __inline int
-hammer_crc_test_fifo_head(hammer_fifo_head_t head, int bytes)
+hammer_crc_test_fifo_head(uint32_t vol_version, hammer_fifo_head_t head, int bytes)
 {
-       return(head->hdr_crc == hammer_crc_get_fifo_head(head, bytes));
+       if (head->hdr_crc == hammer_crc_get_fifo_head(vol_version, head, bytes))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (head->hdr_crc == hammer_crc_get_fifo_head(HAMMER_VOL_VERSION_SIX,
+                                                             head, bytes)) {
+                       return 1;
+               }
+       }
+       return 0;
 }
 
 static __inline hammer_crc_t
-hammer_crc_get_btree(hammer_node_ondisk_t node)
+hammer_crc_get_btree(uint32_t vol_version, hammer_node_ondisk_t node)
 {
-       return(crc32(&node->crc + 1, HAMMER_BTREE_CRCSIZE));
+       return (hammer_datacrc(vol_version, &node->crc + 1, HAMMER_BTREE_CRCSIZE));
 }
 
 static __inline void
-hammer_crc_set_btree(hammer_node_ondisk_t node)
+hammer_crc_set_btree(uint32_t vol_version, hammer_node_ondisk_t node)
 {
-       node->crc = hammer_crc_get_btree(node);
+       node->crc = hammer_crc_get_btree(vol_version, node);
 }
 
 static __inline int
-hammer_crc_test_btree(hammer_node_ondisk_t node)
+hammer_crc_test_btree(uint32_t vol_version, hammer_node_ondisk_t node)
 {
-       return(node->crc == hammer_crc_get_btree(node));
+       if (node->crc == hammer_crc_get_btree(vol_version, node))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (node->crc == hammer_crc_get_btree(HAMMER_VOL_VERSION_SIX, node))
+                       return 1;
+       }
+       return 0;
 }
 
 /*
@@ -165,7 +213,7 @@ hammer_crc_test_btree(hammer_node_ondisk_t node)
  *       allowing them to be updated in-place.
  */
 static __inline hammer_crc_t
-hammer_crc_get_leaf(void *data, hammer_btree_leaf_elm_t leaf)
+hammer_crc_get_leaf(uint32_t vol_version, void *data, hammer_btree_leaf_elm_t leaf)
 {
        hammer_crc_t crc;
 
@@ -176,17 +224,17 @@ hammer_crc_get_leaf(void *data, hammer_btree_leaf_elm_t leaf)
        case HAMMER_RECTYPE_INODE:
                if (leaf->data_len != sizeof(struct hammer_inode_data))
                        return(0);  /* This shouldn't happen */
-               crc = crc32(data, HAMMER_INODE_CRCSIZE);
+               crc = hammer_datacrc(vol_version, data, HAMMER_INODE_CRCSIZE);
                break;
        default:
-               crc = crc32(data, leaf->data_len);
+               crc = hammer_datacrc(vol_version, data, leaf->data_len);
                break;
        }
        return(crc);
 }
 
 static __inline void
-hammer_crc_set_leaf(void *data, hammer_btree_leaf_elm_t leaf)
+hammer_crc_set_leaf(uint32_t vol_version, void *data, hammer_btree_leaf_elm_t leaf)
 {
 #ifdef _KERNEL
 #ifdef INVARIANTS
@@ -194,13 +242,19 @@ hammer_crc_set_leaf(void *data, hammer_btree_leaf_elm_t leaf)
                KKASSERT(leaf->data_len == sizeof(struct hammer_inode_data));
 #endif
 #endif
-       leaf->data_crc = hammer_crc_get_leaf(data, leaf);
+       leaf->data_crc = hammer_crc_get_leaf(vol_version, data, leaf);
 }
 
 static __inline int
-hammer_crc_test_leaf(void *data, hammer_btree_leaf_elm_t leaf)
+hammer_crc_test_leaf(uint32_t vol_version, void *data, hammer_btree_leaf_elm_t leaf)
 {
-       return(leaf->data_crc == hammer_crc_get_leaf(data, leaf));
+       if (leaf->data_crc == hammer_crc_get_leaf(vol_version, data, leaf))
+               return 1;
+       if (vol_version >= HAMMER_VOL_VERSION_SEVEN) {
+               if (leaf->data_crc == hammer_crc_get_leaf(HAMMER_VOL_VERSION_SIX, data, leaf))
+                       return 1;
+       }
+       return 0;
 }
 
 static __inline hammer_crc_t
index ef16b89..8931cfd 100644 (file)
@@ -800,9 +800,9 @@ typedef struct hammer_volume_ondisk {
         sizeof(hammer_crc_t))
 
 #define HAMMER_VOL_VERSION_MIN         1       /* minimum 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_DEFAULT     7       /* newfs default version */
+#define HAMMER_VOL_VERSION_WIP         8       /* version >= this is WIP */
+#define HAMMER_VOL_VERSION_MAX         7       /* maximum supported version */
 
 #define HAMMER_VOL_VERSION_ONE         1
 #define HAMMER_VOL_VERSION_TWO         2       /* new dirent layout (2.3+) */
@@ -810,6 +810,7 @@ typedef struct hammer_volume_ondisk {
 #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 */
+#define HAMMER_VOL_VERSION_SEVEN       7       /* use the faster iscsi_crc */
 
 /*
  * Translate a zone-2 address to physical address
index ea24ad1..45f86f1 100644 (file)
@@ -684,8 +684,10 @@ hammer_flusher_finalize(hammer_transaction_t trans, int final)
                if (root_volume->io.modified) {
                        hammer_modify_volume(trans, root_volume,
                                             dundomap, sizeof(hmp->blockmap));
-                       for (i = 0; i < HAMMER_MAX_ZONES; ++i)
-                               hammer_crc_set_blockmap(&cundomap[i]);
+                       for (i = 0; i < HAMMER_MAX_ZONES; ++i) {
+                               hammer_crc_set_blockmap(hmp->version,
+                                                       &cundomap[i]);
+                       }
                        bcopy(cundomap, dundomap, sizeof(hmp->blockmap));
                        hammer_modify_volume_done(root_volume);
                }
@@ -741,7 +743,7 @@ hammer_flusher_finalize(hammer_transaction_t trans, int final)
                hammer_modify_volume_noundo(NULL, root_volume);
                dundomap->first_offset = cundomap->first_offset;
                dundomap->next_offset = save_undo_next_offset;
-               hammer_crc_set_blockmap(dundomap);
+               hammer_crc_set_blockmap(hmp->version, dundomap);
                hammer_modify_volume_done(root_volume);
        }
 
@@ -761,7 +763,7 @@ hammer_flusher_finalize(hammer_transaction_t trans, int final)
                hammer_modify_volume_noundo(NULL, root_volume);
                if (root_volume->ondisk->vol0_next_tid < trans->tid)
                        root_volume->ondisk->vol0_next_tid = trans->tid;
-               hammer_crc_set_volume(root_volume->ondisk);
+               hammer_crc_set_volume(hmp->version, root_volume->ondisk);
                hammer_modify_volume_done(root_volume);
                hammer_io_write_interlock(&root_volume->io);
                hammer_io_flush(&root_volume->io, 0);
index d0071d4..2f02221 100644 (file)
@@ -1015,7 +1015,7 @@ restart:
                        node->flags &= ~HAMMER_NODE_NEEDSCRC;
                        KKASSERT(node->ondisk);
                        if (inval == 0)
-                               hammer_crc_set_btree(node->ondisk);
+                               hammer_crc_set_btree(hmp->version, node->ondisk);
                        hammer_rel_node(node);
                        goto restart;
                }
@@ -1578,6 +1578,7 @@ hammer_io_indirect_read(hammer_mount_t hmp, struct bio *bio,
                } else {
                        bio->bio_caller_info2.index = 0;
                }
+               bio->bio_caller_info3.ptr = hmp;
 
                hce = hammer_cluster_enable;
                if (hce > 0) {
@@ -1621,6 +1622,7 @@ hammer_indirect_callback(struct bio *bio)
        struct buf *bp = bio->bio_buf;
        struct buf *obp;
        struct bio *obio;
+       hammer_mount_t hmp;
 
        /*
         * If BIO_DONE is already set the device buffer was already
@@ -1643,16 +1645,32 @@ hammer_indirect_callback(struct bio *bio)
 
        obio = bio->bio_caller_info1.ptr;
        obp = obio->bio_buf;
+       hmp = obio->bio_caller_info3.ptr;
 
        if (bp->b_flags & B_ERROR) {
+               /*
+                * Error from block device
+                */
                obp->b_flags |= B_ERROR;
                obp->b_error = bp->b_error;
        } else if (obio->bio_caller_info2.index &&
                   obio->bio_caller_info1.uvalue32 !=
-                   crc32(bp->b_data, bp->b_bufsize)) {
+                   hammer_datacrc(hmp->version,
+                                  bp->b_data, obp->b_bufsize) &&
+                   obio->bio_caller_info1.uvalue32 !=
+                   hammer_datacrc(HAMMER_VOL_VERSION_SIX,
+                                  bp->b_data, obp->b_bufsize)) {
+               /*
+                * CRC error.  First check against current hammer version,
+                * then back-off and check against version 6 (the original
+                * crc).
+                */
                obp->b_flags |= B_ERROR;
                obp->b_error = EIO;
        } else {
+               /*
+                * Everything is ok
+                */
                KKASSERT(bp->b_bufsize >= obp->b_bufsize);
                bcopy(bp->b_data, obp->b_data, obp->b_bufsize);
                obp->b_resid = 0;
index ea54f85..e549aa5 100644 (file)
@@ -586,6 +586,10 @@ hammer_ioc_get_version(hammer_transaction_t trans, hammer_inode_t ip,
                ksnprintf(ver->description, sizeof(ver->description),
                          "Directory Hash ALG1 (tmp/rename resistance)");
                break;
+       case 7:
+               ksnprintf(ver->description, sizeof(ver->description),
+                         "Use ISCSI CRC (faster than original crc32)");
+               break;
        default:
                ksnprintf(ver->description, sizeof(ver->description),
                         "Unknown");
index bc82b38..57c1ac3 100644 (file)
@@ -42,7 +42,7 @@ static int hammer_bulk_scan_callback(hammer_record_t record, void *data);
 static int hammer_record_needs_overwrite_delete(hammer_record_t record);
 static int hammer_delete_general(hammer_cursor_t cursor, hammer_inode_t ip,
                                hammer_btree_leaf_elm_t leaf);
-static int hammer_cursor_localize_data(hammer_data_ondisk_t data,
+static int hammer_cursor_localize_data(hammer_mount_t hmp, hammer_data_ondisk_t data,
                                hammer_btree_leaf_elm_t leaf);
 
 struct rec_trunc_info {
@@ -972,7 +972,7 @@ hammer_ip_add_bulk(hammer_inode_t ip, off_t file_offset, void *data, int bytes,
        if (bytes == 0)
                crc = 0;
        else
-               crc = crc32(data, bytes);
+               crc = hammer_datacrc(ip->hmp->version, data, bytes);
 
        if (hammer_live_dedup == 0)
                goto nodedup;
@@ -1146,6 +1146,7 @@ int
 hammer_ip_sync_record_cursor(hammer_cursor_t cursor, hammer_record_t record)
 {
        hammer_transaction_t trans = cursor->trans;
+       hammer_mount_t hmp = trans->hmp;
        int64_t file_offset;
        int bytes;
        void *bdata;
@@ -1298,7 +1299,7 @@ hammer_ip_sync_record_cursor(hammer_cursor_t cursor, hammer_record_t record)
                                          0, &error);
                if (bdata == NULL)
                        goto done_unlock;
-               hammer_crc_set_leaf(record->data, &record->leaf);
+               hammer_crc_set_leaf(hmp->version, record->data, &record->leaf);
                hammer_modify_buffer_noundo(trans, cursor->data_buffer);
                bcopy(record->data, bdata, record->leaf.data_len);
                hammer_modify_buffer_done(cursor->data_buffer);
@@ -2305,6 +2306,7 @@ hammer_create_at_cursor(hammer_cursor_t cursor, hammer_btree_leaf_elm_t leaf,
                        void *udata, int mode)
 {
        hammer_transaction_t trans;
+       hammer_mount_t hmp;
        hammer_buffer_t data_buffer;
        hammer_off_t ndata_offset;
        hammer_tid_t high_tid;
@@ -2313,6 +2315,7 @@ hammer_create_at_cursor(hammer_cursor_t cursor, hammer_btree_leaf_elm_t leaf,
        int doprop;
 
        trans = cursor->trans;
+       hmp = trans->hmp;
        data_buffer = NULL;
        ndata_offset = 0;
        doprop = 0;
@@ -2339,21 +2342,21 @@ hammer_create_at_cursor(hammer_cursor_t cursor, hammer_btree_leaf_elm_t leaf,
                case HAMMER_CREATE_MODE_UMIRROR:
                        error = copyin(udata, ndata, leaf->data_len);
                        if (error == 0) {
-                               if (hammer_crc_test_leaf(ndata, leaf) == 0) {
+                               if (hammer_crc_test_leaf(hmp->version, ndata, leaf) == 0) {
                                        hdkprintf("CRC DATA @ %016jx/%d MISMATCH ON PIPE\n",
                                                (intmax_t)ndata_offset,
                                                leaf->data_len);
                                        error = EINVAL;
                                } else {
                                        error = hammer_cursor_localize_data(
-                                                       ndata, leaf);
+                                                       hmp, ndata, leaf);
                                }
                        }
                        break;
                case HAMMER_CREATE_MODE_SYS:
                        bcopy(udata, ndata, leaf->data_len);
                        error = 0;
-                       hammer_crc_set_leaf(ndata, leaf);
+                       hammer_crc_set_leaf(hmp->version, ndata, leaf);
                        break;
                default:
                        hpanic("bad mode %d", mode);
@@ -2672,7 +2675,7 @@ hammer_ip_check_directory_empty(hammer_transaction_t trans, hammer_inode_t ip)
  */
 static
 int
-hammer_cursor_localize_data(hammer_data_ondisk_t data,
+hammer_cursor_localize_data(hammer_mount_t hmp, hammer_data_ondisk_t data,
                            hammer_btree_leaf_elm_t leaf)
 {
        uint32_t localization;
@@ -2682,7 +2685,7 @@ hammer_cursor_localize_data(hammer_data_ondisk_t data,
                               HAMMER_LOCALIZE_PSEUDOFS_MASK;
                if (data->entry.localization != localization) {
                        data->entry.localization = localization;
-                       hammer_crc_set_leaf(data, leaf);
+                       hammer_crc_set_leaf(hmp->version, data, leaf);
                }
        }
        return(0);
index 49f3702..a00c4dc 100644 (file)
@@ -1264,6 +1264,7 @@ hammer_load_node(hammer_transaction_t trans, hammer_node_t node, int isnew)
 {
        hammer_buffer_t buffer;
        hammer_off_t buf_offset;
+       hammer_mount_t hmp = trans->hmp;
        int error;
 
        error = 0;
@@ -1305,7 +1306,7 @@ hammer_load_node(hammer_transaction_t trans, hammer_node_t node, int isnew)
                 */
                if (isnew == 0 &&
                    (node->flags & HAMMER_NODE_CRCANY) == 0) {
-                       if (hammer_crc_test_btree(node->ondisk) == 0) {
+                       if (hammer_crc_test_btree(hmp->version, node->ondisk) == 0) {
                                hdkprintf("CRC B-TREE NODE @ %016jx/%lu FAILED\n",
                                        (intmax_t)node->node_offset,
                                        sizeof(*node->ondisk));
index 8997e9b..af488a7 100644 (file)
@@ -457,6 +457,7 @@ hammer_reblock_data(struct hammer_ioc_reblock *reblock,
        hammer_buffer_t data_buffer = NULL;
        hammer_off_t odata_offset;
        hammer_off_t ndata_offset;
+       uint32_t ncrc;
        int error;
        void *ndata;
 
@@ -477,9 +478,15 @@ hammer_reblock_data(struct hammer_ioc_reblock *reblock,
         * The blockmap_free may free up the entire big-block and
         * will not be able to invalidate it if the cursor is holding
         * a data buffer cached in that big-block.
+        *
+        * Unconditionally regenerate the CRC.  This is a slightly hack
+        * to ensure that the crc method is the latest for the filesystem
+        * version (e.g. upgrade from v6 to v7).
         */
        hammer_modify_buffer_noundo(cursor->trans, data_buffer);
        bcopy(cursor->data, ndata, elm->leaf.data_len);
+       ncrc = hammer_crc_get_leaf(cursor->trans->hmp->version, ndata,
+                                  &elm->leaf);
        hammer_modify_buffer_done(data_buffer);
        hammer_cursor_invalidate_cache(cursor);
 
@@ -490,6 +497,7 @@ hammer_reblock_data(struct hammer_ioc_reblock *reblock,
                           &elm->leaf.data_offset, sizeof(hammer_off_t));
        odata_offset = elm->leaf.data_offset;
        elm->leaf.data_offset = ndata_offset;
+       elm->leaf.data_crc = ncrc;
        hammer_modify_node_done(cursor->node);
 
        if (hammer_debug_general & 0x4000) {
index fa2e5fb..f34ecf8 100644 (file)
@@ -157,10 +157,10 @@ struct hammer_rterm_rb_tree;
 RB_HEAD(hammer_rterm_rb_tree, hammer_rterm);
 RB_PROTOTYPE(hammer_rterm_rb_tree, hammer_rterm, rb_node, hammer_rterm_rb_cmp);
 
-static int hammer_check_tail_signature(hammer_fifo_tail_t tail,
-                       hammer_off_t end_off);
-static int hammer_check_head_signature(hammer_fifo_head_t head,
-                       hammer_off_t beg_off);
+static int hammer_check_tail_signature(hammer_mount_t hmp,
+                       hammer_fifo_tail_t tail, hammer_off_t end_off);
+static int hammer_check_head_signature(hammer_mount_t hmp,
+                       hammer_fifo_head_t head, hammer_off_t beg_off);
 static void hammer_recover_copy_undo(hammer_off_t undo_offset,
                        char *src, char *dst, int bytes);
 static hammer_fifo_any_t hammer_recover_scan_fwd(hammer_mount_t hmp,
@@ -804,7 +804,7 @@ hammer_recover_scan_rev(hammer_mount_t hmp, hammer_volume_t root_volume,
                return (NULL);
        }
 
-       if (hammer_check_tail_signature(tail, scan_offset) != 0) {
+       if (hammer_check_tail_signature(hmp, tail, scan_offset) != 0) {
                hvkprintf(root_volume,
                        "Illegal UNDO TAIL signature at %016jx\n",
                        (intmax_t)scan_offset - sizeof(*tail));
@@ -849,7 +849,7 @@ hammer_recover_scan_fwd(hammer_mount_t hmp, hammer_volume_t root_volume,
                return (NULL);
        }
 
-       if (hammer_check_head_signature(&head->head, scan_offset) != 0) {
+       if (hammer_check_head_signature(hmp, &head->head, scan_offset) != 0) {
                hvkprintf(root_volume,
                        "Illegal UNDO TAIL signature at %016jx\n",
                        (intmax_t)scan_offset);
@@ -872,11 +872,11 @@ hammer_recover_scan_fwd(hammer_mount_t hmp, hammer_volume_t root_volume,
  */
 static __inline
 int
-_hammer_check_signature(hammer_fifo_head_t head, hammer_fifo_tail_t tail,
+_hammer_check_signature(hammer_mount_t hmp,
+                       hammer_fifo_head_t head, hammer_fifo_tail_t tail,
                        hammer_off_t beg_off)
 {
        hammer_off_t end_off;
-       uint32_t crc;
        int bytes;
 
        /*
@@ -928,11 +928,10 @@ _hammer_check_signature(hammer_fifo_head_t head, hammer_fifo_tail_t tail,
         * least large enough to fit the head and tail.
         */
        if (head->hdr_type != HAMMER_HEAD_TYPE_PAD) {
-               crc = hammer_crc_get_fifo_head(head, head->hdr_size);
-               if (head->hdr_crc != crc) {
-                       hkprintf("FIFO record CRC failed %08x %08x at %016jx\n",
-                               head->hdr_crc, crc,
-                               (intmax_t)beg_off);
+               if (hammer_crc_test_fifo_head(hmp->version,
+                                             head, head->hdr_size) == 0) {
+                       hkprintf("FIFO record CRC failed %08x at %016jx\n",
+                               head->hdr_crc, (intmax_t)beg_off);
                        return(EIO);
                }
                if (head->hdr_size < sizeof(*head) + sizeof(*tail)) {
@@ -972,7 +971,8 @@ _hammer_check_signature(hammer_fifo_head_t head, hammer_fifo_tail_t tail,
  * but does not check beyond the signature, type, and size.
  */
 static int
-hammer_check_head_signature(hammer_fifo_head_t head, hammer_off_t beg_off)
+hammer_check_head_signature(hammer_mount_t hmp, hammer_fifo_head_t head,
+                           hammer_off_t beg_off)
 {
        hammer_fifo_tail_t tail;
        hammer_off_t end_off;
@@ -992,7 +992,7 @@ hammer_check_head_signature(hammer_fifo_head_t head, hammer_off_t beg_off)
        if ((beg_off ^ (end_off - 1)) & ~HAMMER_BUFMASK64)
                return(1);
        tail = (void *)((char *)head + head->hdr_size - sizeof(*tail));
-       return (_hammer_check_signature(head, tail, beg_off));
+       return (_hammer_check_signature(hmp, head, tail, beg_off));
 }
 
 /*
@@ -1004,7 +1004,8 @@ hammer_check_head_signature(hammer_fifo_head_t head, hammer_off_t beg_off)
  * but does not check beyond the signature, type, and size.
  */
 static int
-hammer_check_tail_signature(hammer_fifo_tail_t tail, hammer_off_t end_off)
+hammer_check_tail_signature(hammer_mount_t hmp, hammer_fifo_tail_t tail,
+                           hammer_off_t end_off)
 {
        hammer_fifo_head_t head;
        hammer_off_t beg_off;
@@ -1023,7 +1024,7 @@ hammer_check_tail_signature(hammer_fifo_tail_t tail, hammer_off_t end_off)
        if ((beg_off ^ (end_off - 1)) & ~HAMMER_BUFMASK64)
                return(1);
        head = (void *)((char *)tail + sizeof(*tail) - tail->tail_size);
-       return (_hammer_check_signature(head, tail, beg_off));
+       return (_hammer_check_signature(hmp, head, tail, beg_off));
 }
 
 static int
index 2369e27..3b38db7 100644 (file)
@@ -109,7 +109,8 @@ hammer_generate_redo(hammer_transaction_t trans, hammer_inode_t ip,
                 */
                if ((next_offset & HAMMER_BUFMASK) == 0) {
                        redo = hammer_bnew(hmp, next_offset, &error, &buffer);
-                       hammer_format_undo(redo, hmp->undo_seqno ^ 0x40000000);
+                       hammer_format_undo(hmp,
+                                          redo, hmp->undo_seqno ^ 0x40000000);
                } else {
                        redo = hammer_bread(hmp, next_offset, &error, &buffer);
                }
@@ -238,7 +239,7 @@ hammer_generate_redo(hammer_transaction_t trans, hammer_inode_t ip,
                tail->tail_size = bytes;
 
                KKASSERT(bytes >= sizeof(redo->head));
-               hammer_crc_set_fifo_head(&redo->head, bytes);
+               hammer_crc_set_fifo_head(hmp->version, &redo->head, bytes);
                undomap->next_offset += bytes;
                hammer_stats_redo += bytes;
 
index 5e6c4a1..cbed713 100644 (file)
@@ -154,7 +154,8 @@ hammer_generate_undo(hammer_transaction_t trans,
                 */
                if ((next_offset & HAMMER_BUFMASK) == 0) {
                        undo = hammer_bnew(hmp, next_offset, &error, &buffer);
-                       hammer_format_undo(undo, hmp->undo_seqno ^ 0x40000000);
+                       hammer_format_undo(hmp, undo,
+                                          hmp->undo_seqno ^ 0x40000000);
                } else {
                        undo = hammer_bread(hmp, next_offset, &error, &buffer);
                }
@@ -238,7 +239,7 @@ hammer_generate_undo(hammer_transaction_t trans,
                tail->tail_size = bytes;
 
                KKASSERT(bytes >= sizeof(undo->head));
-               hammer_crc_set_fifo_head(&undo->head, bytes);
+               hammer_crc_set_fifo_head(hmp->version, &undo->head, bytes);
                undomap->next_offset += bytes;
                hammer_stats_undo += bytes;
 
@@ -301,7 +302,7 @@ hammer_generate_undo(hammer_transaction_t trans,
  * NOTE: Also used by the REDO code.
  */
 void
-hammer_format_undo(void *base, uint32_t seqno)
+hammer_format_undo(hammer_mount_t hmp, void *base, uint32_t seqno)
 {
        hammer_fifo_head_t head;
        hammer_fifo_tail_t tail;
@@ -324,7 +325,7 @@ hammer_format_undo(void *base, uint32_t seqno)
                tail->tail_type = HAMMER_HEAD_TYPE_DUMMY;
                tail->tail_size = bytes;
 
-               hammer_crc_set_fifo_head(head, bytes);
+               hammer_crc_set_fifo_head(hmp->version, head, bytes);
        }
 }
 
@@ -395,7 +396,7 @@ hammer_upgrade_undo_4(hammer_transaction_t trans)
                tail->tail_type = HAMMER_HEAD_TYPE_DUMMY;
                tail->tail_size = bytes;
 
-               hammer_crc_set_fifo_head(head, bytes);
+               hammer_crc_set_fifo_head(hmp->version, head, bytes);
                hammer_modify_buffer_done(buffer);
 
                hammer_stats_undo += bytes;
index 73bc10c..1041818 100644 (file)
@@ -423,7 +423,7 @@ hammer_format_freemap(hammer_transaction_t trans, hammer_volume_t volume)
                        bzero(layer1, sizeof(*layer1));
                        layer1->phys_offset = alloc_offset;
                        layer1->blocks_free = 0;
-                       hammer_crc_set_layer1(layer1);
+                       hammer_crc_set_layer1(hmp->version, layer1);
                        hammer_modify_buffer_done(buffer1);
                        alloc_offset += HAMMER_BIGBLOCK_SIZE;
                }
@@ -467,13 +467,13 @@ hammer_format_freemap(hammer_transaction_t trans, hammer_volume_t volume)
                                layer2->bytes_free = 0;
                        }
 
-                       hammer_crc_set_layer2(layer2);
+                       hammer_crc_set_layer2(hmp->version, layer2);
                        hammer_modify_buffer_done(buffer2);
                }
 
                hammer_modify_buffer(trans, buffer1, layer1, sizeof(*layer1));
                layer1->blocks_free += layer1_count;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(hmp->version, layer1);
                hammer_modify_buffer_done(buffer1);
        }
 
@@ -596,7 +596,7 @@ hammer_free_freemap(hammer_transaction_t trans, hammer_volume_t volume)
                hammer_modify_buffer(trans, buffer1, layer1, sizeof(*layer1));
                bzero(layer1, sizeof(*layer1));
                layer1->phys_offset = HAMMER_BLOCKMAP_UNAVAIL;
-               hammer_crc_set_layer1(layer1);
+               hammer_crc_set_layer1(hmp->version, layer1);
                hammer_modify_buffer_done(buffer1);
        }
 
@@ -695,7 +695,7 @@ hammer_update_volumes_header(hammer_transaction_t trans,
                 * messed with by bioops.
                 */
                if (volume != trans->rootvol && volume->io.modified) {
-                       hammer_crc_set_volume(volume->ondisk);
+                       hammer_crc_set_volume(hmp->version, volume->ondisk);
                        hammer_io_flush(&volume->io, 0);
                }