From: Matthew Dillon Date: Fri, 17 Mar 2017 21:06:24 +0000 (-0700) Subject: hammer - HAMMER Version 7 X-Git-Tag: v5.1.0~733 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/4c09d9c4fd910651904ede280ad90a4abf3fc5d7 hammer - HAMMER Version 7 * 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). --- diff --git a/sbin/hammer/blockmap.c b/sbin/hammer/blockmap.c index 1ff4eb2071..48690dc28b 100644 --- a/sbin/hammer/blockmap.c +++ b/sbin/hammer/blockmap.c @@ -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; diff --git a/sbin/hammer/cmd_blockmap.c b/sbin/hammer/cmd_blockmap.c index 5ea245cb5d..ddc1ca44e9 100644 --- a/sbin/hammer/cmd_blockmap.c +++ b/sbin/hammer/cmd_blockmap.c @@ -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'; } diff --git a/sbin/hammer/cmd_cleanup.c b/sbin/hammer/cmd_cleanup.c index aa339bd9aa..7b97fedd6b 100644 --- a/sbin/hammer/cmd_cleanup.c +++ b/sbin/hammer/cmd_cleanup.c @@ -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) { diff --git a/sbin/hammer/cmd_config.c b/sbin/hammer/cmd_config.c index 9f84e01feb..c1e308bfda 100644 --- a/sbin/hammer/cmd_config.c +++ b/sbin/hammer/cmd_config.c @@ -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); diff --git a/sbin/hammer/cmd_mirror.c b/sbin/hammer/cmd_mirror.c index 8fd69c1e73..7bfffd17c3 100644 --- a/sbin/hammer/cmd_mirror.c +++ b/sbin/hammer/cmd_mirror.c @@ -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", diff --git a/sbin/hammer/cmd_pfs.c b/sbin/hammer/cmd_pfs.c index bee829b080..40b3231143 100644 --- a/sbin/hammer/cmd_pfs.c +++ b/sbin/hammer/cmd_pfs.c @@ -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 " diff --git a/sbin/hammer/cmd_recover.c b/sbin/hammer/cmd_recover.c index d714c04357..a4189dae07 100644 --- a/sbin/hammer/cmd_recover.c +++ b/sbin/hammer/cmd_recover.c @@ -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) { diff --git a/sbin/hammer/cmd_show.c b/sbin/hammer/cmd_show.c index 0fadf28648..d00bb9b75e 100644 --- a/sbin/hammer/cmd_show.c +++ b/sbin/hammer/cmd_show.c @@ -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 diff --git a/sbin/hammer/cmd_snapshot.c b/sbin/hammer/cmd_snapshot.c index 3c7d3e75ad..bf98c48d54 100644 --- a/sbin/hammer/cmd_snapshot.c +++ b/sbin/hammer/cmd_snapshot.c @@ -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); diff --git a/sbin/hammer/cmd_softprune.c b/sbin/hammer/cmd_softprune.c index 656ee440d7..99ceb1f0fa 100644 --- a/sbin/hammer/cmd_softprune.c +++ b/sbin/hammer/cmd_softprune.c @@ -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); diff --git a/sbin/hammer/cmd_strip.c b/sbin/hammer/cmd_strip.c index aa3218cae8..040e12c939 100644 --- a/sbin/hammer/cmd_strip.c +++ b/sbin/hammer/cmd_strip.c @@ -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; diff --git a/sbin/hammer/cmd_version.c b/sbin/hammer/cmd_version.c index 605a68e7c7..6879d5e2b0 100644 --- a/sbin/hammer/cmd_version.c +++ b/sbin/hammer/cmd_version.c @@ -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"); diff --git a/sbin/hammer/hammer.8 b/sbin/hammer/hammer.8 index 6720ae69c4..74c559bf55 100644 --- a/sbin/hammer/hammer.8 +++ b/sbin/hammer/hammer.8 @@ -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 '. +You only have to do this once. .Sh FSYNC FLUSH MODES .Nm HAMMER implements five different fsync flush modes via the diff --git a/sbin/hammer/hammer.c b/sbin/hammer/hammer.c index 19880c50cc..e9c4cdba35 100644 --- a/sbin/hammer/hammer.c +++ b/sbin/hammer/hammer.c @@ -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; diff --git a/sbin/hammer/hammer_util.h b/sbin/hammer/hammer_util.h index 3de4266fbc..59819234a2 100644 --- a/sbin/hammer/hammer_util.h +++ b/sbin/hammer/hammer_util.h @@ -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); diff --git a/sbin/hammer/ondisk.c b/sbin/hammer/ondisk.c index 3cca713e9b..4d2058747d 100644 --- a/sbin/hammer/ondisk.c +++ b/sbin/hammer/ondisk.c @@ -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; } diff --git a/sbin/newfs_hammer/newfs_hammer.c b/sbin/newfs_hammer/newfs_hammer.c index 7640312f1c..8effec0aef 100644 --- a/sbin/newfs_hammer/newfs_hammer.c +++ b/sbin/newfs_hammer/newfs_hammer.c @@ -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); diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index afe7bd4315..1f743e0424 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -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, diff --git a/sys/vfs/hammer/hammer_blockmap.c b/sys/vfs/hammer/hammer_blockmap.c index e95ef465ac..0a88dbdab2 100644 --- a/sys/vfs/hammer/hammer_blockmap.c +++ b/sys/vfs/hammer/hammer_blockmap.c @@ -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); } diff --git a/sys/vfs/hammer/hammer_btree.c b/sys/vfs/hammer/hammer_btree.c index 8552f864e7..9636dacf36 100644 --- a/sys/vfs/hammer/hammer_btree.c +++ b/sys/vfs/hammer/hammer_btree.c @@ -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) diff --git a/sys/vfs/hammer/hammer_crc.h b/sys/vfs/hammer/hammer_crc.h index 052f683e4f..6a982f75e2 100644 --- a/sys/vfs/hammer/hammer_crc.h +++ b/sys/vfs/hammer/hammer_crc.h @@ -45,116 +45,164 @@ */ 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 diff --git a/sys/vfs/hammer/hammer_disk.h b/sys/vfs/hammer/hammer_disk.h index ef16b89f0a..8931cfd802 100644 --- a/sys/vfs/hammer/hammer_disk.h +++ b/sys/vfs/hammer/hammer_disk.h @@ -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 diff --git a/sys/vfs/hammer/hammer_flusher.c b/sys/vfs/hammer/hammer_flusher.c index ea24ad166e..45f86f18c1 100644 --- a/sys/vfs/hammer/hammer_flusher.c +++ b/sys/vfs/hammer/hammer_flusher.c @@ -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); diff --git a/sys/vfs/hammer/hammer_io.c b/sys/vfs/hammer/hammer_io.c index d0071d40a8..2f022218a4 100644 --- a/sys/vfs/hammer/hammer_io.c +++ b/sys/vfs/hammer/hammer_io.c @@ -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; diff --git a/sys/vfs/hammer/hammer_ioctl.c b/sys/vfs/hammer/hammer_ioctl.c index ea54f85749..e549aa5186 100644 --- a/sys/vfs/hammer/hammer_ioctl.c +++ b/sys/vfs/hammer/hammer_ioctl.c @@ -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"); diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c index bc82b38ec4..57c1ac3f3c 100644 --- a/sys/vfs/hammer/hammer_object.c +++ b/sys/vfs/hammer/hammer_object.c @@ -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); diff --git a/sys/vfs/hammer/hammer_ondisk.c b/sys/vfs/hammer/hammer_ondisk.c index 49f3702c41..a00c4dc189 100644 --- a/sys/vfs/hammer/hammer_ondisk.c +++ b/sys/vfs/hammer/hammer_ondisk.c @@ -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)); diff --git a/sys/vfs/hammer/hammer_reblock.c b/sys/vfs/hammer/hammer_reblock.c index 8997e9bd97..af488a7ff4 100644 --- a/sys/vfs/hammer/hammer_reblock.c +++ b/sys/vfs/hammer/hammer_reblock.c @@ -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) { diff --git a/sys/vfs/hammer/hammer_recover.c b/sys/vfs/hammer/hammer_recover.c index fa2e5fbe28..f34ecf8475 100644 --- a/sys/vfs/hammer/hammer_recover.c +++ b/sys/vfs/hammer/hammer_recover.c @@ -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 diff --git a/sys/vfs/hammer/hammer_redo.c b/sys/vfs/hammer/hammer_redo.c index 2369e271ae..3b38db7500 100644 --- a/sys/vfs/hammer/hammer_redo.c +++ b/sys/vfs/hammer/hammer_redo.c @@ -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; diff --git a/sys/vfs/hammer/hammer_undo.c b/sys/vfs/hammer/hammer_undo.c index 5e6c4a196a..cbed713cc1 100644 --- a/sys/vfs/hammer/hammer_undo.c +++ b/sys/vfs/hammer/hammer_undo.c @@ -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; diff --git a/sys/vfs/hammer/hammer_volume.c b/sys/vfs/hammer/hammer_volume.c index 73bc10c778..1041818336 100644 --- a/sys/vfs/hammer/hammer_volume.c +++ b/sys/vfs/hammer/hammer_volume.c @@ -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); }