mkfs.c revision 1.109 1 /* $NetBSD: mkfs.c,v 1.109 2011/03/06 17:08:16 bouyer Exp $ */
2
3 /*
4 * Copyright (c) 1980, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 2002 Networks Associates Technology, Inc.
34 * All rights reserved.
35 *
36 * This software was developed for the FreeBSD Project by Marshall
37 * Kirk McKusick and Network Associates Laboratories, the Security
38 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
39 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
40 * research program
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement:
52 * This product includes software developed by the University of
53 * California, Berkeley and its contributors.
54 * 4. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 */
70
71 #include <sys/cdefs.h>
72 #ifndef lint
73 #if 0
74 static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
75 #else
76 __RCSID("$NetBSD: mkfs.c,v 1.109 2011/03/06 17:08:16 bouyer Exp $");
77 #endif
78 #endif /* not lint */
79
80 #include <sys/param.h>
81 #include <sys/mman.h>
82 #include <sys/time.h>
83 #include <sys/resource.h>
84 #include <ufs/ufs/dinode.h>
85 #include <ufs/ufs/dir.h>
86 #include <ufs/ufs/ufs_bswap.h>
87 #include <ufs/ufs/quota2.h>
88 #include <ufs/ffs/fs.h>
89 #include <ufs/ffs/ffs_extern.h>
90 #include <sys/ioctl.h>
91 #include <sys/disklabel.h>
92
93 #include <err.h>
94 #include <errno.h>
95 #include <string.h>
96 #include <unistd.h>
97 #include <stdlib.h>
98 #include <stddef.h>
99
100 #ifndef STANDALONE
101 #include <stdio.h>
102 #endif
103
104 #include "extern.h"
105
106 union dinode {
107 struct ufs1_dinode dp1;
108 struct ufs2_dinode dp2;
109 };
110
111 static void initcg(int, const struct timeval *);
112 static int fsinit(const struct timeval *, mode_t, uid_t, gid_t);
113 static int makedir(struct direct *, int);
114 static daddr_t alloc(int, int);
115 static void iput(union dinode *, ino_t);
116 static void rdfs(daddr_t, int, void *);
117 static void wtfs(daddr_t, int, void *);
118 static int isblock(struct fs *, unsigned char *, int);
119 static void clrblock(struct fs *, unsigned char *, int);
120 static void setblock(struct fs *, unsigned char *, int);
121 static int ilog2(int);
122 static void zap_old_sblock(int);
123 #ifdef MFS
124 static void calc_memfree(void);
125 static void *mkfs_malloc(size_t size);
126 #endif
127
128 /*
129 * make file system for cylinder-group style file systems
130 */
131 #define UMASK 0755
132
133 union {
134 struct fs fs;
135 char pad[SBLOCKSIZE];
136 } fsun;
137 #define sblock fsun.fs
138
139 struct csum *fscs_0; /* first block of cylinder summaries */
140 struct csum *fscs_next; /* place for next summary */
141 struct csum *fscs_end; /* end of summary buffer */
142 struct csum *fscs_reset; /* place for next summary after write */
143 uint fs_csaddr; /* fragment number to write to */
144
145 union {
146 struct cg cg;
147 char pad[MAXBSIZE];
148 } cgun;
149 #define acg cgun.cg
150
151 #define DIP(dp, field) \
152 ((sblock.fs_magic == FS_UFS1_MAGIC) ? \
153 (dp)->dp1.di_##field : (dp)->dp2.di_##field)
154
155 char *iobuf;
156 int iobufsize; /* size to end of 2nd inode block */
157 int iobuf_memsize; /* Actual buffer size */
158
159 int fsi, fso;
160
161 static void
162 fserr(int num)
163 {
164 #ifdef GARBAGE
165 extern int Gflag;
166
167 if (Gflag)
168 return;
169 #endif
170 exit(num);
171 }
172
173 void
174 mkfs(const char *fsys, int fi, int fo,
175 mode_t mfsmode, uid_t mfsuid, gid_t mfsgid)
176 {
177 uint fragsperinodeblk, ncg, u;
178 uint cgzero;
179 uint64_t inodeblks, cgall;
180 int32_t cylno, i, csfrags;
181 int inodes_per_cg;
182 struct timeval tv;
183 long long sizepb;
184 int len, col, delta, fld_width, max_cols;
185 struct winsize winsize;
186
187 #ifndef STANDALONE
188 gettimeofday(&tv, NULL);
189 #endif
190 #ifdef MFS
191 if (mfs && !Nflag) {
192 calc_memfree();
193 if ((uint64_t)fssize * sectorsize > memleft)
194 fssize = memleft / sectorsize;
195 if ((membase = mkfs_malloc(fssize * sectorsize)) == NULL)
196 exit(12);
197 }
198 #endif
199 fsi = fi;
200 fso = fo;
201 if (Oflag == 0) {
202 sblock.fs_old_inodefmt = FS_42INODEFMT;
203 sblock.fs_maxsymlinklen = 0;
204 sblock.fs_old_flags = 0;
205 } else {
206 sblock.fs_old_inodefmt = FS_44INODEFMT;
207 sblock.fs_maxsymlinklen = (Oflag == 1 ? MAXSYMLINKLEN_UFS1 :
208 MAXSYMLINKLEN_UFS2);
209 sblock.fs_old_flags = FS_FLAGS_UPDATED;
210 if (isappleufs)
211 sblock.fs_old_flags = 0;
212 sblock.fs_flags = 0;
213 }
214
215 /*
216 * collect and verify the filesystem density info
217 */
218 sblock.fs_avgfilesize = avgfilesize;
219 sblock.fs_avgfpdir = avgfpdir;
220 if (sblock.fs_avgfilesize <= 0) {
221 printf("illegal expected average file size %d\n",
222 sblock.fs_avgfilesize);
223 fserr(14);
224 }
225 if (sblock.fs_avgfpdir <= 0) {
226 printf("illegal expected number of files per directory %d\n",
227 sblock.fs_avgfpdir);
228 fserr(15);
229 }
230 /*
231 * collect and verify the block and fragment sizes
232 */
233 sblock.fs_bsize = bsize;
234 sblock.fs_fsize = fsize;
235 if (!powerof2(sblock.fs_bsize)) {
236 printf("block size must be a power of 2, not %d\n",
237 sblock.fs_bsize);
238 fserr(16);
239 }
240 if (!powerof2(sblock.fs_fsize)) {
241 printf("fragment size must be a power of 2, not %d\n",
242 sblock.fs_fsize);
243 fserr(17);
244 }
245 if (sblock.fs_fsize < sectorsize) {
246 printf("fragment size %d is too small, minimum is %d\n",
247 sblock.fs_fsize, sectorsize);
248 fserr(18);
249 }
250 if (sblock.fs_bsize < MINBSIZE) {
251 printf("block size %d is too small, minimum is %d\n",
252 sblock.fs_bsize, MINBSIZE);
253 fserr(19);
254 }
255 if (sblock.fs_bsize > MAXBSIZE) {
256 printf("block size %d is too large, maximum is %d\n",
257 sblock.fs_bsize, MAXBSIZE);
258 fserr(19);
259 }
260 if (sblock.fs_bsize < sblock.fs_fsize) {
261 printf("block size (%d) cannot be smaller than fragment size (%d)\n",
262 sblock.fs_bsize, sblock.fs_fsize);
263 fserr(20);
264 }
265
266 if (maxbsize < bsize || !powerof2(maxbsize)) {
267 sblock.fs_maxbsize = sblock.fs_bsize;
268 } else if (sblock.fs_maxbsize > FS_MAXCONTIG * sblock.fs_bsize) {
269 sblock.fs_maxbsize = FS_MAXCONTIG * sblock.fs_bsize;
270 } else {
271 sblock.fs_maxbsize = maxbsize;
272 }
273 sblock.fs_maxcontig = maxcontig;
274 if (sblock.fs_maxcontig < sblock.fs_maxbsize / sblock.fs_bsize) {
275 sblock.fs_maxcontig = sblock.fs_maxbsize / sblock.fs_bsize;
276 if (verbosity > 0)
277 printf("Maxcontig raised to %d\n", sblock.fs_maxbsize);
278 }
279 if (sblock.fs_maxcontig > 1)
280 sblock.fs_contigsumsize = MIN(sblock.fs_maxcontig,FS_MAXCONTIG);
281
282 sblock.fs_bmask = ~(sblock.fs_bsize - 1);
283 sblock.fs_fmask = ~(sblock.fs_fsize - 1);
284 sblock.fs_qbmask = ~sblock.fs_bmask;
285 sblock.fs_qfmask = ~sblock.fs_fmask;
286 for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1)
287 sblock.fs_bshift++;
288 for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1)
289 sblock.fs_fshift++;
290 sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize);
291 for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1)
292 sblock.fs_fragshift++;
293 if (sblock.fs_frag > MAXFRAG) {
294 printf("fragment size %d is too small, "
295 "minimum with block size %d is %d\n",
296 sblock.fs_fsize, sblock.fs_bsize,
297 sblock.fs_bsize / MAXFRAG);
298 fserr(21);
299 }
300 sblock.fs_fsbtodb = ilog2(sblock.fs_fsize / sectorsize);
301 sblock.fs_size = dbtofsb(&sblock, fssize);
302 if (Oflag <= 1) {
303 if ((uint64_t)sblock.fs_size >= 1ull << 31) {
304 printf("Too many fragments (0x%" PRIx64
305 ") for a FFSv1 filesystem\n", sblock.fs_size);
306 fserr(22);
307 }
308 sblock.fs_magic = FS_UFS1_MAGIC;
309 sblock.fs_sblockloc = SBLOCK_UFS1;
310 sblock.fs_nindir = sblock.fs_bsize / sizeof(int32_t);
311 sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs1_dinode);
312 sblock.fs_old_cgoffset = 0;
313 sblock.fs_old_cgmask = 0xffffffff;
314 sblock.fs_old_size = sblock.fs_size;
315 sblock.fs_old_rotdelay = 0;
316 sblock.fs_old_rps = 60;
317 sblock.fs_old_nspf = sblock.fs_fsize / sectorsize;
318 sblock.fs_old_cpg = 1;
319 sblock.fs_old_interleave = 1;
320 sblock.fs_old_trackskew = 0;
321 sblock.fs_old_cpc = 0;
322 sblock.fs_old_postblformat = FS_DYNAMICPOSTBLFMT;
323 sblock.fs_old_nrpos = 1;
324 } else {
325 sblock.fs_magic = FS_UFS2_MAGIC;
326 sblock.fs_sblockloc = SBLOCK_UFS2;
327 sblock.fs_nindir = sblock.fs_bsize / sizeof(int64_t);
328 sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs2_dinode);
329 }
330
331 sblock.fs_sblkno =
332 roundup(howmany(sblock.fs_sblockloc + SBLOCKSIZE, sblock.fs_fsize),
333 sblock.fs_frag);
334 sblock.fs_cblkno = (daddr_t)(sblock.fs_sblkno +
335 roundup(howmany(SBLOCKSIZE, sblock.fs_fsize), sblock.fs_frag));
336 sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag;
337 sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1;
338 for (sizepb = sblock.fs_bsize, i = 0; i < NIADDR; i++) {
339 sizepb *= NINDIR(&sblock);
340 sblock.fs_maxfilesize += sizepb;
341 }
342
343 /*
344 * Calculate the number of blocks to put into each cylinder group.
345 *
346 * The cylinder group size is limited because the data structure
347 * must fit into a single block.
348 * We try to have as few cylinder groups as possible, with a proviso
349 * that we create at least MINCYLGRPS (==4) except for small
350 * filesystems.
351 *
352 * This algorithm works out how many blocks of inodes would be
353 * needed to fill the entire volume at the specified density.
354 * It then looks at how big the 'cylinder block' would have to
355 * be and, assuming that it is linearly related to the number
356 * of inodes and blocks how many cylinder groups are needed to
357 * keep the cylinder block below the filesystem block size.
358 *
359 * The cylinder groups are then all created with the average size.
360 *
361 * Space taken by the red tape on cylinder groups other than the
362 * first is ignored.
363 */
364
365 /* There must be space for 1 inode block and 2 data blocks */
366 if (sblock.fs_size < sblock.fs_iblkno + 3 * sblock.fs_frag) {
367 printf("Filesystem size %lld < minimum size of %d\n",
368 (long long)sblock.fs_size, sblock.fs_iblkno + 3 * sblock.fs_frag);
369 fserr(23);
370 }
371 if (num_inodes != 0)
372 inodeblks = howmany(num_inodes, INOPB(&sblock));
373 else {
374 /*
375 * Calculate 'per inode block' so we can allocate less than
376 * 1 fragment per inode - useful for /dev.
377 */
378 fragsperinodeblk = MAX(numfrags(&sblock,
379 (uint64_t)density * INOPB(&sblock)), 1);
380 inodeblks = (sblock.fs_size - sblock.fs_iblkno) /
381 (sblock.fs_frag + fragsperinodeblk);
382 }
383 if (inodeblks == 0)
384 inodeblks = 1;
385 /* Ensure that there are at least 2 data blocks (or we fail below) */
386 if (inodeblks > (uint64_t)(sblock.fs_size - sblock.fs_iblkno)/sblock.fs_frag - 2)
387 inodeblks = (sblock.fs_size-sblock.fs_iblkno)/sblock.fs_frag-2;
388 /* Even UFS2 limits number of inodes to 2^31 (fs_ipg is int32_t) */
389 if (inodeblks * INOPB(&sblock) >= 1ull << 31)
390 inodeblks = ((1ull << 31) - NBBY) / INOPB(&sblock);
391 /*
392 * See what would happen if we tried to use 1 cylinder group.
393 * Assume space linear, so work out number of cylinder groups needed.
394 */
395 cgzero = CGSIZE_IF(&sblock, 0, 0);
396 cgall = CGSIZE_IF(&sblock, inodeblks * INOPB(&sblock), sblock.fs_size);
397 ncg = howmany(cgall - cgzero, sblock.fs_bsize - cgzero);
398 if (ncg < MINCYLGRPS) {
399 /*
400 * We would like to allocate MINCLYGRPS cylinder groups,
401 * but for small file sytems (especially ones with a lot
402 * of inodes) this is not desirable (or possible).
403 */
404 u = sblock.fs_size / 2 / (sblock.fs_iblkno +
405 inodeblks * sblock.fs_frag);
406 if (u > ncg)
407 ncg = u;
408 if (ncg > MINCYLGRPS)
409 ncg = MINCYLGRPS;
410 if (ncg > inodeblks)
411 ncg = inodeblks;
412 }
413 /*
414 * Put an equal number of blocks in each cylinder group.
415 * Round up so we don't have more fragments in the last CG than
416 * the earlier ones (does that matter?), but kill a block if the
417 * CGSIZE becomes too big (only happens if there are a lot of CGs).
418 */
419 sblock.fs_fpg = roundup(howmany(sblock.fs_size, ncg), sblock.fs_frag);
420 /* Round up the fragments/group so the bitmap bytes are full */
421 sblock.fs_fpg = roundup(sblock.fs_fpg, NBBY);
422 inodes_per_cg = ((inodeblks - 1) / ncg + 1) * INOPB(&sblock);
423
424 i = CGSIZE_IF(&sblock, inodes_per_cg, sblock.fs_fpg);
425 if (i > sblock.fs_bsize) {
426 sblock.fs_fpg -= (i - sblock.fs_bsize) * NBBY;
427 /* ... and recalculate how many cylinder groups we now need */
428 ncg = howmany(sblock.fs_size, sblock.fs_fpg);
429 inodes_per_cg = ((inodeblks - 1) / ncg + 1) * INOPB(&sblock);
430 }
431 sblock.fs_ipg = inodes_per_cg;
432 /* Sanity check on our sums... */
433 if ((int)CGSIZE(&sblock) > sblock.fs_bsize) {
434 printf("CGSIZE miscalculated %d > %d\n",
435 (int)CGSIZE(&sblock), sblock.fs_bsize);
436 fserr(24);
437 }
438
439 sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock);
440 /* Check that the last cylinder group has enough space for the inodes */
441 i = sblock.fs_size - sblock.fs_fpg * (ncg - 1ull);
442 if (i < sblock.fs_dblkno) {
443 /*
444 * Since we make all the cylinder groups the same size, the
445 * last will only be small if there are a large number of
446 * cylinder groups. If we pull even a fragment from each
447 * of the other groups then the last CG will be overfull.
448 * So we just kill the last CG.
449 */
450 ncg--;
451 sblock.fs_size -= i;
452 }
453 sblock.fs_ncg = ncg;
454
455 sblock.fs_cgsize = fragroundup(&sblock, CGSIZE(&sblock));
456 if (Oflag <= 1) {
457 sblock.fs_old_spc = sblock.fs_fpg * sblock.fs_old_nspf;
458 sblock.fs_old_nsect = sblock.fs_old_spc;
459 sblock.fs_old_npsect = sblock.fs_old_spc;
460 sblock.fs_old_ncyl = sblock.fs_ncg;
461 }
462
463 /*
464 * Cylinder group summary information for each cylinder is written
465 * into the first cylinder group.
466 * Write this fragment by fragment, but doing the first CG last
467 * (after we've taken stuff off for the structure itself and the
468 * root directory.
469 */
470 sblock.fs_csaddr = cgdmin(&sblock, 0);
471 sblock.fs_cssize =
472 fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum));
473 if (512 % sizeof *fscs_0)
474 errx(1, "cylinder group summary doesn't fit in sectors");
475 fscs_0 = mmap(0, 2 * sblock.fs_fsize, PROT_READ|PROT_WRITE,
476 MAP_ANON|MAP_PRIVATE, -1, 0);
477 if (fscs_0 == MAP_FAILED)
478 exit(39);
479 memset(fscs_0, 0, 2 * sblock.fs_fsize);
480 fs_csaddr = sblock.fs_csaddr;
481 fscs_next = fscs_0;
482 fscs_end = (void *)((char *)fscs_0 + 2 * sblock.fs_fsize);
483 fscs_reset = (void *)((char *)fscs_0 + sblock.fs_fsize);
484 /*
485 * fill in remaining fields of the super block
486 */
487 sblock.fs_sbsize = fragroundup(&sblock, sizeof(struct fs));
488 if (sblock.fs_sbsize > SBLOCKSIZE)
489 sblock.fs_sbsize = SBLOCKSIZE;
490 sblock.fs_minfree = minfree;
491 sblock.fs_maxcontig = maxcontig;
492 sblock.fs_maxbpg = maxbpg;
493 sblock.fs_optim = opt;
494 sblock.fs_cgrotor = 0;
495 sblock.fs_pendingblocks = 0;
496 sblock.fs_pendinginodes = 0;
497 sblock.fs_cstotal.cs_ndir = 0;
498 sblock.fs_cstotal.cs_nbfree = 0;
499 sblock.fs_cstotal.cs_nifree = 0;
500 sblock.fs_cstotal.cs_nffree = 0;
501 sblock.fs_fmod = 0;
502 sblock.fs_ronly = 0;
503 sblock.fs_state = 0;
504 sblock.fs_clean = FS_ISCLEAN;
505 sblock.fs_ronly = 0;
506 sblock.fs_id[0] = (long)tv.tv_sec; /* XXXfvdl huh? */
507 sblock.fs_id[1] = arc4random() & INT32_MAX;
508 sblock.fs_fsmnt[0] = '\0';
509 csfrags = howmany(sblock.fs_cssize, sblock.fs_fsize);
510 sblock.fs_dsize = sblock.fs_size - sblock.fs_sblkno -
511 sblock.fs_ncg * (sblock.fs_dblkno - sblock.fs_sblkno);
512 sblock.fs_cstotal.cs_nbfree =
513 fragstoblks(&sblock, sblock.fs_dsize) -
514 howmany(csfrags, sblock.fs_frag);
515 sblock.fs_cstotal.cs_nffree =
516 fragnum(&sblock, sblock.fs_size) +
517 (fragnum(&sblock, csfrags) > 0 ?
518 sblock.fs_frag - fragnum(&sblock, csfrags) : 0);
519 sblock.fs_cstotal.cs_nifree = sblock.fs_ncg * sblock.fs_ipg - ROOTINO;
520 sblock.fs_cstotal.cs_ndir = 0;
521 sblock.fs_dsize -= csfrags;
522 sblock.fs_time = tv.tv_sec;
523 if (Oflag <= 1) {
524 sblock.fs_old_time = tv.tv_sec;
525 sblock.fs_old_dsize = sblock.fs_dsize;
526 sblock.fs_old_csaddr = sblock.fs_csaddr;
527 sblock.fs_old_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir;
528 sblock.fs_old_cstotal.cs_nbfree = sblock.fs_cstotal.cs_nbfree;
529 sblock.fs_old_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree;
530 sblock.fs_old_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree;
531 }
532 /* add quota data in superblock */
533 if (quotas) {
534 sblock.fs_flags |= FS_DOQUOTA2;
535 sblock.fs_quota_magic = Q2_HEAD_MAGIC;
536 sblock.fs_quota_flags = quotas;
537 }
538 /*
539 * Dump out summary information about file system.
540 */
541 if (verbosity > 0) {
542 #define B2MBFACTOR (1 / (1024.0 * 1024.0))
543 printf("%s: %.1fMB (%lld sectors) block size %d, "
544 "fragment size %d\n",
545 fsys, (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR,
546 (long long)fsbtodb(&sblock, sblock.fs_size),
547 sblock.fs_bsize, sblock.fs_fsize);
548 printf("\tusing %d cylinder groups of %.2fMB, %d blks, "
549 "%d inodes.\n",
550 sblock.fs_ncg,
551 (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR,
552 sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg);
553 #undef B2MBFACTOR
554 }
555
556 /*
557 * allocate space for superblock, cylinder group map, and
558 * two sets of inode blocks.
559 */
560 if (sblock.fs_bsize < SBLOCKSIZE)
561 iobufsize = SBLOCKSIZE + 3 * sblock.fs_bsize;
562 else
563 iobufsize = 4 * sblock.fs_bsize;
564 iobuf_memsize = iobufsize;
565 if (!mfs && sblock.fs_magic == FS_UFS1_MAGIC) {
566 /* A larger buffer so we can write multiple inode blks */
567 iobuf_memsize += 14 * sblock.fs_bsize;
568 }
569 for (;;) {
570 iobuf = mmap(0, iobuf_memsize, PROT_READ|PROT_WRITE,
571 MAP_ANON|MAP_PRIVATE, -1, 0);
572 if (iobuf != MAP_FAILED)
573 break;
574 if (iobuf_memsize != iobufsize) {
575 /* Try again with the smaller size */
576 iobuf_memsize = iobufsize;
577 continue;
578 }
579 printf("Cannot allocate I/O buffer\n");
580 exit(38);
581 }
582 memset(iobuf, 0, iobuf_memsize);
583
584 /*
585 * We now start writing to the filesystem
586 */
587
588 if (!Nflag) {
589 /*
590 * Validate the given file system size.
591 * Verify that its last block can actually be accessed.
592 * Convert to file system fragment sized units.
593 */
594 if (fssize <= 0) {
595 printf("preposterous size %lld\n", (long long)fssize);
596 fserr(13);
597 }
598 wtfs(fssize - 1, sectorsize, iobuf);
599
600 /*
601 * Ensure there is nothing that looks like a filesystem
602 * superbock anywhere other than where ours will be.
603 * If fsck finds the wrong one all hell breaks loose!
604 */
605 for (i = 0; ; i++) {
606 static const int sblocklist[] = SBLOCKSEARCH;
607 int sblkoff = sblocklist[i];
608 int sz;
609 if (sblkoff == -1)
610 break;
611 /* Remove main superblock */
612 zap_old_sblock(sblkoff);
613 /* and all possible locations for the first alternate */
614 sblkoff += SBLOCKSIZE;
615 for (sz = SBLOCKSIZE; sz <= 0x10000; sz <<= 1)
616 zap_old_sblock(roundup(sblkoff, sz));
617 }
618
619 if (isappleufs) {
620 struct appleufslabel appleufs;
621 ffs_appleufs_set(&appleufs, appleufs_volname,
622 tv.tv_sec, 0);
623 wtfs(APPLEUFS_LABEL_OFFSET/sectorsize,
624 APPLEUFS_LABEL_SIZE, &appleufs);
625 } else if (APPLEUFS_LABEL_SIZE % sectorsize == 0) {
626 struct appleufslabel appleufs;
627 /* Look for & zap any existing valid apple ufs labels */
628 rdfs(APPLEUFS_LABEL_OFFSET/sectorsize,
629 APPLEUFS_LABEL_SIZE, &appleufs);
630 if (ffs_appleufs_validate(fsys, &appleufs, NULL) == 0) {
631 memset(&appleufs, 0, sizeof(appleufs));
632 wtfs(APPLEUFS_LABEL_OFFSET/sectorsize,
633 APPLEUFS_LABEL_SIZE, &appleufs);
634 }
635 }
636 }
637
638 /*
639 * Make a copy of the superblock into the buffer that we will be
640 * writing out in each cylinder group.
641 */
642 memcpy(iobuf, &sblock, sizeof sblock);
643 if (needswap)
644 ffs_sb_swap(&sblock, (struct fs *)iobuf);
645 if ((sblock.fs_old_flags & FS_FLAGS_UPDATED) == 0)
646 memset(iobuf + offsetof(struct fs, fs_old_postbl_start),
647 0xff, 256);
648
649 if (verbosity >= 3)
650 printf("super-block backups (for fsck_ffs -b #) at:\n");
651 /* If we are printing more than one line of numbers, line up columns */
652 fld_width = verbosity < 4 ? 1 : snprintf(NULL, 0, "%" PRIu64,
653 (uint64_t)fsbtodb(&sblock, cgsblock(&sblock, sblock.fs_ncg-1)));
654 /* Get terminal width */
655 if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) == 0)
656 max_cols = winsize.ws_col;
657 else
658 max_cols = 80;
659 if (Nflag && verbosity == 3)
660 /* Leave space to add " ..." after one row of numbers */
661 max_cols -= 4;
662 #define BASE 0x10000 /* For some fixed-point maths */
663 col = 0;
664 delta = verbosity > 2 ? 0 : max_cols * BASE / sblock.fs_ncg;
665 for (cylno = 0; cylno < sblock.fs_ncg; cylno++) {
666 fflush(stdout);
667 initcg(cylno, &tv);
668 if (verbosity < 2)
669 continue;
670 if (delta > 0) {
671 if (Nflag)
672 /* No point doing dots for -N */
673 break;
674 /* Print dots scaled to end near RH margin */
675 for (col += delta; col > BASE; col -= BASE)
676 printf(".");
677 continue;
678 }
679 /* Print superblock numbers */
680 len = printf(" %*" PRIu64 "," + !col, fld_width,
681 (uint64_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)));
682 col += len;
683 if (col + len < max_cols)
684 /* Next number fits */
685 continue;
686 /* Next number won't fit, need a newline */
687 if (verbosity <= 3) {
688 /* Print dots for subsequent cylinder groups */
689 delta = sblock.fs_ncg - cylno - 1;
690 if (delta != 0) {
691 if (Nflag) {
692 printf(" ...");
693 break;
694 }
695 delta = max_cols * BASE / delta;
696 }
697 }
698 col = 0;
699 printf("\n");
700 }
701 #undef BASE
702 if (col > 0)
703 printf("\n");
704 if (Nflag)
705 exit(0);
706
707 /*
708 * Now construct the initial file system,
709 */
710 if (fsinit(&tv, mfsmode, mfsuid, mfsgid) == 0 && mfs)
711 errx(1, "Error making filesystem");
712 sblock.fs_time = tv.tv_sec;
713 if (Oflag <= 1) {
714 sblock.fs_old_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir;
715 sblock.fs_old_cstotal.cs_nbfree = sblock.fs_cstotal.cs_nbfree;
716 sblock.fs_old_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree;
717 sblock.fs_old_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree;
718 }
719 /*
720 * Write out the super-block and zeros until the first cg info
721 */
722 i = cgsblock(&sblock, 0) * sblock.fs_fsize - sblock.fs_sblockloc,
723 memset(iobuf, 0, i);
724 memcpy(iobuf, &sblock, sizeof sblock);
725 if (needswap)
726 ffs_sb_swap(&sblock, (struct fs *)iobuf);
727 if ((sblock.fs_old_flags & FS_FLAGS_UPDATED) == 0)
728 memset(iobuf + offsetof(struct fs, fs_old_postbl_start),
729 0xff, 256);
730 wtfs(sblock.fs_sblockloc / sectorsize, i, iobuf);
731
732 /* Write out first and last cylinder summary sectors */
733 if (needswap)
734 ffs_csum_swap(fscs_0, fscs_0, sblock.fs_fsize);
735 wtfs(fsbtodb(&sblock, sblock.fs_csaddr), sblock.fs_fsize, fscs_0);
736
737 if (fscs_next > fscs_reset) {
738 if (needswap)
739 ffs_csum_swap(fscs_reset, fscs_reset, sblock.fs_fsize);
740 fs_csaddr++;
741 wtfs(fsbtodb(&sblock, fs_csaddr), sblock.fs_fsize, fscs_reset);
742 }
743
744 /* mfs doesn't need these permanently allocated */
745 munmap(iobuf, iobuf_memsize);
746 munmap(fscs_0, 2 * sblock.fs_fsize);
747 }
748
749 /*
750 * Initialize a cylinder group.
751 */
752 void
753 initcg(int cylno, const struct timeval *tv)
754 {
755 daddr_t cbase, dmax;
756 int32_t i, d, dlower, dupper, blkno;
757 uint32_t u;
758 struct ufs1_dinode *dp1;
759 struct ufs2_dinode *dp2;
760 int start;
761
762 /*
763 * Determine block bounds for cylinder group.
764 * Allow space for super block summary information in first
765 * cylinder group.
766 */
767 cbase = cgbase(&sblock, cylno);
768 dmax = cbase + sblock.fs_fpg;
769 if (dmax > sblock.fs_size)
770 dmax = sblock.fs_size;
771 dlower = cgsblock(&sblock, cylno) - cbase;
772 dupper = cgdmin(&sblock, cylno) - cbase;
773 if (cylno == 0) {
774 dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
775 if (dupper >= cgstart(&sblock, cylno + 1)) {
776 printf("\rToo many cylinder groups to fit summary "
777 "information into first cylinder group\n");
778 fserr(40);
779 }
780 }
781 memset(&acg, 0, sblock.fs_cgsize);
782 acg.cg_magic = CG_MAGIC;
783 acg.cg_cgx = cylno;
784 acg.cg_ndblk = dmax - cbase;
785 if (sblock.fs_contigsumsize > 0)
786 acg.cg_nclusterblks = acg.cg_ndblk >> sblock.fs_fragshift;
787 start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
788 if (Oflag == 2) {
789 acg.cg_time = tv->tv_sec;
790 acg.cg_niblk = sblock.fs_ipg;
791 acg.cg_initediblk = sblock.fs_ipg < 2 * INOPB(&sblock) ?
792 sblock.fs_ipg : 2 * INOPB(&sblock);
793 acg.cg_iusedoff = start;
794 } else {
795 acg.cg_old_ncyl = sblock.fs_old_cpg;
796 if ((sblock.fs_old_flags & FS_FLAGS_UPDATED) == 0 &&
797 (cylno == sblock.fs_ncg - 1))
798 acg.cg_old_ncyl =
799 sblock.fs_old_ncyl % sblock.fs_old_cpg;
800 acg.cg_old_time = tv->tv_sec;
801 acg.cg_old_niblk = sblock.fs_ipg;
802 acg.cg_old_btotoff = start;
803 acg.cg_old_boff = acg.cg_old_btotoff +
804 sblock.fs_old_cpg * sizeof(int32_t);
805 acg.cg_iusedoff = acg.cg_old_boff +
806 sblock.fs_old_cpg * sizeof(u_int16_t);
807 }
808 acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT);
809 if (sblock.fs_contigsumsize <= 0) {
810 acg.cg_nextfreeoff = acg.cg_freeoff +
811 howmany(sblock.fs_fpg, CHAR_BIT);
812 } else {
813 acg.cg_clustersumoff = acg.cg_freeoff +
814 howmany(sblock.fs_fpg, CHAR_BIT) - sizeof(int32_t);
815 if (isappleufs) {
816 /* Apple PR2216969 gives rationale for this change.
817 * I believe they were mistaken, but we need to
818 * duplicate it for compatibility. -- dbj (at) NetBSD.org
819 */
820 acg.cg_clustersumoff += sizeof(int32_t);
821 }
822 acg.cg_clustersumoff =
823 roundup(acg.cg_clustersumoff, sizeof(int32_t));
824 acg.cg_clusteroff = acg.cg_clustersumoff +
825 (sblock.fs_contigsumsize + 1) * sizeof(int32_t);
826 acg.cg_nextfreeoff = acg.cg_clusteroff +
827 howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
828 }
829 if (acg.cg_nextfreeoff > sblock.fs_cgsize) {
830 printf("Panic: cylinder group too big\n");
831 fserr(37);
832 }
833 acg.cg_cs.cs_nifree += sblock.fs_ipg;
834 if (cylno == 0)
835 for (u = 0; u < ROOTINO; u++) {
836 setbit(cg_inosused(&acg, 0), u);
837 acg.cg_cs.cs_nifree--;
838 }
839 if (cylno > 0) {
840 /*
841 * In cylno 0, beginning space is reserved
842 * for boot and super blocks.
843 */
844 for (d = 0, blkno = 0; d < dlower;) {
845 setblock(&sblock, cg_blksfree(&acg, 0), blkno);
846 if (sblock.fs_contigsumsize > 0)
847 setbit(cg_clustersfree(&acg, 0), blkno);
848 acg.cg_cs.cs_nbfree++;
849 if (Oflag <= 1) {
850 int cn = old_cbtocylno(&sblock, d);
851 old_cg_blktot(&acg, 0)[cn]++;
852 old_cg_blks(&sblock, &acg,
853 cn, 0)[old_cbtorpos(&sblock, d)]++;
854 }
855 d += sblock.fs_frag;
856 blkno++;
857 }
858 }
859 if ((i = (dupper & (sblock.fs_frag - 1))) != 0) {
860 acg.cg_frsum[sblock.fs_frag - i]++;
861 for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) {
862 setbit(cg_blksfree(&acg, 0), dupper);
863 acg.cg_cs.cs_nffree++;
864 }
865 }
866 for (d = dupper, blkno = dupper >> sblock.fs_fragshift;
867 d + sblock.fs_frag <= acg.cg_ndblk; ) {
868 setblock(&sblock, cg_blksfree(&acg, 0), blkno);
869 if (sblock.fs_contigsumsize > 0)
870 setbit(cg_clustersfree(&acg, 0), blkno);
871 acg.cg_cs.cs_nbfree++;
872 if (Oflag <= 1) {
873 int cn = old_cbtocylno(&sblock, d);
874 old_cg_blktot(&acg, 0)[cn]++;
875 old_cg_blks(&sblock, &acg,
876 cn, 0)[old_cbtorpos(&sblock, d)]++;
877 }
878 d += sblock.fs_frag;
879 blkno++;
880 }
881 if (d < acg.cg_ndblk) {
882 acg.cg_frsum[acg.cg_ndblk - d]++;
883 for (; d < acg.cg_ndblk; d++) {
884 setbit(cg_blksfree(&acg, 0), d);
885 acg.cg_cs.cs_nffree++;
886 }
887 }
888 if (sblock.fs_contigsumsize > 0) {
889 int32_t *sump = cg_clustersum(&acg, 0);
890 u_char *mapp = cg_clustersfree(&acg, 0);
891 int map = *mapp++;
892 int bit = 1;
893 int run = 0;
894
895 for (i = 0; i < acg.cg_nclusterblks; i++) {
896 if ((map & bit) != 0) {
897 run++;
898 } else if (run != 0) {
899 if (run > sblock.fs_contigsumsize)
900 run = sblock.fs_contigsumsize;
901 sump[run]++;
902 run = 0;
903 }
904 if ((i & (CHAR_BIT - 1)) != (CHAR_BIT - 1)) {
905 bit <<= 1;
906 } else {
907 map = *mapp++;
908 bit = 1;
909 }
910 }
911 if (run != 0) {
912 if (run > sblock.fs_contigsumsize)
913 run = sblock.fs_contigsumsize;
914 sump[run]++;
915 }
916 }
917 *fscs_next++ = acg.cg_cs;
918 if (fscs_next == fscs_end) {
919 /* write block of cylinder group summary info into cyl 0 */
920 if (needswap)
921 ffs_csum_swap(fscs_reset, fscs_reset, sblock.fs_fsize);
922 fs_csaddr++;
923 wtfs(fsbtodb(&sblock, fs_csaddr), sblock.fs_fsize, fscs_reset);
924 fscs_next = fscs_reset;
925 memset(fscs_next, 0, sblock.fs_fsize);
926 }
927 /*
928 * Write out the duplicate super block, the cylinder group map
929 * and two blocks worth of inodes in a single write.
930 */
931 start = sblock.fs_bsize > SBLOCKSIZE ? sblock.fs_bsize : SBLOCKSIZE;
932 memcpy(&iobuf[start], &acg, sblock.fs_cgsize);
933 if (needswap)
934 ffs_cg_swap(&acg, (struct cg*)&iobuf[start], &sblock);
935 start += sblock.fs_bsize;
936 dp1 = (struct ufs1_dinode *)(&iobuf[start]);
937 dp2 = (struct ufs2_dinode *)(&iobuf[start]);
938 for (i = MIN(sblock.fs_ipg, 2) * INOPB(&sblock); i != 0; i--) {
939 if (sblock.fs_magic == FS_UFS1_MAGIC) {
940 /* No need to swap, it'll stay random */
941 dp1->di_gen = arc4random() & INT32_MAX;
942 dp1++;
943 } else {
944 dp2->di_gen = arc4random() & INT32_MAX;
945 dp2++;
946 }
947 }
948 wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), iobufsize, iobuf);
949 /*
950 * For the old file system, we have to initialize all the inodes.
951 */
952 if (sblock.fs_magic != FS_UFS1_MAGIC)
953 return;
954
955 /* Write 'd' (usually 16 * fs_frag) file-system fragments at once */
956 d = (iobuf_memsize - start) / sblock.fs_bsize * sblock.fs_frag;
957 dupper = sblock.fs_ipg / INOPF(&sblock);
958 for (i = 2 * sblock.fs_frag; i < dupper; i += d) {
959 if (d > dupper - i)
960 d = dupper - i;
961 dp1 = (struct ufs1_dinode *)(&iobuf[start]);
962 do
963 dp1->di_gen = arc4random() & INT32_MAX;
964 while ((char *)++dp1 < &iobuf[iobuf_memsize]);
965 wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i),
966 d * sblock.fs_bsize / sblock.fs_frag, &iobuf[start]);
967 }
968 }
969
970 /*
971 * initialize the file system
972 */
973
974 #ifdef LOSTDIR
975 #define PREDEFDIR 3
976 #else
977 #define PREDEFDIR 2
978 #endif
979
980 struct direct root_dir[] = {
981 { ROOTINO, sizeof(struct direct), DT_DIR, 1, "." },
982 { ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." },
983 #ifdef LOSTDIR
984 { LOSTFOUNDINO, sizeof(struct direct), DT_DIR, 10, "lost+found" },
985 #endif
986 };
987 struct odirect {
988 u_int32_t d_ino;
989 u_int16_t d_reclen;
990 u_int16_t d_namlen;
991 u_char d_name[FFS_MAXNAMLEN + 1];
992 } oroot_dir[] = {
993 { ROOTINO, sizeof(struct direct), 1, "." },
994 { ROOTINO, sizeof(struct direct), 2, ".." },
995 #ifdef LOSTDIR
996 { LOSTFOUNDINO, sizeof(struct direct), 10, "lost+found" },
997 #endif
998 };
999 #ifdef LOSTDIR
1000 struct direct lost_found_dir[] = {
1001 { LOSTFOUNDINO, sizeof(struct direct), DT_DIR, 1, "." },
1002 { ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." },
1003 { 0, DIRBLKSIZ, 0, 0, 0 },
1004 };
1005 struct odirect olost_found_dir[] = {
1006 { LOSTFOUNDINO, sizeof(struct direct), 1, "." },
1007 { ROOTINO, sizeof(struct direct), 2, ".." },
1008 { 0, DIRBLKSIZ, 0, 0 },
1009 };
1010 #endif
1011 char buf[MAXBSIZE];
1012 static void copy_dir(struct direct *, struct direct *);
1013
1014 int
1015 fsinit(const struct timeval *tv, mode_t mfsmode, uid_t mfsuid, gid_t mfsgid)
1016 {
1017 union dinode node;
1018 int i;
1019 int qblocks = 0;
1020 int qinos = 0;
1021 uint8_t q2h_hash_shift;
1022 uint16_t q2h_hash_mask;
1023 #ifdef LOSTDIR
1024 int dirblksiz = DIRBLKSIZ;
1025 if (isappleufs)
1026 dirblksiz = APPLEUFS_DIRBLKSIZ;
1027 int nextino = LOSTFOUNDINO+1;
1028 #else
1029 int nextino = ROOTINO+1;
1030 #endif
1031
1032 /*
1033 * initialize the node
1034 */
1035
1036 #ifdef LOSTDIR
1037 /*
1038 * create the lost+found directory
1039 */
1040 memset(&node, 0, sizeof(node));
1041 if (Oflag == 0) {
1042 (void)makedir((struct direct *)olost_found_dir, 2);
1043 for (i = dirblksiz; i < sblock.fs_bsize; i += dirblksiz)
1044 copy_dir((struct direct*)&olost_found_dir[2],
1045 (struct direct*)&buf[i]);
1046 } else {
1047 (void)makedir(lost_found_dir, 2);
1048 for (i = dirblksiz; i < sblock.fs_bsize; i += dirblksiz)
1049 copy_dir(&lost_found_dir[2], (struct direct*)&buf[i]);
1050 }
1051 if (sblock.fs_magic == FS_UFS1_MAGIC) {
1052 node.dp1.di_atime = tv->tv_sec;
1053 node.dp1.di_atimensec = tv->tv_usec * 1000;
1054 node.dp1.di_mtime = tv->tv_sec;
1055 node.dp1.di_mtimensec = tv->tv_usec * 1000;
1056 node.dp1.di_ctime = tv->tv_sec;
1057 node.dp1.di_ctimensec = tv->tv_usec * 1000;
1058 node.dp1.di_mode = IFDIR | UMASK;
1059 node.dp1.di_nlink = 2;
1060 node.dp1.di_size = sblock.fs_bsize;
1061 node.dp1.di_db[0] = alloc(node.dp1.di_size, node.dp1.di_mode);
1062 if (node.dp1.di_db[0] == 0)
1063 return (0);
1064 node.dp1.di_blocks = btodb(fragroundup(&sblock,
1065 node.dp1.di_size));
1066 qblocks += node.dp1.di_blocks;
1067 node.dp1.di_uid = geteuid();
1068 node.dp1.di_gid = getegid();
1069 wtfs(fsbtodb(&sblock, node.dp1.di_db[0]), node.dp1.di_size,
1070 buf);
1071 } else {
1072 node.dp2.di_atime = tv->tv_sec;
1073 node.dp2.di_atimensec = tv->tv_usec * 1000;
1074 node.dp2.di_mtime = tv->tv_sec;
1075 node.dp2.di_mtimensec = tv->tv_usec * 1000;
1076 node.dp2.di_ctime = tv->tv_sec;
1077 node.dp2.di_ctimensec = tv->tv_usec * 1000;
1078 node.dp2.di_birthtime = tv->tv_sec;
1079 node.dp2.di_birthnsec = tv->tv_usec * 1000;
1080 node.dp2.di_mode = IFDIR | UMASK;
1081 node.dp2.di_nlink = 2;
1082 node.dp2.di_size = sblock.fs_bsize;
1083 node.dp2.di_db[0] = alloc(node.dp2.di_size, node.dp2.di_mode);
1084 if (node.dp2.di_db[0] == 0)
1085 return (0);
1086 node.dp2.di_blocks = btodb(fragroundup(&sblock,
1087 node.dp2.di_size));
1088 qblocks += node.dp2.di_blocks;
1089 node.dp2.di_uid = geteuid();
1090 node.dp2.di_gid = getegid();
1091 wtfs(fsbtodb(&sblock, node.dp2.di_db[0]), node.dp2.di_size,
1092 buf);
1093 }
1094 qinos++;
1095 iput(&node, LOSTFOUNDINO);
1096 #endif
1097 /*
1098 * create the root directory
1099 */
1100 memset(&node, 0, sizeof(node));
1101 if (Oflag <= 1) {
1102 if (mfs) {
1103 node.dp1.di_mode = IFDIR | mfsmode;
1104 node.dp1.di_uid = mfsuid;
1105 node.dp1.di_gid = mfsgid;
1106 } else {
1107 node.dp1.di_mode = IFDIR | UMASK;
1108 node.dp1.di_uid = geteuid();
1109 node.dp1.di_gid = getegid();
1110 }
1111 node.dp1.di_nlink = PREDEFDIR;
1112 if (Oflag == 0)
1113 node.dp1.di_size = makedir((struct direct *)oroot_dir,
1114 PREDEFDIR);
1115 else
1116 node.dp1.di_size = makedir(root_dir, PREDEFDIR);
1117 node.dp1.di_db[0] = alloc(sblock.fs_fsize, node.dp1.di_mode);
1118 if (node.dp1.di_db[0] == 0)
1119 return (0);
1120 node.dp1.di_blocks = btodb(fragroundup(&sblock,
1121 node.dp1.di_size));
1122 qblocks += node.dp1.di_blocks;
1123 wtfs(fsbtodb(&sblock, node.dp1.di_db[0]), sblock.fs_fsize, buf);
1124 } else {
1125 if (mfs) {
1126 node.dp2.di_mode = IFDIR | mfsmode;
1127 node.dp2.di_uid = mfsuid;
1128 node.dp2.di_gid = mfsgid;
1129 } else {
1130 node.dp2.di_mode = IFDIR | UMASK;
1131 node.dp2.di_uid = geteuid();
1132 node.dp2.di_gid = getegid();
1133 }
1134 node.dp2.di_atime = tv->tv_sec;
1135 node.dp2.di_atimensec = tv->tv_usec * 1000;
1136 node.dp2.di_mtime = tv->tv_sec;
1137 node.dp2.di_mtimensec = tv->tv_usec * 1000;
1138 node.dp2.di_ctime = tv->tv_sec;
1139 node.dp2.di_ctimensec = tv->tv_usec * 1000;
1140 node.dp2.di_birthtime = tv->tv_sec;
1141 node.dp2.di_birthnsec = tv->tv_usec * 1000;
1142 node.dp2.di_nlink = PREDEFDIR;
1143 node.dp2.di_size = makedir(root_dir, PREDEFDIR);
1144 node.dp2.di_db[0] = alloc(sblock.fs_fsize, node.dp2.di_mode);
1145 if (node.dp2.di_db[0] == 0)
1146 return (0);
1147 node.dp2.di_blocks = btodb(fragroundup(&sblock,
1148 node.dp2.di_size));
1149 qblocks += node.dp2.di_blocks;
1150 wtfs(fsbtodb(&sblock, node.dp2.di_db[0]), sblock.fs_fsize, buf);
1151 }
1152 qinos++;
1153 iput(&node, ROOTINO);
1154 /*
1155 * compute the size of the hash table
1156 * We know the smallest block size is 4k, so we can use 2k
1157 * for the hash table; as an entry is 8 bytes we can store
1158 * 256 entries. So let start q2h_hash_shift at 8
1159 */
1160 for (q2h_hash_shift = 8;
1161 q2h_hash_shift < 15;
1162 q2h_hash_shift++) {
1163 if ((sizeof(uint64_t) << (q2h_hash_shift + 1)) +
1164 sizeof(struct quota2_header) > (u_int)sblock.fs_bsize)
1165 break;
1166 }
1167 q2h_hash_mask = (1 << q2h_hash_shift) - 1;
1168 for (i = 0; i < MAXQUOTAS; i++) {
1169 struct quota2_header *q2h;
1170 struct quota2_entry *q2e;
1171 uint64_t offset;
1172 uid_t uid = (i == USRQUOTA ? geteuid() : getegid());
1173
1174 if ((quotas & FS_Q2_DO_TYPE(i)) == 0)
1175 continue;
1176 quota2_create_blk0(sblock.fs_bsize, buf, q2h_hash_shift,
1177 i, needswap);
1178 /* grab an entry from header for root dir */
1179 q2h = (void *)buf;
1180 offset = ufs_rw64(q2h->q2h_free, needswap);
1181 q2e = (void *)((char *)buf + offset);
1182 q2h->q2h_free = q2e->q2e_next;
1183 memcpy(q2e, &q2h->q2h_defentry, sizeof(*q2e));
1184 q2e->q2e_uid = ufs_rw32(uid, needswap);
1185 q2e->q2e_val[QL_BLOCK].q2v_cur = ufs_rw64(qblocks, needswap);
1186 q2e->q2e_val[QL_FILE].q2v_cur = ufs_rw64(qinos, needswap);
1187 /* add to the hash entry */
1188 q2e->q2e_next = q2h->q2h_entries[uid & q2h_hash_mask];
1189 q2h->q2h_entries[uid & q2h_hash_mask] =
1190 ufs_rw64(offset, needswap);
1191
1192 memset(&node, 0, sizeof(node));
1193 if (sblock.fs_magic == FS_UFS1_MAGIC) {
1194 node.dp1.di_atime = tv->tv_sec;
1195 node.dp1.di_atimensec = tv->tv_usec * 1000;
1196 node.dp1.di_mtime = tv->tv_sec;
1197 node.dp1.di_mtimensec = tv->tv_usec * 1000;
1198 node.dp1.di_ctime = tv->tv_sec;
1199 node.dp1.di_ctimensec = tv->tv_usec * 1000;
1200 node.dp1.di_mode = IFREG;
1201 node.dp1.di_nlink = 1;
1202 node.dp1.di_size = sblock.fs_bsize;
1203 node.dp1.di_db[0] =
1204 alloc(node.dp1.di_size, node.dp1.di_mode);
1205 if (node.dp1.di_db[0] == 0)
1206 return (0);
1207 node.dp1.di_blocks = btodb(fragroundup(&sblock,
1208 node.dp1.di_size));
1209 node.dp1.di_uid = geteuid();
1210 node.dp1.di_gid = getegid();
1211 wtfs(fsbtodb(&sblock, node.dp1.di_db[0]),
1212 node.dp1.di_size, buf);
1213 } else {
1214 node.dp2.di_atime = tv->tv_sec;
1215 node.dp2.di_atimensec = tv->tv_usec * 1000;
1216 node.dp2.di_mtime = tv->tv_sec;
1217 node.dp2.di_mtimensec = tv->tv_usec * 1000;
1218 node.dp2.di_ctime = tv->tv_sec;
1219 node.dp2.di_ctimensec = tv->tv_usec * 1000;
1220 node.dp2.di_birthtime = tv->tv_sec;
1221 node.dp2.di_birthnsec = tv->tv_usec * 1000;
1222 node.dp2.di_mode = IFREG;
1223 node.dp2.di_nlink = 1;
1224 node.dp2.di_size = sblock.fs_bsize;
1225 node.dp2.di_db[0] =
1226 alloc(node.dp2.di_size, node.dp2.di_mode);
1227 if (node.dp2.di_db[0] == 0)
1228 return (0);
1229 node.dp2.di_blocks = btodb(fragroundup(&sblock,
1230 node.dp2.di_size));
1231 node.dp2.di_uid = geteuid();
1232 node.dp2.di_gid = getegid();
1233 wtfs(fsbtodb(&sblock, node.dp2.di_db[0]),
1234 node.dp2.di_size, buf);
1235 }
1236 iput(&node, nextino);
1237 sblock.fs_quotafile[i] = nextino;
1238 nextino++;
1239 }
1240 return (1);
1241 }
1242
1243 /*
1244 * construct a set of directory entries in "buf".
1245 * return size of directory.
1246 */
1247 int
1248 makedir(struct direct *protodir, int entries)
1249 {
1250 char *cp;
1251 int i, spcleft;
1252 int dirblksiz = DIRBLKSIZ;
1253 if (isappleufs)
1254 dirblksiz = APPLEUFS_DIRBLKSIZ;
1255
1256 memset(buf, 0, DIRBLKSIZ);
1257 spcleft = dirblksiz;
1258 for (cp = buf, i = 0; i < entries - 1; i++) {
1259 protodir[i].d_reclen = DIRSIZ(Oflag == 0, &protodir[i], 0);
1260 copy_dir(&protodir[i], (struct direct*)cp);
1261 cp += protodir[i].d_reclen;
1262 spcleft -= protodir[i].d_reclen;
1263 }
1264 protodir[i].d_reclen = spcleft;
1265 copy_dir(&protodir[i], (struct direct*)cp);
1266 return (dirblksiz);
1267 }
1268
1269 /*
1270 * allocate a block or frag
1271 */
1272 daddr_t
1273 alloc(int size, int mode)
1274 {
1275 int i, frag;
1276 daddr_t d, blkno;
1277
1278 rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, &acg);
1279 /* fs -> host byte order */
1280 if (needswap)
1281 ffs_cg_swap(&acg, &acg, &sblock);
1282 if (acg.cg_magic != CG_MAGIC) {
1283 printf("cg 0: bad magic number\n");
1284 return (0);
1285 }
1286 if (acg.cg_cs.cs_nbfree == 0) {
1287 printf("first cylinder group ran out of space\n");
1288 return (0);
1289 }
1290 for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag)
1291 if (isblock(&sblock, cg_blksfree(&acg, 0),
1292 d >> sblock.fs_fragshift))
1293 goto goth;
1294 printf("internal error: can't find block in cyl 0\n");
1295 return (0);
1296 goth:
1297 blkno = fragstoblks(&sblock, d);
1298 clrblock(&sblock, cg_blksfree(&acg, 0), blkno);
1299 if (sblock.fs_contigsumsize > 0)
1300 clrbit(cg_clustersfree(&acg, 0), blkno);
1301 acg.cg_cs.cs_nbfree--;
1302 sblock.fs_cstotal.cs_nbfree--;
1303 fscs_0->cs_nbfree--;
1304 if (mode & IFDIR) {
1305 acg.cg_cs.cs_ndir++;
1306 sblock.fs_cstotal.cs_ndir++;
1307 fscs_0->cs_ndir++;
1308 }
1309 if (Oflag <= 1) {
1310 int cn = old_cbtocylno(&sblock, d);
1311 old_cg_blktot(&acg, 0)[cn]--;
1312 old_cg_blks(&sblock, &acg,
1313 cn, 0)[old_cbtorpos(&sblock, d)]--;
1314 }
1315 if (size != sblock.fs_bsize) {
1316 frag = howmany(size, sblock.fs_fsize);
1317 fscs_0->cs_nffree += sblock.fs_frag - frag;
1318 sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag;
1319 acg.cg_cs.cs_nffree += sblock.fs_frag - frag;
1320 acg.cg_frsum[sblock.fs_frag - frag]++;
1321 for (i = frag; i < sblock.fs_frag; i++)
1322 setbit(cg_blksfree(&acg, 0), d + i);
1323 }
1324 /* host -> fs byte order */
1325 if (needswap)
1326 ffs_cg_swap(&acg, &acg, &sblock);
1327 wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, &acg);
1328 return (d);
1329 }
1330
1331 /*
1332 * Allocate an inode on the disk
1333 */
1334 static void
1335 iput(union dinode *ip, ino_t ino)
1336 {
1337 daddr_t d;
1338 int c, i;
1339 struct ufs1_dinode *dp1;
1340 struct ufs2_dinode *dp2;
1341
1342 c = ino_to_cg(&sblock, ino);
1343 rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, &acg);
1344 /* fs -> host byte order */
1345 if (needswap)
1346 ffs_cg_swap(&acg, &acg, &sblock);
1347 if (acg.cg_magic != CG_MAGIC) {
1348 printf("cg 0: bad magic number\n");
1349 fserr(31);
1350 }
1351 acg.cg_cs.cs_nifree--;
1352 setbit(cg_inosused(&acg, 0), ino);
1353 /* host -> fs byte order */
1354 if (needswap)
1355 ffs_cg_swap(&acg, &acg, &sblock);
1356 wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, &acg);
1357 sblock.fs_cstotal.cs_nifree--;
1358 fscs_0->cs_nifree--;
1359 if (ino >= (ino_t)(sblock.fs_ipg * sblock.fs_ncg)) {
1360 printf("fsinit: inode value out of range (%llu).\n",
1361 (unsigned long long)ino);
1362 fserr(32);
1363 }
1364 d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino));
1365 rdfs(d, sblock.fs_bsize, (char *)iobuf);
1366 if (sblock.fs_magic == FS_UFS1_MAGIC) {
1367 dp1 = (struct ufs1_dinode *)iobuf;
1368 dp1 += ino_to_fsbo(&sblock, ino);
1369 if (needswap) {
1370 ffs_dinode1_swap(&ip->dp1, dp1);
1371 /* ffs_dinode1_swap() doesn't swap blocks addrs */
1372 for (i=0; i<NDADDR + NIADDR; i++)
1373 dp1->di_db[i] = bswap32(ip->dp1.di_db[i]);
1374 } else
1375 *dp1 = ip->dp1;
1376 dp1->di_gen = arc4random() & INT32_MAX;
1377 } else {
1378 dp2 = (struct ufs2_dinode *)iobuf;
1379 dp2 += ino_to_fsbo(&sblock, ino);
1380 if (needswap) {
1381 ffs_dinode2_swap(&ip->dp2, dp2);
1382 for (i=0; i<NDADDR + NIADDR; i++)
1383 dp2->di_db[i] = bswap64(ip->dp2.di_db[i]);
1384 } else
1385 *dp2 = ip->dp2;
1386 dp2->di_gen = arc4random() & INT32_MAX;
1387 }
1388 wtfs(d, sblock.fs_bsize, iobuf);
1389 }
1390
1391 /*
1392 * read a block from the file system
1393 */
1394 void
1395 rdfs(daddr_t bno, int size, void *bf)
1396 {
1397 int n;
1398 off_t offset;
1399
1400 #ifdef MFS
1401 if (mfs) {
1402 if (Nflag)
1403 memset(bf, 0, size);
1404 else
1405 memmove(bf, membase + bno * sectorsize, size);
1406 return;
1407 }
1408 #endif
1409 offset = bno;
1410 n = pread(fsi, bf, size, offset * sectorsize);
1411 if (n != size) {
1412 printf("rdfs: read error for sector %lld: %s\n",
1413 (long long)bno, strerror(errno));
1414 exit(34);
1415 }
1416 }
1417
1418 /*
1419 * write a block to the file system
1420 */
1421 void
1422 wtfs(daddr_t bno, int size, void *bf)
1423 {
1424 int n;
1425 off_t offset;
1426
1427 if (Nflag)
1428 return;
1429 #ifdef MFS
1430 if (mfs) {
1431 memmove(membase + bno * sectorsize, bf, size);
1432 return;
1433 }
1434 #endif
1435 offset = bno;
1436 n = pwrite(fso, bf, size, offset * sectorsize);
1437 if (n != size) {
1438 printf("wtfs: write error for sector %lld: %s\n",
1439 (long long)bno, strerror(errno));
1440 exit(36);
1441 }
1442 }
1443
1444 /*
1445 * check if a block is available
1446 */
1447 int
1448 isblock(struct fs *fs, unsigned char *cp, int h)
1449 {
1450 unsigned char mask;
1451
1452 switch (fs->fs_fragshift) {
1453 case 3:
1454 return (cp[h] == 0xff);
1455 case 2:
1456 mask = 0x0f << ((h & 0x1) << 2);
1457 return ((cp[h >> 1] & mask) == mask);
1458 case 1:
1459 mask = 0x03 << ((h & 0x3) << 1);
1460 return ((cp[h >> 2] & mask) == mask);
1461 case 0:
1462 mask = 0x01 << (h & 0x7);
1463 return ((cp[h >> 3] & mask) == mask);
1464 default:
1465 #ifdef STANDALONE
1466 printf("isblock bad fs_fragshift %d\n", fs->fs_fragshift);
1467 #else
1468 fprintf(stderr, "isblock bad fs_fragshift %d\n",
1469 fs->fs_fragshift);
1470 #endif
1471 return (0);
1472 }
1473 }
1474
1475 /*
1476 * take a block out of the map
1477 */
1478 void
1479 clrblock(struct fs *fs, unsigned char *cp, int h)
1480 {
1481 switch ((fs)->fs_fragshift) {
1482 case 3:
1483 cp[h] = 0;
1484 return;
1485 case 2:
1486 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
1487 return;
1488 case 1:
1489 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
1490 return;
1491 case 0:
1492 cp[h >> 3] &= ~(0x01 << (h & 0x7));
1493 return;
1494 default:
1495 #ifdef STANDALONE
1496 printf("clrblock bad fs_fragshift %d\n", fs->fs_fragshift);
1497 #else
1498 fprintf(stderr, "clrblock bad fs_fragshift %d\n",
1499 fs->fs_fragshift);
1500 #endif
1501 return;
1502 }
1503 }
1504
1505 /*
1506 * put a block into the map
1507 */
1508 void
1509 setblock(struct fs *fs, unsigned char *cp, int h)
1510 {
1511 switch (fs->fs_fragshift) {
1512 case 3:
1513 cp[h] = 0xff;
1514 return;
1515 case 2:
1516 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
1517 return;
1518 case 1:
1519 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
1520 return;
1521 case 0:
1522 cp[h >> 3] |= (0x01 << (h & 0x7));
1523 return;
1524 default:
1525 #ifdef STANDALONE
1526 printf("setblock bad fs_frag %d\n", fs->fs_fragshift);
1527 #else
1528 fprintf(stderr, "setblock bad fs_fragshift %d\n",
1529 fs->fs_fragshift);
1530 #endif
1531 return;
1532 }
1533 }
1534
1535 /* copy a direntry to a buffer, in fs byte order */
1536 static void
1537 copy_dir(struct direct *dir, struct direct *dbuf)
1538 {
1539 memcpy(dbuf, dir, DIRSIZ(Oflag == 0, dir, 0));
1540 if (needswap) {
1541 dbuf->d_ino = bswap32(dir->d_ino);
1542 dbuf->d_reclen = bswap16(dir->d_reclen);
1543 if (Oflag == 0)
1544 ((struct odirect*)dbuf)->d_namlen =
1545 bswap16(((struct odirect*)dir)->d_namlen);
1546 }
1547 }
1548
1549 static int
1550 ilog2(int val)
1551 {
1552 u_int n;
1553
1554 for (n = 0; n < sizeof(n) * CHAR_BIT; n++)
1555 if (1 << n == val)
1556 return (n);
1557 errx(1, "ilog2: %d is not a power of 2\n", val);
1558 }
1559
1560 static void
1561 zap_old_sblock(int sblkoff)
1562 {
1563 static int cg0_data;
1564 uint32_t oldfs[SBLOCKSIZE / 4];
1565 static const struct fsm {
1566 uint32_t offset;
1567 uint32_t magic;
1568 uint32_t mask;
1569 } fs_magics[] = {
1570 {offsetof(struct fs, fs_magic)/4, FS_UFS1_MAGIC, ~0u},
1571 {offsetof(struct fs, fs_magic)/4, FS_UFS2_MAGIC, ~0u},
1572 {0, 0x70162, ~0u}, /* LFS_MAGIC */
1573 {14, 0xef53, 0xffff}, /* EXT2FS (little) */
1574 {14, 0xef530000, 0xffff0000}, /* EXT2FS (big) */
1575 {.offset = ~0u},
1576 };
1577 const struct fsm *fsm;
1578
1579 if (Nflag)
1580 return;
1581
1582 if (sblkoff == 0) /* Why did UFS2 add support for this? sigh. */
1583 return;
1584
1585 if (cg0_data == 0)
1586 /* For FFSv1 this could include all the inodes. */
1587 cg0_data = cgsblock(&sblock, 0) * sblock.fs_fsize + iobufsize;
1588
1589 /* Ignore anything that is beyond our filesystem */
1590 if ((sblkoff + SBLOCKSIZE)/sectorsize >= fssize)
1591 return;
1592 /* Zero anything inside our filesystem... */
1593 if (sblkoff >= sblock.fs_sblockloc) {
1594 /* ...unless we will write that area anyway */
1595 if (sblkoff >= cg0_data)
1596 wtfs(sblkoff / sectorsize,
1597 roundup(sizeof sblock, sectorsize), iobuf);
1598 return;
1599 }
1600
1601 /* The sector might contain boot code, so we must validate it */
1602 rdfs(sblkoff/sectorsize, sizeof oldfs, &oldfs);
1603 for (fsm = fs_magics; ; fsm++) {
1604 uint32_t v;
1605 if (fsm->mask == 0)
1606 return;
1607 v = oldfs[fsm->offset];
1608 if ((v & fsm->mask) == fsm->magic ||
1609 (bswap32(v) & fsm->mask) == fsm->magic)
1610 break;
1611 }
1612
1613 /* Just zap the magic number */
1614 oldfs[fsm->offset] = 0;
1615 wtfs(sblkoff/sectorsize, sizeof oldfs, &oldfs);
1616 }
1617
1618
1619 #ifdef MFS
1620 /*
1621 * XXX!
1622 * Attempt to guess how much more space is available for process data. The
1623 * heuristic we use is
1624 *
1625 * max_data_limit - (sbrk(0) - etext) - 128kB
1626 *
1627 * etext approximates that start address of the data segment, and the 128kB
1628 * allows some slop for both segment gap between text and data, and for other
1629 * (libc) malloc usage.
1630 */
1631 static void
1632 calc_memfree(void)
1633 {
1634 extern char etext;
1635 struct rlimit rlp;
1636 u_long base;
1637
1638 base = (u_long)sbrk(0) - (u_long)&etext;
1639 if (getrlimit(RLIMIT_DATA, &rlp) < 0)
1640 perror("getrlimit");
1641 rlp.rlim_cur = rlp.rlim_max;
1642 if (setrlimit(RLIMIT_DATA, &rlp) < 0)
1643 perror("setrlimit");
1644 memleft = rlp.rlim_max - base - (128 * 1024);
1645 }
1646
1647 /*
1648 * Internal version of malloc that trims the requested size if not enough
1649 * memory is available.
1650 */
1651 static void *
1652 mkfs_malloc(size_t size)
1653 {
1654 u_long pgsz;
1655 caddr_t *memory;
1656
1657 if (size == 0)
1658 return (NULL);
1659 if (memleft == 0)
1660 calc_memfree();
1661
1662 pgsz = getpagesize() - 1;
1663 size = (size + pgsz) &~ pgsz;
1664 if (size > memleft)
1665 size = memleft;
1666 memleft -= size;
1667 memory = mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
1668 -1, 0);
1669 return memory != MAP_FAILED ? memory : NULL;
1670 }
1671 #endif /* MFS */
1672