1*9f988b79SJean-Baptiste Boric /*-
2*9f988b79SJean-Baptiste Boric * Copyright (c) 2012 Department of Software Engineering,
3*9f988b79SJean-Baptiste Boric * University of Szeged, Hungary
4*9f988b79SJean-Baptiste Boric * Copyright (c) 2012 Tamas Toth <ttoth@inf.u-szeged.hu>
5*9f988b79SJean-Baptiste Boric * All rights reserved.
6*9f988b79SJean-Baptiste Boric *
7*9f988b79SJean-Baptiste Boric * This code is derived from software contributed to The NetBSD Foundation
8*9f988b79SJean-Baptiste Boric * by the Department of Software Engineering, University of Szeged, Hungary
9*9f988b79SJean-Baptiste Boric *
10*9f988b79SJean-Baptiste Boric * Redistribution and use in source and binary forms, with or without
11*9f988b79SJean-Baptiste Boric * modification, are permitted provided that the following conditions
12*9f988b79SJean-Baptiste Boric * are met:
13*9f988b79SJean-Baptiste Boric * 1. Redistributions of source code must retain the above copyright
14*9f988b79SJean-Baptiste Boric * notice, this list of conditions and the following disclaimer.
15*9f988b79SJean-Baptiste Boric * 2. Redistributions in binary form must reproduce the above copyright
16*9f988b79SJean-Baptiste Boric * notice, this list of conditions and the following disclaimer in the
17*9f988b79SJean-Baptiste Boric * documentation and/or other materials provided with the distribution.
18*9f988b79SJean-Baptiste Boric *
19*9f988b79SJean-Baptiste Boric * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20*9f988b79SJean-Baptiste Boric * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*9f988b79SJean-Baptiste Boric * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*9f988b79SJean-Baptiste Boric * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23*9f988b79SJean-Baptiste Boric * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24*9f988b79SJean-Baptiste Boric * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*9f988b79SJean-Baptiste Boric * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26*9f988b79SJean-Baptiste Boric * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27*9f988b79SJean-Baptiste Boric * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*9f988b79SJean-Baptiste Boric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*9f988b79SJean-Baptiste Boric * SUCH DAMAGE.
30*9f988b79SJean-Baptiste Boric */
31*9f988b79SJean-Baptiste Boric
32*9f988b79SJean-Baptiste Boric #if HAVE_NBTOOL_CONFIG_H
33*9f988b79SJean-Baptiste Boric #include "nbtool_config.h"
34*9f988b79SJean-Baptiste Boric #endif
35*9f988b79SJean-Baptiste Boric
36*9f988b79SJean-Baptiste Boric #include <sys/param.h>
37*9f988b79SJean-Baptiste Boric #include <sys/stat.h>
38*9f988b79SJean-Baptiste Boric
39*9f988b79SJean-Baptiste Boric #include <assert.h>
40*9f988b79SJean-Baptiste Boric #include <fcntl.h>
41*9f988b79SJean-Baptiste Boric #include <stdio.h>
42*9f988b79SJean-Baptiste Boric #include <stdlib.h>
43*9f988b79SJean-Baptiste Boric #include <string.h>
44*9f988b79SJean-Baptiste Boric #include <zlib.h>
45*9f988b79SJean-Baptiste Boric #include <util.h>
46*9f988b79SJean-Baptiste Boric
47*9f988b79SJean-Baptiste Boric #if defined(__minix)
48*9f988b79SJean-Baptiste Boric #include <unistd.h>
49*9f988b79SJean-Baptiste Boric #endif
50*9f988b79SJean-Baptiste Boric
51*9f988b79SJean-Baptiste Boric #include "makefs.h"
52*9f988b79SJean-Baptiste Boric #include "chfs_makefs.h"
53*9f988b79SJean-Baptiste Boric
54*9f988b79SJean-Baptiste Boric #include "media.h"
55*9f988b79SJean-Baptiste Boric #include "ebh.h"
56*9f988b79SJean-Baptiste Boric
57*9f988b79SJean-Baptiste Boric #include "chfs/chfs_mkfs.h"
58*9f988b79SJean-Baptiste Boric
59*9f988b79SJean-Baptiste Boric static uint32_t img_ofs = 0;
60*9f988b79SJean-Baptiste Boric static uint64_t version = 0;
61*9f988b79SJean-Baptiste Boric static uint64_t max_serial = 0;
62*9f988b79SJean-Baptiste Boric static int lebnumber = 0;
63*9f988b79SJean-Baptiste Boric
64*9f988b79SJean-Baptiste Boric static const unsigned char ffbuf[16] = {
65*9f988b79SJean-Baptiste Boric 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
66*9f988b79SJean-Baptiste Boric 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
67*9f988b79SJean-Baptiste Boric };
68*9f988b79SJean-Baptiste Boric
69*9f988b79SJean-Baptiste Boric static void
buf_write(fsinfo_t * fsopts,const void * buf,size_t len)70*9f988b79SJean-Baptiste Boric buf_write(fsinfo_t *fsopts, const void *buf, size_t len)
71*9f988b79SJean-Baptiste Boric {
72*9f988b79SJean-Baptiste Boric ssize_t retval;
73*9f988b79SJean-Baptiste Boric const char *charbuf = buf;
74*9f988b79SJean-Baptiste Boric
75*9f988b79SJean-Baptiste Boric while (len > 0) {
76*9f988b79SJean-Baptiste Boric retval = write(fsopts->fd, charbuf, len);
77*9f988b79SJean-Baptiste Boric
78*9f988b79SJean-Baptiste Boric if (retval == -1) {
79*9f988b79SJean-Baptiste Boric err(EXIT_FAILURE, "ERROR while writing");
80*9f988b79SJean-Baptiste Boric }
81*9f988b79SJean-Baptiste Boric
82*9f988b79SJean-Baptiste Boric len -= retval;
83*9f988b79SJean-Baptiste Boric charbuf += retval;
84*9f988b79SJean-Baptiste Boric img_ofs += retval;
85*9f988b79SJean-Baptiste Boric }
86*9f988b79SJean-Baptiste Boric }
87*9f988b79SJean-Baptiste Boric
88*9f988b79SJean-Baptiste Boric void
padblock(fsinfo_t * fsopts)89*9f988b79SJean-Baptiste Boric padblock(fsinfo_t *fsopts)
90*9f988b79SJean-Baptiste Boric {
91*9f988b79SJean-Baptiste Boric chfs_opt_t *chfs_opts = fsopts->fs_specific;
92*9f988b79SJean-Baptiste Boric while (img_ofs % chfs_opts->eraseblock) {
93*9f988b79SJean-Baptiste Boric buf_write(fsopts, ffbuf, MIN(sizeof(ffbuf),
94*9f988b79SJean-Baptiste Boric chfs_opts->eraseblock - (img_ofs % chfs_opts->eraseblock)));
95*9f988b79SJean-Baptiste Boric }
96*9f988b79SJean-Baptiste Boric }
97*9f988b79SJean-Baptiste Boric
98*9f988b79SJean-Baptiste Boric static void
padword(fsinfo_t * fsopts)99*9f988b79SJean-Baptiste Boric padword(fsinfo_t *fsopts)
100*9f988b79SJean-Baptiste Boric {
101*9f988b79SJean-Baptiste Boric if (img_ofs % 4) {
102*9f988b79SJean-Baptiste Boric buf_write(fsopts, ffbuf, 4 - img_ofs % 4);
103*9f988b79SJean-Baptiste Boric }
104*9f988b79SJean-Baptiste Boric }
105*9f988b79SJean-Baptiste Boric
106*9f988b79SJean-Baptiste Boric static void
pad_block_if_less_than(fsinfo_t * fsopts,int req)107*9f988b79SJean-Baptiste Boric pad_block_if_less_than(fsinfo_t *fsopts, int req)
108*9f988b79SJean-Baptiste Boric {
109*9f988b79SJean-Baptiste Boric chfs_opt_t *chfs_opts = fsopts->fs_specific;
110*9f988b79SJean-Baptiste Boric if ((img_ofs % chfs_opts->eraseblock) + req >
111*9f988b79SJean-Baptiste Boric (uint32_t)chfs_opts->eraseblock) {
112*9f988b79SJean-Baptiste Boric padblock(fsopts);
113*9f988b79SJean-Baptiste Boric write_eb_header(fsopts);
114*9f988b79SJean-Baptiste Boric }
115*9f988b79SJean-Baptiste Boric }
116*9f988b79SJean-Baptiste Boric
117*9f988b79SJean-Baptiste Boric void
write_eb_header(fsinfo_t * fsopts)118*9f988b79SJean-Baptiste Boric write_eb_header(fsinfo_t *fsopts)
119*9f988b79SJean-Baptiste Boric {
120*9f988b79SJean-Baptiste Boric chfs_opt_t *opts;
121*9f988b79SJean-Baptiste Boric struct chfs_eb_hdr ebhdr;
122*9f988b79SJean-Baptiste Boric char *buf;
123*9f988b79SJean-Baptiste Boric
124*9f988b79SJean-Baptiste Boric opts = fsopts->fs_specific;
125*9f988b79SJean-Baptiste Boric
126*9f988b79SJean-Baptiste Boric #define MINSIZE MAX(MAX(CHFS_EB_EC_HDR_SIZE, CHFS_EB_HDR_NOR_SIZE), \
127*9f988b79SJean-Baptiste Boric CHFS_EB_HDR_NAND_SIZE)
128*9f988b79SJean-Baptiste Boric if ((uint32_t)opts->pagesize < MINSIZE)
129*9f988b79SJean-Baptiste Boric errx(EXIT_FAILURE, "pagesize cannot be less than %zu", MINSIZE);
130*9f988b79SJean-Baptiste Boric buf = emalloc(opts->pagesize);
131*9f988b79SJean-Baptiste Boric memset(buf, 0xFF, opts->pagesize);
132*9f988b79SJean-Baptiste Boric
133*9f988b79SJean-Baptiste Boric ebhdr.ec_hdr.magic = htole32(CHFS_MAGIC_BITMASK);
134*9f988b79SJean-Baptiste Boric ebhdr.ec_hdr.erase_cnt = htole32(1);
135*9f988b79SJean-Baptiste Boric ebhdr.ec_hdr.crc_ec = htole32(crc32(0,
136*9f988b79SJean-Baptiste Boric (uint8_t *)&ebhdr.ec_hdr + 8, 4));
137*9f988b79SJean-Baptiste Boric
138*9f988b79SJean-Baptiste Boric memcpy(buf, &ebhdr.ec_hdr, CHFS_EB_EC_HDR_SIZE);
139*9f988b79SJean-Baptiste Boric
140*9f988b79SJean-Baptiste Boric buf_write(fsopts, buf, opts->pagesize);
141*9f988b79SJean-Baptiste Boric
142*9f988b79SJean-Baptiste Boric memset(buf, 0xFF, opts->pagesize);
143*9f988b79SJean-Baptiste Boric
144*9f988b79SJean-Baptiste Boric if (opts->mediatype == TYPE_NAND) {
145*9f988b79SJean-Baptiste Boric ebhdr.u.nand_hdr.lid = htole32(lebnumber++);
146*9f988b79SJean-Baptiste Boric ebhdr.u.nand_hdr.serial = htole64(++(max_serial));
147*9f988b79SJean-Baptiste Boric ebhdr.u.nand_hdr.crc = htole32(crc32(0,
148*9f988b79SJean-Baptiste Boric (uint8_t *)&ebhdr.u.nand_hdr + 4,
149*9f988b79SJean-Baptiste Boric CHFS_EB_HDR_NAND_SIZE - 4));
150*9f988b79SJean-Baptiste Boric memcpy(buf, &ebhdr.u.nand_hdr, CHFS_EB_HDR_NAND_SIZE);
151*9f988b79SJean-Baptiste Boric } else {
152*9f988b79SJean-Baptiste Boric ebhdr.u.nor_hdr.lid = htole32(lebnumber++);
153*9f988b79SJean-Baptiste Boric ebhdr.u.nor_hdr.crc = htole32(crc32(0,
154*9f988b79SJean-Baptiste Boric (uint8_t *)&ebhdr.u.nor_hdr + 4,
155*9f988b79SJean-Baptiste Boric CHFS_EB_HDR_NOR_SIZE - 4));
156*9f988b79SJean-Baptiste Boric memcpy(buf, &ebhdr.u.nor_hdr, CHFS_EB_HDR_NOR_SIZE);
157*9f988b79SJean-Baptiste Boric }
158*9f988b79SJean-Baptiste Boric
159*9f988b79SJean-Baptiste Boric buf_write(fsopts, buf, opts->pagesize);
160*9f988b79SJean-Baptiste Boric free(buf);
161*9f988b79SJean-Baptiste Boric }
162*9f988b79SJean-Baptiste Boric
163*9f988b79SJean-Baptiste Boric void
write_vnode(fsinfo_t * fsopts,fsnode * node)164*9f988b79SJean-Baptiste Boric write_vnode(fsinfo_t *fsopts, fsnode *node)
165*9f988b79SJean-Baptiste Boric {
166*9f988b79SJean-Baptiste Boric struct chfs_flash_vnode fvnode;
167*9f988b79SJean-Baptiste Boric memset(&fvnode, 0, sizeof(fvnode));
168*9f988b79SJean-Baptiste Boric
169*9f988b79SJean-Baptiste Boric fvnode.magic = htole16(CHFS_FS_MAGIC_BITMASK);
170*9f988b79SJean-Baptiste Boric fvnode.type = htole16(CHFS_NODETYPE_VNODE);
171*9f988b79SJean-Baptiste Boric fvnode.length = htole32(CHFS_PAD(sizeof(fvnode)));
172*9f988b79SJean-Baptiste Boric fvnode.hdr_crc = htole32(crc32(0, (uint8_t *)&fvnode,
173*9f988b79SJean-Baptiste Boric CHFS_NODE_HDR_SIZE - 4));
174*9f988b79SJean-Baptiste Boric fvnode.vno = htole64(node->inode->ino);
175*9f988b79SJean-Baptiste Boric fvnode.version = htole64(version++);
176*9f988b79SJean-Baptiste Boric fvnode.mode = htole32(node->inode->st.st_mode);
177*9f988b79SJean-Baptiste Boric fvnode.dn_size = htole32(node->inode->st.st_size);
178*9f988b79SJean-Baptiste Boric fvnode.atime = htole32(node->inode->st.st_atime);
179*9f988b79SJean-Baptiste Boric fvnode.ctime = htole32(node->inode->st.st_ctime);
180*9f988b79SJean-Baptiste Boric fvnode.mtime = htole32(node->inode->st.st_mtime);
181*9f988b79SJean-Baptiste Boric fvnode.gid = htole32(node->inode->st.st_uid);
182*9f988b79SJean-Baptiste Boric fvnode.uid = htole32(node->inode->st.st_gid);
183*9f988b79SJean-Baptiste Boric fvnode.node_crc = htole32(crc32(0, (uint8_t *)&fvnode,
184*9f988b79SJean-Baptiste Boric sizeof(fvnode) - 4));
185*9f988b79SJean-Baptiste Boric
186*9f988b79SJean-Baptiste Boric pad_block_if_less_than(fsopts, sizeof(fvnode));
187*9f988b79SJean-Baptiste Boric buf_write(fsopts, &fvnode, sizeof(fvnode));
188*9f988b79SJean-Baptiste Boric padword(fsopts);
189*9f988b79SJean-Baptiste Boric }
190*9f988b79SJean-Baptiste Boric
191*9f988b79SJean-Baptiste Boric void
write_dirent(fsinfo_t * fsopts,fsnode * node)192*9f988b79SJean-Baptiste Boric write_dirent(fsinfo_t *fsopts, fsnode *node)
193*9f988b79SJean-Baptiste Boric {
194*9f988b79SJean-Baptiste Boric struct chfs_flash_dirent_node fdirent;
195*9f988b79SJean-Baptiste Boric char *name;
196*9f988b79SJean-Baptiste Boric
197*9f988b79SJean-Baptiste Boric name = emalloc(strlen(node->name));
198*9f988b79SJean-Baptiste Boric memcpy(name, node->name, strlen(node->name));
199*9f988b79SJean-Baptiste Boric
200*9f988b79SJean-Baptiste Boric memset(&fdirent, 0, sizeof(fdirent));
201*9f988b79SJean-Baptiste Boric fdirent.magic = htole16(CHFS_FS_MAGIC_BITMASK);
202*9f988b79SJean-Baptiste Boric fdirent.type = htole16(CHFS_NODETYPE_DIRENT);
203*9f988b79SJean-Baptiste Boric fdirent.length = htole32(CHFS_PAD(sizeof(fdirent) + strlen(name)));
204*9f988b79SJean-Baptiste Boric fdirent.hdr_crc = htole32(crc32(0, (uint8_t *)&fdirent,
205*9f988b79SJean-Baptiste Boric CHFS_NODE_HDR_SIZE - 4));
206*9f988b79SJean-Baptiste Boric fdirent.vno = htole64(node->inode->ino);
207*9f988b79SJean-Baptiste Boric if (node->parent != NULL) {
208*9f988b79SJean-Baptiste Boric fdirent.pvno = htole64(node->parent->inode->ino);
209*9f988b79SJean-Baptiste Boric } else {
210*9f988b79SJean-Baptiste Boric fdirent.pvno = htole64(node->inode->ino);
211*9f988b79SJean-Baptiste Boric }
212*9f988b79SJean-Baptiste Boric
213*9f988b79SJean-Baptiste Boric fdirent.version = htole64(version++);
214*9f988b79SJean-Baptiste Boric fdirent.mctime = 0;
215*9f988b79SJean-Baptiste Boric fdirent.nsize = htole32(strlen(name));
216*9f988b79SJean-Baptiste Boric fdirent.dtype = htole32(IFTOCHT(node->type & S_IFMT));
217*9f988b79SJean-Baptiste Boric fdirent.name_crc = htole32(crc32(0, (uint8_t *)name, fdirent.nsize));
218*9f988b79SJean-Baptiste Boric fdirent.node_crc = htole32(crc32(0, (uint8_t *)&fdirent,
219*9f988b79SJean-Baptiste Boric sizeof(fdirent) - 4));
220*9f988b79SJean-Baptiste Boric
221*9f988b79SJean-Baptiste Boric pad_block_if_less_than(fsopts, sizeof(fdirent) + fdirent.nsize);
222*9f988b79SJean-Baptiste Boric buf_write(fsopts, &fdirent, sizeof(fdirent));
223*9f988b79SJean-Baptiste Boric buf_write(fsopts, name, fdirent.nsize);
224*9f988b79SJean-Baptiste Boric padword(fsopts);
225*9f988b79SJean-Baptiste Boric }
226*9f988b79SJean-Baptiste Boric
227*9f988b79SJean-Baptiste Boric void
write_file(fsinfo_t * fsopts,fsnode * node,const char * dir)228*9f988b79SJean-Baptiste Boric write_file(fsinfo_t *fsopts, fsnode *node, const char *dir)
229*9f988b79SJean-Baptiste Boric {
230*9f988b79SJean-Baptiste Boric int fd;
231*9f988b79SJean-Baptiste Boric ssize_t len;
232*9f988b79SJean-Baptiste Boric char *name = node->name;
233*9f988b79SJean-Baptiste Boric chfs_opt_t *opts;
234*9f988b79SJean-Baptiste Boric unsigned char *buf;
235*9f988b79SJean-Baptiste Boric uint32_t fileofs = 0;
236*9f988b79SJean-Baptiste Boric
237*9f988b79SJean-Baptiste Boric opts = fsopts->fs_specific;
238*9f988b79SJean-Baptiste Boric buf = emalloc(opts->pagesize);
239*9f988b79SJean-Baptiste Boric if (node->type == S_IFREG || node->type == S_IFSOCK) {
240*9f988b79SJean-Baptiste Boric char *longname;
241*9f988b79SJean-Baptiste Boric if (asprintf(&longname, "%s/%s", dir, name) == 1)
242*9f988b79SJean-Baptiste Boric goto out;
243*9f988b79SJean-Baptiste Boric
244*9f988b79SJean-Baptiste Boric fd = open(longname, O_RDONLY, 0444);
245*9f988b79SJean-Baptiste Boric if (fd == -1)
246*9f988b79SJean-Baptiste Boric err(EXIT_FAILURE, "Cannot open `%s'", longname);
247*9f988b79SJean-Baptiste Boric
248*9f988b79SJean-Baptiste Boric while ((len = read(fd, buf, opts->pagesize))) {
249*9f988b79SJean-Baptiste Boric if (len < 0) {
250*9f988b79SJean-Baptiste Boric warn("ERROR while reading %s", longname);
251*9f988b79SJean-Baptiste Boric free(longname);
252*9f988b79SJean-Baptiste Boric free(buf);
253*9f988b79SJean-Baptiste Boric close(fd);
254*9f988b79SJean-Baptiste Boric return;
255*9f988b79SJean-Baptiste Boric }
256*9f988b79SJean-Baptiste Boric
257*9f988b79SJean-Baptiste Boric write_data(fsopts, node, buf, len, fileofs);
258*9f988b79SJean-Baptiste Boric fileofs += len;
259*9f988b79SJean-Baptiste Boric }
260*9f988b79SJean-Baptiste Boric free(longname);
261*9f988b79SJean-Baptiste Boric close(fd);
262*9f988b79SJean-Baptiste Boric } else if (node->type == S_IFLNK) {
263*9f988b79SJean-Baptiste Boric len = strlen(node->symlink);
264*9f988b79SJean-Baptiste Boric memcpy(buf, node->symlink, len);
265*9f988b79SJean-Baptiste Boric write_data(fsopts, node, buf, len, 0);
266*9f988b79SJean-Baptiste Boric } else if (node->type == S_IFCHR || node->type == S_IFBLK ||
267*9f988b79SJean-Baptiste Boric node->type == S_IFIFO) {
268*9f988b79SJean-Baptiste Boric len = sizeof(dev_t);
269*9f988b79SJean-Baptiste Boric memcpy(buf, &(node->inode->st.st_rdev), len);
270*9f988b79SJean-Baptiste Boric write_data(fsopts, node, buf, len, 0);
271*9f988b79SJean-Baptiste Boric }
272*9f988b79SJean-Baptiste Boric
273*9f988b79SJean-Baptiste Boric free(buf);
274*9f988b79SJean-Baptiste Boric return;
275*9f988b79SJean-Baptiste Boric out:
276*9f988b79SJean-Baptiste Boric err(EXIT_FAILURE, "Memory allocation failed");
277*9f988b79SJean-Baptiste Boric }
278*9f988b79SJean-Baptiste Boric
279*9f988b79SJean-Baptiste Boric void
write_data(fsinfo_t * fsopts,fsnode * node,unsigned char * buf,size_t len,uint32_t ofs)280*9f988b79SJean-Baptiste Boric write_data(fsinfo_t *fsopts, fsnode *node, unsigned char *buf, size_t len,
281*9f988b79SJean-Baptiste Boric uint32_t ofs)
282*9f988b79SJean-Baptiste Boric {
283*9f988b79SJean-Baptiste Boric struct chfs_flash_data_node fdata;
284*9f988b79SJean-Baptiste Boric
285*9f988b79SJean-Baptiste Boric memset(&fdata, 0, sizeof(fdata));
286*9f988b79SJean-Baptiste Boric if (len == 0) {
287*9f988b79SJean-Baptiste Boric return;
288*9f988b79SJean-Baptiste Boric }
289*9f988b79SJean-Baptiste Boric
290*9f988b79SJean-Baptiste Boric pad_block_if_less_than(fsopts, sizeof(fdata) + len);
291*9f988b79SJean-Baptiste Boric
292*9f988b79SJean-Baptiste Boric fdata.magic = htole16(CHFS_FS_MAGIC_BITMASK);
293*9f988b79SJean-Baptiste Boric fdata.type = htole16(CHFS_NODETYPE_DATA);
294*9f988b79SJean-Baptiste Boric fdata.length = htole32(CHFS_PAD(sizeof(fdata) + len));
295*9f988b79SJean-Baptiste Boric fdata.hdr_crc = htole32(crc32(0, (uint8_t *)&fdata,
296*9f988b79SJean-Baptiste Boric CHFS_NODE_HDR_SIZE - 4));
297*9f988b79SJean-Baptiste Boric fdata.vno = htole64(node->inode->ino);
298*9f988b79SJean-Baptiste Boric fdata.data_length = htole32(len);
299*9f988b79SJean-Baptiste Boric fdata.offset = htole32(ofs);
300*9f988b79SJean-Baptiste Boric fdata.data_crc = htole32(crc32(0, (uint8_t *)buf, len));
301*9f988b79SJean-Baptiste Boric fdata.node_crc = htole32(crc32(0,
302*9f988b79SJean-Baptiste Boric (uint8_t *)&fdata, sizeof(fdata) - 4));
303*9f988b79SJean-Baptiste Boric
304*9f988b79SJean-Baptiste Boric buf_write(fsopts, &fdata, sizeof(fdata));
305*9f988b79SJean-Baptiste Boric buf_write(fsopts, buf, len);
306*9f988b79SJean-Baptiste Boric padword(fsopts);
307*9f988b79SJean-Baptiste Boric }
308