2 * Copyright (c) 2007-2016 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #ifndef VFS_HAMMER_CRC_H_
36 #define VFS_HAMMER_CRC_H_
38 #include "hammer_disk.h"
39 #include "hammer_ioctl.h"
43 * These are only for userspace.
44 * Userspace can't include sys/sys/systm.h.
46 uint32_t crc32(const void *buf, size_t size);
47 uint32_t crc32_ext(const void *buf, size_t size, uint32_t ocrc);
50 static __inline hammer_crc_t
51 hammer_crc_get_blockmap(hammer_blockmap_t blockmap)
53 return(crc32(blockmap, HAMMER_BLOCKMAP_CRCSIZE));
57 hammer_crc_set_blockmap(hammer_blockmap_t blockmap)
59 blockmap->entry_crc = hammer_crc_get_blockmap(blockmap);
63 hammer_crc_test_blockmap(hammer_blockmap_t blockmap)
65 return(blockmap->entry_crc == hammer_crc_get_blockmap(blockmap));
68 static __inline hammer_crc_t
69 hammer_crc_get_layer1(hammer_blockmap_layer1_t layer1)
71 return(crc32(layer1, HAMMER_LAYER1_CRCSIZE));
75 hammer_crc_set_layer1(hammer_blockmap_layer1_t layer1)
77 layer1->layer1_crc = hammer_crc_get_layer1(layer1);
81 hammer_crc_test_layer1(hammer_blockmap_layer1_t layer1)
83 return(layer1->layer1_crc == hammer_crc_get_layer1(layer1));
86 static __inline hammer_crc_t
87 hammer_crc_get_layer2(hammer_blockmap_layer2_t layer2)
89 return(crc32(layer2, HAMMER_LAYER2_CRCSIZE));
93 hammer_crc_set_layer2(hammer_blockmap_layer2_t layer2)
95 layer2->entry_crc = hammer_crc_get_layer2(layer2);
99 hammer_crc_test_layer2(hammer_blockmap_layer2_t layer2)
101 return(layer2->entry_crc == hammer_crc_get_layer2(layer2));
104 static __inline hammer_crc_t
105 hammer_crc_get_volume(hammer_volume_ondisk_t ondisk)
107 return(crc32(ondisk, HAMMER_VOL_CRCSIZE1) ^
108 crc32(&ondisk->vol_crc + 1, HAMMER_VOL_CRCSIZE2));
112 hammer_crc_set_volume(hammer_volume_ondisk_t ondisk)
114 ondisk->vol_crc = hammer_crc_get_volume(ondisk);
118 hammer_crc_test_volume(hammer_volume_ondisk_t ondisk)
120 return(ondisk->vol_crc == hammer_crc_get_volume(ondisk));
123 static __inline hammer_crc_t
124 hammer_crc_get_fifo_head(hammer_fifo_head_t head, int bytes)
126 return(crc32(head, HAMMER_FIFO_HEAD_CRCOFF) ^
127 crc32(head + 1, bytes - sizeof(*head)));
131 hammer_crc_set_fifo_head(hammer_fifo_head_t head, int bytes)
133 head->hdr_crc = hammer_crc_get_fifo_head(head, bytes);
137 hammer_crc_test_fifo_head(hammer_fifo_head_t head, int bytes)
139 return(head->hdr_crc == hammer_crc_get_fifo_head(head, bytes));
142 static __inline hammer_crc_t
143 hammer_crc_get_btree(hammer_node_ondisk_t node)
145 return(crc32(&node->crc + 1, HAMMER_BTREE_CRCSIZE));
149 hammer_crc_set_btree(hammer_node_ondisk_t node)
151 node->crc = hammer_crc_get_btree(node);
155 hammer_crc_test_btree(hammer_node_ondisk_t node)
157 return(node->crc == hammer_crc_get_btree(node));
161 * Get the leaf->data_crc field. Deal with any special cases given
162 * a generic B-Tree leaf element and its data.
164 * NOTE: Inode-data: the atime and mtime fields are not CRCd,
165 * allowing them to be updated in-place.
167 static __inline hammer_crc_t
168 hammer_crc_get_leaf(void *data, hammer_btree_leaf_elm_t leaf)
172 if (leaf->data_len == 0)
175 switch(leaf->base.rec_type) {
176 case HAMMER_RECTYPE_INODE:
177 if (leaf->data_len != sizeof(struct hammer_inode_data))
178 return(0); /* This shouldn't happen */
179 crc = crc32(data, HAMMER_INODE_CRCSIZE);
182 crc = crc32(data, leaf->data_len);
189 hammer_crc_set_leaf(void *data, hammer_btree_leaf_elm_t leaf)
193 if (leaf->data_len && leaf->base.rec_type == HAMMER_RECTYPE_INODE)
194 KKASSERT(leaf->data_len == sizeof(struct hammer_inode_data));
197 leaf->data_crc = hammer_crc_get_leaf(data, leaf);
201 hammer_crc_test_leaf(void *data, hammer_btree_leaf_elm_t leaf)
203 return(leaf->data_crc == hammer_crc_get_leaf(data, leaf));
206 static __inline hammer_crc_t
207 hammer_crc_get_mrec_head(hammer_ioc_mrecord_head_t head, int bytes)
209 return(crc32(&head->rec_size, bytes - HAMMER_MREC_CRCOFF));
213 hammer_crc_set_mrec_head(hammer_ioc_mrecord_head_t head, int bytes)
215 head->rec_crc = hammer_crc_get_mrec_head(head, bytes);
219 hammer_crc_test_mrec_head(hammer_ioc_mrecord_head_t head, int bytes)
221 return(head->rec_crc == hammer_crc_get_mrec_head(head, bytes));
224 #endif /* !VFS_HAMMER_CRC_H_ */