File: | src/sbin/newfs/mkfs.c |
Warning: | line 762, column 25 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: mkfs.c,v 1.101 2020/06/20 07:49:04 otto Exp $ */ | |||
2 | /* $NetBSD: mkfs.c,v 1.25 1995/06/18 21:35:38 cgd Exp $ */ | |||
3 | ||||
4 | /* | |||
5 | * Copyright (c) 2002 Networks Associates Technology, Inc. | |||
6 | * All rights reserved. | |||
7 | * | |||
8 | * This software was developed for the FreeBSD Project by Marshall | |||
9 | * Kirk McKusick and Network Associates Laboratories, the Security | |||
10 | * Research Division of Network Associates, Inc. under DARPA/SPAWAR | |||
11 | * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS | |||
12 | * research program. | |||
13 | * | |||
14 | * Copyright (c) 1980, 1989, 1993 | |||
15 | * The Regents of the University of California. All rights reserved. | |||
16 | * | |||
17 | * Redistribution and use in source and binary forms, with or without | |||
18 | * modification, are permitted provided that the following conditions | |||
19 | * are met: | |||
20 | * 1. Redistributions of source code must retain the above copyright | |||
21 | * notice, this list of conditions and the following disclaimer. | |||
22 | * 2. Redistributions in binary form must reproduce the above copyright | |||
23 | * notice, this list of conditions and the following disclaimer in the | |||
24 | * documentation and/or other materials provided with the distribution. | |||
25 | * 3. Neither the name of the University nor the names of its contributors | |||
26 | * may be used to endorse or promote products derived from this software | |||
27 | * without specific prior written permission. | |||
28 | * | |||
29 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||
30 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
31 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
32 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||
33 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
37 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
38 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
39 | * SUCH DAMAGE. | |||
40 | */ | |||
41 | ||||
42 | #include <sys/param.h> /* MAXBSIZE DEV_BSIZE roundup btodb setbit */ | |||
43 | #include <sys/signal.h> | |||
44 | #include <sys/time.h> | |||
45 | #include <sys/disklabel.h> | |||
46 | #include <sys/ioctl.h> | |||
47 | #include <sys/mman.h> | |||
48 | #include <sys/resource.h> | |||
49 | #include <sys/sysctl.h> | |||
50 | ||||
51 | #include <ufs/ufs/dinode.h> | |||
52 | #include <ufs/ufs/dir.h> | |||
53 | #include <ufs/ffs/fs.h> | |||
54 | ||||
55 | #include <err.h> | |||
56 | #include <string.h> | |||
57 | #include <stdlib.h> | |||
58 | #include <stdint.h> | |||
59 | #include <unistd.h> | |||
60 | #include <limits.h> | |||
61 | ||||
62 | #ifndef STANDALONE | |||
63 | #include <stdio.h> | |||
64 | #include <errno(*__errno()).h> | |||
65 | #endif | |||
66 | ||||
67 | #define MINIMUM(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b)) | |||
68 | #define MAXIMUM(a, b)(((a) > (b)) ? (a) : (b)) (((a) > (b)) ? (a) : (b)) | |||
69 | ||||
70 | /* | |||
71 | * Default directory umask. | |||
72 | */ | |||
73 | #define UMASK0755 0755 | |||
74 | ||||
75 | #define POWEROF2(num)(((num) & ((num) - 1)) == 0) (((num) & ((num) - 1)) == 0) | |||
76 | ||||
77 | /* | |||
78 | * 'Standard' bad FFS magic. | |||
79 | */ | |||
80 | #define FS_BAD_MAGIC0x19960408 0x19960408 | |||
81 | ||||
82 | /* | |||
83 | * The minimum number of cylinder groups that should be created. | |||
84 | */ | |||
85 | #define MINCYLGRPS4 4 | |||
86 | ||||
87 | /* | |||
88 | * variables set up by front end. | |||
89 | */ | |||
90 | extern int mfs; /* run as the memory based filesystem */ | |||
91 | extern int Nflag; /* run mkfs without writing file system */ | |||
92 | extern int Oflag; /* format as an 4.3BSD file system */ | |||
93 | extern daddr_t fssize; /* file system size in 512-byte blocks. */ | |||
94 | extern long long sectorsize; /* bytes/sector */ | |||
95 | extern int fsize; /* fragment size */ | |||
96 | extern int bsize; /* block size */ | |||
97 | extern int maxfrgspercg; /* maximum fragments per cylinder group */ | |||
98 | extern int minfree; /* free space threshold */ | |||
99 | extern int opt; /* optimization preference (space or time) */ | |||
100 | extern int density; /* number of bytes per inode */ | |||
101 | extern int maxbpg; /* maximum blocks per file in a cyl group */ | |||
102 | extern int avgfilesize; /* expected average file size */ | |||
103 | extern int avgfilesperdir; /* expected number of files per directory */ | |||
104 | extern int quiet; /* quiet flag */ | |||
105 | extern caddr_t membase; /* start address of memory based filesystem */ | |||
106 | ||||
107 | union fs_u { | |||
108 | struct fs fs; | |||
109 | char pad[SBSIZE8192]; | |||
110 | } *fsun; | |||
111 | #define sblockfsun->fs fsun->fs | |||
112 | ||||
113 | struct csum *fscs; | |||
114 | ||||
115 | union cg_u { | |||
116 | struct cg cg; | |||
117 | char pad[MAXBSIZE(64 * 1024)]; | |||
118 | } *cgun; | |||
119 | #define acgcgun->cg cgun->cg | |||
120 | ||||
121 | union dinode { | |||
122 | struct ufs1_dinode dp1; | |||
123 | struct ufs2_dinode dp2; | |||
124 | }; | |||
125 | ||||
126 | int fsi, fso; | |||
127 | ||||
128 | static caddr_t iobuf; | |||
129 | static long iobufsize; | |||
130 | ||||
131 | daddr_t alloc(int, int); | |||
132 | static int charsperline(void); | |||
133 | static int ilog2(int); | |||
134 | void initcg(u_int, time_t); | |||
135 | void wtfs(daddr_t, int, void *); | |||
136 | int fsinit1(time_t, mode_t, uid_t, gid_t); | |||
137 | int fsinit2(time_t, mode_t, uid_t, gid_t); | |||
138 | int makedir(struct direct *, int); | |||
139 | void iput(union dinode *, ino_t); | |||
140 | void setblock(struct fs *, unsigned char *, int); | |||
141 | void clrblock(struct fs *, unsigned char *, int); | |||
142 | int isblock(struct fs *, unsigned char *, int); | |||
143 | void rdfs(daddr_t, int, void *); | |||
144 | void mkfs(struct partition *, char *, int, int, | |||
145 | mode_t, uid_t, gid_t); | |||
146 | static void checksz(void); | |||
147 | ||||
148 | #ifndef STANDALONE | |||
149 | volatile sig_atomic_t cur_cylno; | |||
150 | volatile const char *cur_fsys; | |||
151 | void siginfo(int sig); | |||
152 | ||||
153 | void | |||
154 | siginfo(int sig) | |||
155 | { | |||
156 | int save_errno = errno(*__errno()); | |||
157 | ||||
158 | dprintf(STDERR_FILENO2, "%s: initializing cg %ld/%d\n", | |||
159 | cur_fsys, (long)cur_cylno, sblockfsun->fs.fs_ncg); | |||
160 | errno(*__errno()) = save_errno; | |||
161 | } | |||
162 | #endif | |||
163 | ||||
164 | void | |||
165 | mkfs(struct partition *pp, char *fsys, int fi, int fo, mode_t mfsmode, | |||
166 | uid_t mfsuid, gid_t mfsgid) | |||
167 | { | |||
168 | time_t utime; | |||
169 | quad_t sizepb; | |||
170 | int i, j, width, origdensity, fragsperinode, minfpg, optimalfpg; | |||
171 | int lastminfpg, mincylgrps; | |||
172 | uint32_t bpg; | |||
173 | long csfrags; | |||
174 | u_int cg; | |||
175 | char tmpbuf[100]; /* XXX this will break in about 2,500 years */ | |||
176 | ||||
177 | if ((fsun = calloc(1, sizeof (union fs_u))) == NULL((void *)0) || | |||
178 | (cgun = calloc(1, sizeof (union cg_u))) == NULL((void *)0)) | |||
179 | err(1, "calloc"); | |||
180 | ||||
181 | #ifndef STANDALONE | |||
182 | time(&utime); | |||
183 | #endif | |||
184 | if (mfs) { | |||
185 | size_t sz; | |||
186 | if (fssize > SIZE_MAX0xffffffffffffffffUL / DEV_BSIZE(1 << 9)) { | |||
187 | errno(*__errno()) = ENOMEM12; | |||
188 | err(12, "mmap"); | |||
189 | } | |||
190 | sz = (size_t)fssize * DEV_BSIZE(1 << 9); | |||
191 | membase = mmap(NULL((void *)0), sz, PROT_READ0x01|PROT_WRITE0x02, | |||
192 | MAP_ANON0x1000|MAP_PRIVATE0x0002, -1, (off_t)0); | |||
193 | if (membase == MAP_FAILED((void *)-1)) | |||
194 | err(12, "mmap"); | |||
195 | madvise(membase, sz, MADV_RANDOM1); | |||
196 | } | |||
197 | fsi = fi; | |||
198 | fso = fo; | |||
199 | /* | |||
200 | * Validate the given file system size. | |||
201 | * Verify that its last block can actually be accessed. | |||
202 | */ | |||
203 | if (Oflag <= 1 && fssize > INT_MAX2147483647) | |||
204 | errx(13, "preposterous size %lld, max is %d", (long long)fssize, | |||
205 | INT_MAX2147483647); | |||
206 | if (Oflag == 2 && fssize > MAXDISKSIZE0x7fffffffffffLL) | |||
207 | errx(13, "preposterous size %lld, max is %lld", | |||
208 | (long long)fssize, MAXDISKSIZE0x7fffffffffffLL); | |||
209 | ||||
210 | wtfs(fssize - (sectorsize / DEV_BSIZE(1 << 9)), sectorsize, (char *)&sblockfsun->fs); | |||
211 | ||||
212 | sblockfsun->fs.fs_postblformat = FS_DYNAMICPOSTBLFMT1; | |||
213 | sblockfsun->fs.fs_avgfilesize = avgfilesize; | |||
214 | sblockfsun->fs.fs_avgfpdir = avgfilesperdir; | |||
215 | ||||
216 | /* | |||
217 | * Collect and verify the block and fragment sizes. | |||
218 | */ | |||
219 | if (!POWEROF2(bsize)(((bsize) & ((bsize) - 1)) == 0)) { | |||
220 | errx(16, "block size must be a power of 2, not %d", bsize); | |||
221 | } | |||
222 | if (!POWEROF2(fsize)(((fsize) & ((fsize) - 1)) == 0)) { | |||
223 | errx(17, "fragment size must be a power of 2, not %d", | |||
224 | fsize); | |||
225 | } | |||
226 | if (fsize < sectorsize) { | |||
227 | errx(18, "fragment size %d is too small, minimum is %lld", | |||
228 | fsize, sectorsize); | |||
229 | } | |||
230 | if (bsize < MINBSIZE4096) { | |||
231 | errx(19, "block size %d is too small, minimum is %d", | |||
232 | bsize, MINBSIZE4096); | |||
233 | } | |||
234 | if (bsize > MAXBSIZE(64 * 1024)) { | |||
235 | errx(19, "block size %d is too large, maximum is %d", | |||
236 | bsize, MAXBSIZE(64 * 1024)); | |||
237 | } | |||
238 | if (bsize < fsize) { | |||
239 | errx(20, "block size (%d) cannot be smaller than fragment size (%d)", | |||
240 | bsize, fsize); | |||
241 | } | |||
242 | sblockfsun->fs.fs_bsize = bsize; | |||
243 | sblockfsun->fs.fs_fsize = fsize; | |||
244 | ||||
245 | /* | |||
246 | * Calculate the superblock bitmasks and shifts. | |||
247 | */ | |||
248 | sblockfsun->fs.fs_bmask = ~(sblockfsun->fs.fs_bsize - 1); | |||
249 | sblockfsun->fs.fs_fmask = ~(sblockfsun->fs.fs_fsize - 1); | |||
250 | sblockfsun->fs.fs_qbmask = ~sblockfsun->fs.fs_bmask; | |||
251 | sblockfsun->fs.fs_qfmask = ~sblockfsun->fs.fs_fmask; | |||
252 | sblockfsun->fs.fs_bshift = ilog2(sblockfsun->fs.fs_bsize); | |||
253 | sblockfsun->fs.fs_fshift = ilog2(sblockfsun->fs.fs_fsize); | |||
254 | sblockfsun->fs.fs_frag = numfrags(&sblock, sblock.fs_bsize)((fsun->fs.fs_bsize) >> (&fsun->fs)->fs_fshift ); | |||
255 | if (sblockfsun->fs.fs_frag > MAXFRAG8) { | |||
256 | errx(21, "fragment size %d is too small, minimum with block " | |||
257 | "size %d is %d", sblockfsun->fs.fs_fsize, sblockfsun->fs.fs_bsize, | |||
258 | sblockfsun->fs.fs_bsize / MAXFRAG8); | |||
259 | } | |||
260 | sblockfsun->fs.fs_fragshift = ilog2(sblockfsun->fs.fs_frag); | |||
261 | sblockfsun->fs.fs_fsbtodb = ilog2(sblockfsun->fs.fs_fsize / DEV_BSIZE(1 << 9)); | |||
262 | sblockfsun->fs.fs_size = dbtofsb(&sblock, fssize)((fssize) >> (&fsun->fs)->fs_fsbtodb); | |||
263 | sblockfsun->fs.fs_nspf = sblockfsun->fs.fs_fsize / DEV_BSIZE(1 << 9); | |||
264 | sblockfsun->fs.fs_maxcontig = 1; | |||
265 | sblockfsun->fs.fs_nrpos = 1; | |||
266 | sblockfsun->fs.fs_cpg = 1; | |||
267 | ||||
268 | /* | |||
269 | * Before the file system is fully initialized, mark it as invalid. | |||
270 | */ | |||
271 | sblockfsun->fs.fs_magic = FS_BAD_MAGIC0x19960408; | |||
272 | ||||
273 | /* | |||
274 | * Set the remaining superblock fields. Note that for FFS1, media | |||
275 | * geometry fields are set to fake values. This is for compatibility | |||
276 | * with really ancient kernels that might still inspect these values. | |||
277 | */ | |||
278 | if (Oflag <= 1) { | |||
279 | sblockfsun->fs.fs_sblockloc = SBLOCK_UFS18192; | |||
280 | sblockfsun->fs.fs_nindir = sblockfsun->fs.fs_bsize / sizeof(int32_t); | |||
281 | sblockfsun->fs.fs_inopb = sblockfsun->fs.fs_bsize / sizeof(struct ufs1_dinode); | |||
282 | if (Oflag == 0) { | |||
283 | sblockfsun->fs.fs_maxsymlinklen = 0; | |||
284 | sblockfsun->fs.fs_inodefmt = FS_42INODEFMT-1; | |||
285 | } else { | |||
286 | sblockfsun->fs.fs_maxsymlinklen = MAXSYMLINKLEN_UFS1((12 + 3) * sizeof(int32_t)); | |||
287 | sblockfsun->fs.fs_inodefmt = FS_44INODEFMT2; | |||
288 | } | |||
289 | sblockfsun->fs.fs_cgoffset = 0; | |||
290 | sblockfsun->fs.fs_cgmask = 0xffffffff; | |||
291 | sblockfsun->fs.fs_ffs1_size = sblockfsun->fs.fs_size; | |||
292 | sblockfsun->fs.fs_rotdelay = 0; | |||
293 | sblockfsun->fs.fs_rps = 60; | |||
294 | sblockfsun->fs.fs_interleave = 1; | |||
295 | sblockfsun->fs.fs_trackskew = 0; | |||
296 | sblockfsun->fs.fs_cpc = 0; | |||
297 | } else { | |||
298 | sblockfsun->fs.fs_inodefmt = FS_44INODEFMT2; | |||
299 | sblockfsun->fs.fs_sblockloc = SBLOCK_UFS265536; | |||
300 | sblockfsun->fs.fs_nindir = sblockfsun->fs.fs_bsize / sizeof(int64_t); | |||
301 | sblockfsun->fs.fs_inopb = sblockfsun->fs.fs_bsize / sizeof(struct ufs2_dinode); | |||
302 | sblockfsun->fs.fs_maxsymlinklen = MAXSYMLINKLEN_UFS2((12 + 3) * sizeof(int64_t)); | |||
303 | } | |||
304 | sblockfsun->fs.fs_sblkno = | |||
305 | roundup(howmany(sblock.fs_sblockloc + SBLOCKSIZE, sblock.fs_fsize),(((((((fsun->fs.fs_sblockloc + 8192) + ((fsun->fs.fs_fsize ) - 1)) / (fsun->fs.fs_fsize)))+((fsun->fs.fs_frag)-1)) /(fsun->fs.fs_frag))*(fsun->fs.fs_frag)) | |||
306 | sblock.fs_frag)(((((((fsun->fs.fs_sblockloc + 8192) + ((fsun->fs.fs_fsize ) - 1)) / (fsun->fs.fs_fsize)))+((fsun->fs.fs_frag)-1)) /(fsun->fs.fs_frag))*(fsun->fs.fs_frag)); | |||
307 | sblockfsun->fs.fs_cblkno = (int32_t)(sblockfsun->fs.fs_sblkno + | |||
308 | roundup(howmany(SBSIZE, sblock.fs_fsize), sblock.fs_frag)(((((((8192) + ((fsun->fs.fs_fsize) - 1)) / (fsun->fs.fs_fsize )))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag))); | |||
309 | sblockfsun->fs.fs_iblkno = sblockfsun->fs.fs_cblkno + sblockfsun->fs.fs_frag; | |||
310 | sblockfsun->fs.fs_maxfilesize = sblockfsun->fs.fs_bsize * NDADDR12 - 1; | |||
311 | for (sizepb = sblockfsun->fs.fs_bsize, i = 0; i < NIADDR3; i++) { | |||
312 | sizepb *= NINDIR(&sblock)((&fsun->fs)->fs_nindir); | |||
313 | sblockfsun->fs.fs_maxfilesize += sizepb; | |||
314 | } | |||
315 | #ifdef notyet | |||
316 | /* | |||
317 | * It is impossible to create a snapshot in case fs_maxfilesize is | |||
318 | * smaller than fssize. | |||
319 | */ | |||
320 | if (sblockfsun->fs.fs_maxfilesize < (u_quad_t)fssize) | |||
321 | warnx("WARNING: You will be unable to create snapshots on this " | |||
322 | "file system. Correct by using a larger blocksize."); | |||
323 | #endif | |||
324 | /* | |||
325 | * Calculate the number of blocks to put into each cylinder group. The | |||
326 | * first goal is to have at least enough data blocks in each cylinder | |||
327 | * group to meet the density requirement. Once this goal is achieved | |||
328 | * we try to expand to have at least mincylgrps cylinder groups. Once | |||
329 | * this goal is achieved, we pack as many blocks into each cylinder | |||
330 | * group map as will fit. | |||
331 | * | |||
332 | * We start by calculating the smallest number of blocks that we can | |||
333 | * put into each cylinder group. If this is too big, we reduce the | |||
334 | * density until it fits. | |||
335 | */ | |||
336 | origdensity = density; | |||
337 | for (;;) { | |||
338 | fragsperinode = MAXIMUM(numfrags(&sblock, density), 1)(((((density) >> (&fsun->fs)->fs_fshift)) > (1)) ? (((density) >> (&fsun->fs)->fs_fshift )) : (1)); | |||
339 | ||||
340 | minfpg = fragsperinode * INOPB(&sblock)((&fsun->fs)->fs_inopb); | |||
341 | if (minfpg > sblockfsun->fs.fs_size) | |||
342 | minfpg = sblockfsun->fs.fs_size; | |||
343 | ||||
344 | sblockfsun->fs.fs_ipg = INOPB(&sblock)((&fsun->fs)->fs_inopb); | |||
345 | sblockfsun->fs.fs_fpg = roundup(sblock.fs_iblkno +((((fsun->fs.fs_iblkno + fsun->fs.fs_ipg / ((&fsun-> fs)->fs_inopb >> (&fsun->fs)->fs_fragshift ))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag)) | |||
346 | sblock.fs_ipg / INOPF(&sblock), sblock.fs_frag)((((fsun->fs.fs_iblkno + fsun->fs.fs_ipg / ((&fsun-> fs)->fs_inopb >> (&fsun->fs)->fs_fragshift ))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag)); | |||
347 | if (sblockfsun->fs.fs_fpg < minfpg) | |||
348 | sblockfsun->fs.fs_fpg = minfpg; | |||
349 | ||||
350 | sblockfsun->fs.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode),(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))) | |||
351 | INOPB(&sblock))(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))); | |||
352 | sblockfsun->fs.fs_fpg = roundup(sblock.fs_iblkno +((((fsun->fs.fs_iblkno + fsun->fs.fs_ipg / ((&fsun-> fs)->fs_inopb >> (&fsun->fs)->fs_fragshift ))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag)) | |||
353 | sblock.fs_ipg / INOPF(&sblock), sblock.fs_frag)((((fsun->fs.fs_iblkno + fsun->fs.fs_ipg / ((&fsun-> fs)->fs_inopb >> (&fsun->fs)->fs_fragshift ))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag)); | |||
354 | if (sblockfsun->fs.fs_fpg < minfpg) | |||
355 | sblockfsun->fs.fs_fpg = minfpg; | |||
356 | ||||
357 | sblockfsun->fs.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode),(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))) | |||
358 | INOPB(&sblock))(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))); | |||
359 | ||||
360 | if (CGSIZE(&sblock)(sizeof(struct cg) + sizeof(int32_t) + (&fsun->fs)-> fs_cpg * sizeof(int32_t) + (&fsun->fs)->fs_cpg * (& fsun->fs)->fs_nrpos * sizeof(int16_t) + ((((&fsun-> fs)->fs_ipg) + ((8) - 1)) / (8)) + ((((&fsun->fs)-> fs_fpg) + ((8) - 1)) / (8)) + ((&fsun->fs)->fs_contigsumsize <= 0 ? 0 : (&fsun->fs)->fs_contigsumsize * sizeof (int32_t) + ((((((&fsun->fs)->fs_fpg) >> (& fsun->fs)->fs_fragshift)) + ((8) - 1)) / (8)))) < (unsigned long)sblockfsun->fs.fs_bsize) | |||
361 | break; | |||
362 | ||||
363 | density -= sblockfsun->fs.fs_fsize; | |||
364 | } | |||
365 | if (density != origdensity) | |||
366 | warnx("density reduced from %d to %d bytes per inode", | |||
367 | origdensity, density); | |||
368 | ||||
369 | /* | |||
370 | * Use a lower value for mincylgrps if the user specified a large | |||
371 | * number of blocks per cylinder group. This is needed for, e.g. the | |||
372 | * install media which needs to pack 2 files very tightly. | |||
373 | */ | |||
374 | mincylgrps = MINCYLGRPS4; | |||
375 | if (maxfrgspercg != INT_MAX2147483647) { | |||
376 | i = sblockfsun->fs.fs_size / maxfrgspercg; | |||
377 | if (i < MINCYLGRPS4) | |||
378 | mincylgrps = i <= 0 ? 1 : i; | |||
379 | } | |||
380 | ||||
381 | /* | |||
382 | * Start packing more blocks into the cylinder group until it cannot | |||
383 | * grow any larger, the number of cylinder groups drops below | |||
384 | * mincylgrps, or we reach the requested size. | |||
385 | */ | |||
386 | for (;;) { | |||
387 | sblockfsun->fs.fs_fpg += sblockfsun->fs.fs_frag; | |||
388 | sblockfsun->fs.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode),(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))) | |||
389 | INOPB(&sblock))(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))); | |||
390 | ||||
391 | if (sblockfsun->fs.fs_fpg > maxfrgspercg || | |||
392 | sblockfsun->fs.fs_size / sblockfsun->fs.fs_fpg < mincylgrps || | |||
393 | CGSIZE(&sblock)(sizeof(struct cg) + sizeof(int32_t) + (&fsun->fs)-> fs_cpg * sizeof(int32_t) + (&fsun->fs)->fs_cpg * (& fsun->fs)->fs_nrpos * sizeof(int16_t) + ((((&fsun-> fs)->fs_ipg) + ((8) - 1)) / (8)) + ((((&fsun->fs)-> fs_fpg) + ((8) - 1)) / (8)) + ((&fsun->fs)->fs_contigsumsize <= 0 ? 0 : (&fsun->fs)->fs_contigsumsize * sizeof (int32_t) + ((((((&fsun->fs)->fs_fpg) >> (& fsun->fs)->fs_fragshift)) + ((8) - 1)) / (8)))) > (unsigned long)sblockfsun->fs.fs_bsize) | |||
394 | break; | |||
395 | } | |||
396 | sblockfsun->fs.fs_fpg -= sblockfsun->fs.fs_frag; | |||
397 | sblockfsun->fs.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode),(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))) | |||
398 | INOPB(&sblock))(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))); | |||
399 | if (sblockfsun->fs.fs_fpg > maxfrgspercg) | |||
400 | warnx("can't honour -c: minimum is %d", sblockfsun->fs.fs_fpg); | |||
401 | ||||
402 | /* | |||
403 | * Check to be sure that the last cylinder group has enough blocks to | |||
404 | * be viable. If it is too small, reduce the number of blocks per | |||
405 | * cylinder group which will have the effect of moving more blocks into | |||
406 | * the last cylinder group. | |||
407 | */ | |||
408 | optimalfpg = sblockfsun->fs.fs_fpg; | |||
409 | for (;;) { | |||
410 | sblockfsun->fs.fs_ncg = howmany(sblock.fs_size, sblock.fs_fpg)(((fsun->fs.fs_size) + ((fsun->fs.fs_fpg) - 1)) / (fsun ->fs.fs_fpg)); | |||
411 | lastminfpg = roundup(sblock.fs_iblkno +((((fsun->fs.fs_iblkno + fsun->fs.fs_ipg / ((&fsun-> fs)->fs_inopb >> (&fsun->fs)->fs_fragshift ))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag)) | |||
412 | sblock.fs_ipg / INOPF(&sblock), sblock.fs_frag)((((fsun->fs.fs_iblkno + fsun->fs.fs_ipg / ((&fsun-> fs)->fs_inopb >> (&fsun->fs)->fs_fragshift ))+((fsun->fs.fs_frag)-1))/(fsun->fs.fs_frag))*(fsun-> fs.fs_frag)); | |||
413 | if (sblockfsun->fs.fs_size < lastminfpg) | |||
414 | errx(28, "file system size %jd < minimum size of %d " | |||
415 | "fragments", (intmax_t)sblockfsun->fs.fs_size, lastminfpg); | |||
416 | ||||
417 | if (sblockfsun->fs.fs_size % sblockfsun->fs.fs_fpg >= lastminfpg || | |||
418 | sblockfsun->fs.fs_size % sblockfsun->fs.fs_fpg == 0) | |||
419 | break; | |||
420 | ||||
421 | sblockfsun->fs.fs_fpg -= sblockfsun->fs.fs_frag; | |||
422 | sblockfsun->fs.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode),(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))) | |||
423 | INOPB(&sblock))(((((((fsun->fs.fs_fpg) + ((fragsperinode) - 1)) / (fragsperinode )))+((((&fsun->fs)->fs_inopb))-1))/(((&fsun-> fs)->fs_inopb)))*(((&fsun->fs)->fs_inopb))); | |||
424 | } | |||
425 | ||||
426 | if (optimalfpg != sblockfsun->fs.fs_fpg) | |||
427 | warnx("reduced number of fragments per cylinder group from %d" | |||
428 | " to %d to enlarge last cylinder group", optimalfpg, | |||
429 | sblockfsun->fs.fs_fpg); | |||
430 | ||||
431 | if ((ino_t)sblockfsun->fs.fs_ipg * sblockfsun->fs.fs_ncg > UINT_MAX(2147483647 *2U +1U)) | |||
432 | errx(42, "more than 2^32 inodes, increase density, block or " | |||
433 | "fragment size"); | |||
434 | ||||
435 | /* | |||
436 | * Back to filling superblock fields. | |||
437 | */ | |||
438 | if (Oflag <= 1) { | |||
439 | sblockfsun->fs.fs_spc = sblockfsun->fs.fs_fpg * sblockfsun->fs.fs_nspf; | |||
440 | sblockfsun->fs.fs_nsect = sblockfsun->fs.fs_spc; | |||
441 | sblockfsun->fs.fs_npsect = sblockfsun->fs.fs_spc; | |||
442 | sblockfsun->fs.fs_ncyl = sblockfsun->fs.fs_ncg; | |||
443 | } | |||
444 | sblockfsun->fs.fs_cgsize = fragroundup(&sblock, CGSIZE(&sblock))((((sizeof(struct cg) + sizeof(int32_t) + (&fsun->fs)-> fs_cpg * sizeof(int32_t) + (&fsun->fs)->fs_cpg * (& fsun->fs)->fs_nrpos * sizeof(int16_t) + ((((&fsun-> fs)->fs_ipg) + ((8) - 1)) / (8)) + ((((&fsun->fs)-> fs_fpg) + ((8) - 1)) / (8)) + ((&fsun->fs)->fs_contigsumsize <= 0 ? 0 : (&fsun->fs)->fs_contigsumsize * sizeof (int32_t) + ((((((&fsun->fs)->fs_fpg) >> (& fsun->fs)->fs_fragshift)) + ((8) - 1)) / (8))))) + (& fsun->fs)->fs_qfmask) & (&fsun->fs)->fs_fmask ); | |||
445 | sblockfsun->fs.fs_dblkno = sblockfsun->fs.fs_iblkno + sblockfsun->fs.fs_ipg / INOPF(&sblock)((&fsun->fs)->fs_inopb >> (&fsun->fs)-> fs_fragshift); | |||
446 | sblockfsun->fs.fs_csaddr = cgdmin(&sblock, 0)((((daddr_t)(&fsun->fs)->fs_fpg * (0)) + (&fsun ->fs)->fs_cgoffset * ((0) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_dblkno); | |||
447 | sblockfsun->fs.fs_cssize = | |||
448 | fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum))(((fsun->fs.fs_ncg * sizeof(struct csum)) + (&fsun-> fs)->fs_qfmask) & (&fsun->fs)->fs_fmask); | |||
449 | ||||
450 | fscs = calloc(1, sblockfsun->fs.fs_cssize); | |||
451 | if (fscs == NULL((void *)0)) | |||
452 | errx(31, "calloc failed"); | |||
453 | ||||
454 | sblockfsun->fs.fs_sbsize = fragroundup(&sblock, sizeof(struct fs))(((sizeof(struct fs)) + (&fsun->fs)->fs_qfmask) & (&fsun->fs)->fs_fmask); | |||
455 | if (sblockfsun->fs.fs_sbsize > SBLOCKSIZE8192) | |||
456 | sblockfsun->fs.fs_sbsize = SBLOCKSIZE8192; | |||
457 | ||||
458 | sblockfsun->fs.fs_minfree = minfree; | |||
459 | sblockfsun->fs.fs_maxbpg = maxbpg; | |||
460 | sblockfsun->fs.fs_optim = opt; | |||
461 | sblockfsun->fs.fs_cgrotor = 0; | |||
462 | sblockfsun->fs.fs_pendingblocks = 0; | |||
463 | sblockfsun->fs.fs_pendinginodes = 0; | |||
464 | sblockfsun->fs.fs_fmod = 0; | |||
465 | sblockfsun->fs.fs_ronly = 0; | |||
466 | sblockfsun->fs.fs_state = 0; | |||
467 | sblockfsun->fs.fs_clean = 1; | |||
468 | sblockfsun->fs.fs_id[0] = (u_int32_t)utime; | |||
469 | sblockfsun->fs.fs_id[1] = (u_int32_t)arc4random(); | |||
470 | sblockfsun->fs.fs_fsmnt[0] = '\0'; | |||
471 | ||||
472 | csfrags = howmany(sblock.fs_cssize, sblock.fs_fsize)(((fsun->fs.fs_cssize) + ((fsun->fs.fs_fsize) - 1)) / ( fsun->fs.fs_fsize)); | |||
473 | sblockfsun->fs.fs_dsize = sblockfsun->fs.fs_size - sblockfsun->fs.fs_sblkno - | |||
474 | sblockfsun->fs.fs_ncg * (sblockfsun->fs.fs_dblkno - sblockfsun->fs.fs_sblkno); | |||
475 | ||||
476 | sblockfsun->fs.fs_cstotal.cs_nbfree = fragstoblks(&sblock, sblock.fs_dsize)((fsun->fs.fs_dsize) >> (&fsun->fs)->fs_fragshift ) - | |||
477 | howmany(csfrags, sblock.fs_frag)(((csfrags) + ((fsun->fs.fs_frag) - 1)) / (fsun->fs.fs_frag )); | |||
478 | sblockfsun->fs.fs_cstotal.cs_nffree = fragnum(&sblock, sblock.fs_size)((fsun->fs.fs_size) & ((&fsun->fs)->fs_frag - 1)) + | |||
479 | (fragnum(&sblock, csfrags)((csfrags) & ((&fsun->fs)->fs_frag - 1)) > 0 ? | |||
480 | sblockfsun->fs.fs_frag - fragnum(&sblock, csfrags)((csfrags) & ((&fsun->fs)->fs_frag - 1)) : 0); | |||
481 | sblockfsun->fs.fs_cstotal.cs_nifree = sblockfsun->fs.fs_ncg * sblockfsun->fs.fs_ipg - ROOTINO((ufsino_t)2); | |||
482 | sblockfsun->fs.fs_cstotal.cs_ndir = 0; | |||
483 | ||||
484 | sblockfsun->fs.fs_dsize -= csfrags; | |||
485 | sblockfsun->fs.fs_time = utime; | |||
486 | ||||
487 | if (Oflag <= 1) { | |||
488 | sblockfsun->fs.fs_ffs1_time = sblockfsun->fs.fs_time; | |||
489 | sblockfsun->fs.fs_ffs1_dsize = sblockfsun->fs.fs_dsize; | |||
490 | sblockfsun->fs.fs_ffs1_csaddr = sblockfsun->fs.fs_csaddr; | |||
491 | sblockfsun->fs.fs_ffs1_cstotal.cs_ndir = sblockfsun->fs.fs_cstotal.cs_ndir; | |||
492 | sblockfsun->fs.fs_ffs1_cstotal.cs_nbfree = sblockfsun->fs.fs_cstotal.cs_nbfree; | |||
493 | sblockfsun->fs.fs_ffs1_cstotal.cs_nifree = sblockfsun->fs.fs_cstotal.cs_nifree; | |||
494 | sblockfsun->fs.fs_ffs1_cstotal.cs_nffree = sblockfsun->fs.fs_cstotal.cs_nffree; | |||
495 | } | |||
496 | ||||
497 | /* | |||
498 | * Dump out summary information about file system. | |||
499 | */ | |||
500 | if (!mfs) { | |||
501 | #define B2MBFACTOR (1 / (1024.0 * 1024.0)) | |||
502 | printf("%s: %.1fMB in %jd sectors of %lld bytes\n", fsys, | |||
503 | (float)sblockfsun->fs.fs_size * sblockfsun->fs.fs_fsize * B2MBFACTOR, | |||
504 | (intmax_t)fsbtodb(&sblock, sblock.fs_size)((fsun->fs.fs_size) << (&fsun->fs)->fs_fsbtodb ) / | |||
505 | (sectorsize / DEV_BSIZE(1 << 9)), sectorsize); | |||
506 | printf("%u cylinder groups of %.2fMB, %d blocks, %u" | |||
507 | " inodes each\n", sblockfsun->fs.fs_ncg, | |||
508 | (float)sblockfsun->fs.fs_fpg * sblockfsun->fs.fs_fsize * B2MBFACTOR, | |||
509 | sblockfsun->fs.fs_fpg / sblockfsun->fs.fs_frag, sblockfsun->fs.fs_ipg); | |||
510 | #undef B2MBFACTOR | |||
511 | checksz(); | |||
512 | } | |||
513 | ||||
514 | /* | |||
515 | * Wipe out old FFS1 superblock if necessary. | |||
516 | */ | |||
517 | if (Oflag >= 2) { | |||
518 | union fs_u *fsun1; | |||
519 | struct fs *fs1; | |||
520 | ||||
521 | fsun1 = calloc(1, sizeof(union fs_u)); | |||
522 | if (fsun1 == NULL((void *)0)) | |||
523 | err(39, "calloc"); | |||
524 | fs1 = &fsun1->fs; | |||
525 | rdfs(SBLOCK_UFS18192 / DEV_BSIZE(1 << 9), SBSIZE8192, (char *)fs1); | |||
526 | if (fs1->fs_magic == FS_UFS1_MAGIC0x011954) { | |||
527 | fs1->fs_magic = FS_BAD_MAGIC0x19960408; | |||
528 | wtfs(SBLOCK_UFS18192 / DEV_BSIZE(1 << 9), SBSIZE8192, (char *)fs1); | |||
529 | } | |||
530 | free(fsun1); | |||
531 | } | |||
532 | ||||
533 | wtfs((int)sblockfsun->fs.fs_sblockloc / DEV_BSIZE(1 << 9), SBSIZE8192, (char *)&sblockfsun->fs); | |||
534 | sblockfsun->fs.fs_magic = (Oflag <= 1) ? FS_UFS1_MAGIC0x011954 : FS_UFS2_MAGIC0x19540119; | |||
535 | ||||
536 | /* | |||
537 | * Now build the cylinders group blocks and | |||
538 | * then print out indices of cylinder groups. | |||
539 | */ | |||
540 | if (!quiet) | |||
541 | printf("super-block backups (for fsck -b #) at:\n"); | |||
542 | #ifndef STANDALONE | |||
543 | else if (!mfs && isatty(STDIN_FILENO0)) { | |||
544 | signal(SIGINFO29, siginfo); | |||
545 | cur_fsys = fsys; | |||
546 | } | |||
547 | #endif | |||
548 | i = 0; | |||
549 | width = charsperline(); | |||
550 | /* | |||
551 | * Allocate space for superblock, cylinder group map, and two sets of | |||
552 | * inode blocks. | |||
553 | */ | |||
554 | if (sblockfsun->fs.fs_bsize < SBLOCKSIZE8192) | |||
555 | iobufsize = SBLOCKSIZE8192 + 3 * sblockfsun->fs.fs_bsize; | |||
556 | else | |||
557 | iobufsize = 4 * sblockfsun->fs.fs_bsize; | |||
558 | if ((iobuf = malloc(iobufsize)) == NULL((void *)0)) | |||
559 | errx(38, "cannot allocate I/O buffer"); | |||
560 | bzero(iobuf, iobufsize); | |||
561 | /* | |||
562 | * Make a copy of the superblock into the buffer that we will be | |||
563 | * writing out in each cylinder group. | |||
564 | */ | |||
565 | bcopy((char *)&sblockfsun->fs, iobuf, SBLOCKSIZE8192); | |||
566 | for (cg = 0; cg < sblockfsun->fs.fs_ncg; cg++) { | |||
567 | cur_cylno = (sig_atomic_t)cg; | |||
568 | initcg(cg, utime); | |||
569 | if (quiet) | |||
570 | continue; | |||
571 | j = snprintf(tmpbuf, sizeof tmpbuf, " %lld,", | |||
572 | (long long)fsbtodb(&sblock, cgsblock(&sblock, cg))((((((daddr_t)(&fsun->fs)->fs_fpg * (cg)) + (&fsun ->fs)->fs_cgoffset * ((cg) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_sblkno)) << (& fsun->fs)->fs_fsbtodb)); | |||
573 | if (j >= sizeof tmpbuf) | |||
574 | j = sizeof tmpbuf - 1; | |||
575 | if (j < 0 || i+j >= width) { | |||
576 | printf("\n"); | |||
577 | i = 0; | |||
578 | } | |||
579 | i += j; | |||
580 | printf("%s", tmpbuf); | |||
581 | fflush(stdout(&__sF[1])); | |||
582 | } | |||
583 | if (!quiet) | |||
584 | printf("\n"); | |||
585 | if (Nflag && !mfs) | |||
586 | exit(0); | |||
587 | /* | |||
588 | * Now construct the initial file system, then write out the superblock. | |||
589 | */ | |||
590 | if (Oflag <= 1) { | |||
591 | if (fsinit1(utime, mfsmode, mfsuid, mfsgid)) | |||
592 | errx(32, "fsinit1 failed"); | |||
593 | sblockfsun->fs.fs_ffs1_cstotal.cs_ndir = sblockfsun->fs.fs_cstotal.cs_ndir; | |||
594 | sblockfsun->fs.fs_ffs1_cstotal.cs_nbfree = sblockfsun->fs.fs_cstotal.cs_nbfree; | |||
595 | sblockfsun->fs.fs_ffs1_cstotal.cs_nifree = sblockfsun->fs.fs_cstotal.cs_nifree; | |||
596 | sblockfsun->fs.fs_ffs1_cstotal.cs_nffree = sblockfsun->fs.fs_cstotal.cs_nffree; | |||
597 | } else { | |||
598 | if (fsinit2(utime, mfsmode, mfsuid, mfsgid)) | |||
599 | errx(32, "fsinit2 failed"); | |||
600 | } | |||
601 | ||||
602 | wtfs((int)sblockfsun->fs.fs_sblockloc / DEV_BSIZE(1 << 9), SBSIZE8192, (char *)&sblockfsun->fs); | |||
603 | ||||
604 | for (i = 0; i < sblockfsun->fs.fs_cssize; i += sblockfsun->fs.fs_bsize) | |||
605 | wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i))((fsun->fs.fs_csaddr + ((i) >> (&fsun->fs)-> fs_fshift)) << (&fsun->fs)->fs_fsbtodb), | |||
606 | sblockfsun->fs.fs_cssize - i < sblockfsun->fs.fs_bsize ? | |||
607 | sblockfsun->fs.fs_cssize - i : sblockfsun->fs.fs_bsize, | |||
608 | ((char *)fscs) + i); | |||
609 | ||||
610 | /* | |||
611 | * Update information about this partition in pack label, to that it may | |||
612 | * be updated on disk. | |||
613 | */ | |||
614 | pp->p_fstype = FS_BSDFFS7; | |||
615 | pp->p_fragblock = | |||
616 | DISKLABELV1_FFS_FRAGBLOCK(sblock.fs_fsize, sblock.fs_frag)((fsun->fs.fs_fsize) * (fsun->fs.fs_frag) == 0 ? 0 : (( (ffs((fsun->fs.fs_fsize) * (fsun->fs.fs_frag)) - 13) << 3) | (ffs(fsun->fs.fs_frag)))); | |||
617 | bpg = sblockfsun->fs.fs_fpg / sblockfsun->fs.fs_frag; | |||
618 | while (bpg > USHRT_MAX(32767 *2 +1)) | |||
619 | bpg >>= 1; | |||
620 | pp->p_cpg = bpg; | |||
621 | } | |||
622 | ||||
623 | /* | |||
624 | * Initialize a cylinder group. | |||
625 | */ | |||
626 | void | |||
627 | initcg(u_int cg, time_t utime) | |||
628 | { | |||
629 | u_int i, j, d, dlower, dupper, blkno, start; | |||
630 | daddr_t cbase, dmax; | |||
631 | struct ufs1_dinode *dp1; | |||
632 | struct ufs2_dinode *dp2; | |||
633 | struct csum *cs; | |||
634 | ||||
635 | /* | |||
636 | * Determine block bounds for cylinder group. Allow space for | |||
637 | * super block summary information in first cylinder group. | |||
638 | */ | |||
639 | cbase = cgbase(&sblock, cg)((daddr_t)(&fsun->fs)->fs_fpg * (cg)); | |||
640 | dmax = cbase + sblockfsun->fs.fs_fpg; | |||
641 | if (dmax > sblockfsun->fs.fs_size) | |||
| ||||
642 | dmax = sblockfsun->fs.fs_size; | |||
643 | if (fsbtodb(&sblock, cgsblock(&sblock, cg))((((((daddr_t)(&fsun->fs)->fs_fpg * (cg)) + (&fsun ->fs)->fs_cgoffset * ((cg) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_sblkno)) << (& fsun->fs)->fs_fsbtodb) + iobufsize / DEV_BSIZE(1 << 9) | |||
644 | > fssize) | |||
645 | errx(40, "inode table does not fit in cylinder group"); | |||
646 | ||||
647 | dlower = cgsblock(&sblock, cg)((((daddr_t)(&fsun->fs)->fs_fpg * (cg)) + (&fsun ->fs)->fs_cgoffset * ((cg) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_sblkno) - cbase; | |||
648 | dupper = cgdmin(&sblock, cg)((((daddr_t)(&fsun->fs)->fs_fpg * (cg)) + (&fsun ->fs)->fs_cgoffset * ((cg) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_dblkno) - cbase; | |||
649 | if (cg == 0) | |||
650 | dupper += howmany(sblock.fs_cssize, sblock.fs_fsize)(((fsun->fs.fs_cssize) + ((fsun->fs.fs_fsize) - 1)) / ( fsun->fs.fs_fsize)); | |||
651 | cs = &fscs[cg]; | |||
652 | memset(&acgcgun->cg, 0, sblockfsun->fs.fs_cgsize); | |||
653 | acgcgun->cg.cg_ffs2_time = utime; | |||
654 | acgcgun->cg.cg_magic = CG_MAGIC0x090255; | |||
655 | acgcgun->cg.cg_cgx = cg; | |||
656 | acgcgun->cg.cg_ffs2_niblk = sblockfsun->fs.fs_ipg; | |||
657 | acgcgun->cg.cg_initediblk = MINIMUM(sblock.fs_ipg, 2 * INOPB(&sblock))(((fsun->fs.fs_ipg) < (2 * ((&fsun->fs)->fs_inopb ))) ? (fsun->fs.fs_ipg) : (2 * ((&fsun->fs)->fs_inopb ))); | |||
658 | acgcgun->cg.cg_ndblk = dmax - cbase; | |||
659 | ||||
660 | start = sizeof(struct cg); | |||
661 | if (Oflag <= 1) { | |||
662 | /* Hack to maintain compatibility with old fsck. */ | |||
663 | if (cg == sblockfsun->fs.fs_ncg - 1) | |||
664 | acgcgun->cg.cg_ncyl = 0; | |||
665 | else | |||
666 | acgcgun->cg.cg_ncyl = sblockfsun->fs.fs_cpg; | |||
667 | acgcgun->cg.cg_time = acgcgun->cg.cg_ffs2_time; | |||
668 | acgcgun->cg.cg_ffs2_time = 0; | |||
669 | acgcgun->cg.cg_niblk = acgcgun->cg.cg_ffs2_niblk; | |||
670 | acgcgun->cg.cg_ffs2_niblk = 0; | |||
671 | acgcgun->cg.cg_initediblk = 0; | |||
672 | acgcgun->cg.cg_btotoff = start; | |||
673 | acgcgun->cg.cg_boff = acgcgun->cg.cg_btotoff + sblockfsun->fs.fs_cpg * sizeof(int32_t); | |||
674 | acgcgun->cg.cg_iusedoff = acgcgun->cg.cg_boff + | |||
675 | sblockfsun->fs.fs_cpg * sizeof(u_int16_t); | |||
676 | } else { | |||
677 | acgcgun->cg.cg_iusedoff = start; | |||
678 | } | |||
679 | ||||
680 | acgcgun->cg.cg_freeoff = acgcgun->cg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT)(((fsun->fs.fs_ipg) + ((8) - 1)) / (8)); | |||
681 | acgcgun->cg.cg_nextfreeoff = acgcgun->cg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT)(((fsun->fs.fs_fpg) + ((8) - 1)) / (8)); | |||
682 | if (acgcgun->cg.cg_nextfreeoff > sblockfsun->fs.fs_cgsize) | |||
683 | errx(37, "panic: cylinder group too big: %u > %d", | |||
684 | acgcgun->cg.cg_nextfreeoff, sblockfsun->fs.fs_cgsize); | |||
685 | acgcgun->cg.cg_cs.cs_nifree += sblockfsun->fs.fs_ipg; | |||
686 | if (cg
| |||
687 | for (i = 0; i < ROOTINO((ufsino_t)2); i++) { | |||
688 | setbit(cg_inosused(&acg), i)(((((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_iused) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_iusedoff))) )[(i)>>3] |= 1<<((i)&(8 -1))); | |||
689 | acgcgun->cg.cg_cs.cs_nifree--; | |||
690 | } | |||
691 | } | |||
692 | if (cg
| |||
693 | /* | |||
694 | * In cg 0, space is reserved for boot and super blocks. | |||
695 | */ | |||
696 | for (d = 0; d < dlower; d += sblockfsun->fs.fs_frag) { | |||
697 | blkno = d / sblockfsun->fs.fs_frag; | |||
698 | setblock(&sblockfsun->fs, cg_blksfree(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff))), blkno); | |||
699 | acgcgun->cg.cg_cs.cs_nbfree++; | |||
700 | if (Oflag <= 1) { | |||
701 | cg_blktot(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_btot) : ((int32_t *)((u_int8_t * )(&cgun->cg) + (&cgun->cg)->cg_btotoff)))[cbtocylno(&sblock, d)(((d) << (&fsun->fs)->fs_fsbtodb) / (&fsun ->fs)->fs_spc)]++; | |||
702 | cg_blks(&sblock, &acg, cbtocylno(&sblock, d))(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_b[(((d) << (&fsun-> fs)->fs_fsbtodb) / (&fsun->fs)->fs_spc)]) : ((int16_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_boff ) + ((((d) << (&fsun->fs)->fs_fsbtodb) / (& fsun->fs)->fs_spc)) * (&fsun->fs)->fs_nrpos)) | |||
703 | [cbtorpos(&sblock, d)((&fsun->fs)->fs_nrpos <= 1 ? 0 : (((d) << (&fsun->fs)->fs_fsbtodb) % (&fsun->fs)-> fs_spc / (&fsun->fs)->fs_nsect * (&fsun->fs) ->fs_trackskew + ((d) << (&fsun->fs)->fs_fsbtodb ) % (&fsun->fs)->fs_spc % (&fsun->fs)->fs_nsect * (&fsun->fs)->fs_interleave) % (&fsun->fs) ->fs_nsect * (&fsun->fs)->fs_nrpos / (&fsun-> fs)->fs_npsect)]++; | |||
704 | } | |||
705 | } | |||
706 | } | |||
707 | if ((i = dupper % sblockfsun->fs.fs_frag)) { | |||
708 | acgcgun->cg.cg_frsum[sblockfsun->fs.fs_frag - i]++; | |||
709 | for (d = dupper + sblockfsun->fs.fs_frag - i; dupper < d; dupper++) { | |||
710 | setbit(cg_blksfree(&acg), dupper)(((((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff)))) [(dupper)>>3] |= 1<<((dupper)&(8 -1))); | |||
711 | acgcgun->cg.cg_cs.cs_nffree++; | |||
712 | } | |||
713 | } | |||
714 | for (d = dupper; | |||
715 | d + sblockfsun->fs.fs_frag <= acgcgun->cg.cg_ndblk; | |||
716 | d += sblockfsun->fs.fs_frag) { | |||
717 | blkno = d / sblockfsun->fs.fs_frag; | |||
718 | setblock(&sblockfsun->fs, cg_blksfree(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff))), blkno); | |||
719 | acgcgun->cg.cg_cs.cs_nbfree++; | |||
720 | if (Oflag <= 1) { | |||
721 | cg_blktot(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_btot) : ((int32_t *)((u_int8_t * )(&cgun->cg) + (&cgun->cg)->cg_btotoff)))[cbtocylno(&sblock, d)(((d) << (&fsun->fs)->fs_fsbtodb) / (&fsun ->fs)->fs_spc)]++; | |||
722 | cg_blks(&sblock, &acg, cbtocylno(&sblock, d))(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_b[(((d) << (&fsun-> fs)->fs_fsbtodb) / (&fsun->fs)->fs_spc)]) : ((int16_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_boff ) + ((((d) << (&fsun->fs)->fs_fsbtodb) / (& fsun->fs)->fs_spc)) * (&fsun->fs)->fs_nrpos)) | |||
723 | [cbtorpos(&sblock, d)((&fsun->fs)->fs_nrpos <= 1 ? 0 : (((d) << (&fsun->fs)->fs_fsbtodb) % (&fsun->fs)-> fs_spc / (&fsun->fs)->fs_nsect * (&fsun->fs) ->fs_trackskew + ((d) << (&fsun->fs)->fs_fsbtodb ) % (&fsun->fs)->fs_spc % (&fsun->fs)->fs_nsect * (&fsun->fs)->fs_interleave) % (&fsun->fs) ->fs_nsect * (&fsun->fs)->fs_nrpos / (&fsun-> fs)->fs_npsect)]++; | |||
724 | } | |||
725 | } | |||
726 | if (d < acgcgun->cg.cg_ndblk) { | |||
727 | acgcgun->cg.cg_frsum[acgcgun->cg.cg_ndblk - d]++; | |||
728 | for (; d < acgcgun->cg.cg_ndblk; d++) { | |||
729 | setbit(cg_blksfree(&acg), d)(((((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff)))) [(d)>>3] |= 1<<((d)&(8 -1))); | |||
730 | acgcgun->cg.cg_cs.cs_nffree++; | |||
731 | } | |||
732 | } | |||
733 | *cs = acgcgun->cg.cg_cs; | |||
734 | ||||
735 | /* | |||
736 | * Write out the duplicate superblock, the cylinder group map | |||
737 | * and two blocks worth of inodes in a single write. | |||
738 | */ | |||
739 | start = sblockfsun->fs.fs_bsize > SBLOCKSIZE8192 ? sblockfsun->fs.fs_bsize : SBLOCKSIZE8192; | |||
740 | ||||
741 | if (cg
| |||
742 | errx(42, "cg 0: summary info is too large to fit"); | |||
743 | ||||
744 | bcopy((char *)&acgcgun->cg, &iobuf[start], sblockfsun->fs.fs_cgsize); | |||
745 | start += sblockfsun->fs.fs_bsize; | |||
746 | dp1 = (struct ufs1_dinode *)(&iobuf[start]); | |||
747 | dp2 = (struct ufs2_dinode *)(&iobuf[start]); | |||
748 | for (i = MINIMUM(sblock.fs_ipg, 2 * INOPB(&sblock))(((fsun->fs.fs_ipg) < (2 * ((&fsun->fs)->fs_inopb ))) ? (fsun->fs.fs_ipg) : (2 * ((&fsun->fs)->fs_inopb ))); i != 0; i--) { | |||
749 | if (sblockfsun->fs.fs_magic == FS_UFS1_MAGIC0x011954) { | |||
750 | dp1->di_gen = arc4random(); | |||
751 | dp1++; | |||
752 | } else { | |||
753 | dp2->di_gen = arc4random(); | |||
754 | dp2++; | |||
755 | } | |||
756 | } | |||
757 | wtfs(fsbtodb(&sblock, cgsblock(&sblock, cg))((((((daddr_t)(&fsun->fs)->fs_fpg * (cg)) + (&fsun ->fs)->fs_cgoffset * ((cg) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_sblkno)) << (& fsun->fs)->fs_fsbtodb), iobufsize, iobuf); | |||
758 | ||||
759 | if (Oflag
| |||
760 | /* Initialize inodes for FFS1. */ | |||
761 | for (i = 2 * sblockfsun->fs.fs_frag; | |||
762 | i < sblockfsun->fs.fs_ipg / INOPF(&sblock)((&fsun->fs)->fs_inopb >> (&fsun->fs)-> fs_fragshift); | |||
| ||||
763 | i += sblockfsun->fs.fs_frag) { | |||
764 | dp1 = (struct ufs1_dinode *)(&iobuf[start]); | |||
765 | for (j = 0; j < INOPB(&sblock)((&fsun->fs)->fs_inopb); j++) { | |||
766 | dp1->di_gen = arc4random(); | |||
767 | dp1++; | |||
768 | } | |||
769 | wtfs(fsbtodb(&sblock, cgimin(&sblock, cg) + i)((((((daddr_t)(&fsun->fs)->fs_fpg * (cg)) + (&fsun ->fs)->fs_cgoffset * ((cg) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_iblkno) + i) << (&fsun->fs)->fs_fsbtodb), | |||
770 | sblockfsun->fs.fs_bsize, &iobuf[start]); | |||
771 | } | |||
772 | } | |||
773 | } | |||
774 | ||||
775 | #define PREDEFDIR2 2 | |||
776 | ||||
777 | struct direct root_dir[] = { | |||
778 | { ROOTINO((ufsino_t)2), sizeof(struct direct), DT_DIR4, 1, "." }, | |||
779 | { ROOTINO((ufsino_t)2), sizeof(struct direct), DT_DIR4, 2, ".." }, | |||
780 | }; | |||
781 | struct odirect { | |||
782 | u_int32_t d_ino; | |||
783 | u_int16_t d_reclen; | |||
784 | u_int16_t d_namlen; | |||
785 | u_char d_name[MAXNAMLEN255 + 1]; | |||
786 | } oroot_dir[] = { | |||
787 | { ROOTINO((ufsino_t)2), sizeof(struct direct), 1, "." }, | |||
788 | { ROOTINO((ufsino_t)2), sizeof(struct direct), 2, ".." }, | |||
789 | }; | |||
790 | ||||
791 | int | |||
792 | fsinit1(time_t utime, mode_t mfsmode, uid_t mfsuid, gid_t mfsgid) | |||
793 | { | |||
794 | union dinode node; | |||
795 | ||||
796 | /* | |||
797 | * Initialize the node | |||
798 | */ | |||
799 | memset(&node, 0, sizeof(node)); | |||
800 | node.dp1.di_atime = utime; | |||
801 | node.dp1.di_mtime = utime; | |||
802 | node.dp1.di_ctime = utime; | |||
803 | ||||
804 | /* | |||
805 | * Create the root directory. | |||
806 | */ | |||
807 | if (mfs) { | |||
808 | node.dp1.di_mode = IFDIR0040000 | mfsmode; | |||
809 | node.dp1.di_uid = mfsuid; | |||
810 | node.dp1.di_gid = mfsgid; | |||
811 | } else { | |||
812 | node.dp1.di_mode = IFDIR0040000 | UMASK0755; | |||
813 | node.dp1.di_uid = geteuid(); | |||
814 | node.dp1.di_gid = getegid(); | |||
815 | } | |||
816 | node.dp1.di_nlink = PREDEFDIR2; | |||
817 | if (Oflag == 0) | |||
818 | node.dp1.di_size = makedir((struct direct *)oroot_dir, | |||
819 | PREDEFDIR2); | |||
820 | else | |||
821 | node.dp1.di_size = makedir(root_dir, PREDEFDIR2); | |||
822 | node.dp1.di_db[0] = alloc(sblockfsun->fs.fs_fsize, node.dp1.di_mode); | |||
823 | if (node.dp1.di_db[0] == 0) | |||
824 | return (1); | |||
825 | ||||
826 | node.dp1.di_blocks = btodb(fragroundup(&sblock, node.dp1.di_size))(((((node.dp1.di_size) + (&fsun->fs)->fs_qfmask) & (&fsun->fs)->fs_fmask)) >> 9); | |||
827 | ||||
828 | wtfs(fsbtodb(&sblock, node.dp1.di_db[0])((node.dp1.di_db[0]) << (&fsun->fs)->fs_fsbtodb ), sblockfsun->fs.fs_fsize, iobuf); | |||
829 | iput(&node, ROOTINO((ufsino_t)2)); | |||
830 | ||||
831 | #ifdef notyet | |||
832 | /* | |||
833 | * Create the .snap directory. | |||
834 | */ | |||
835 | node.dp1.di_mode |= 020; | |||
836 | node.dp1.di_gid = gid; | |||
837 | node.dp1.di_nlink = SNAPLINKCNT; | |||
838 | node.dp1.di_size = makedir(snap_dir, SNAPLINKCNT); | |||
839 | ||||
840 | node.dp1.di_db[0] = alloc(sblockfsun->fs.fs_fsize, node.dp1.di_mode); | |||
841 | if (node.dp1.di_db[0] == 0) | |||
842 | return (1); | |||
843 | ||||
844 | node.dp1.di_blocks = btodb(fragroundup(&sblock, node.dp1.di_size))(((((node.dp1.di_size) + (&fsun->fs)->fs_qfmask) & (&fsun->fs)->fs_fmask)) >> 9); | |||
845 | ||||
846 | wtfs(fsbtodb(&sblock, node.dp1.di_db[0])((node.dp1.di_db[0]) << (&fsun->fs)->fs_fsbtodb ), sblockfsun->fs.fs_fsize, iobuf); | |||
847 | iput(&node, ROOTINO((ufsino_t)2) + 1); | |||
848 | #endif | |||
849 | return (0); | |||
850 | } | |||
851 | ||||
852 | int | |||
853 | fsinit2(time_t utime, mode_t mfsmode, uid_t mfsuid, gid_t mfsgid) | |||
854 | { | |||
855 | union dinode node; | |||
856 | ||||
857 | /* | |||
858 | * Initialize the node. | |||
859 | */ | |||
860 | memset(&node, 0, sizeof(node)); | |||
861 | node.dp2.di_atime = utime; | |||
862 | node.dp2.di_mtime = utime; | |||
863 | node.dp2.di_ctime = utime; | |||
864 | ||||
865 | /* | |||
866 | * Create the root directory. | |||
867 | */ | |||
868 | if (mfs) { | |||
869 | node.dp2.di_mode = IFDIR0040000 | mfsmode; | |||
870 | node.dp2.di_uid = mfsuid; | |||
871 | node.dp2.di_gid = mfsgid; | |||
872 | } else { | |||
873 | node.dp2.di_mode = IFDIR0040000 | UMASK0755; | |||
874 | node.dp2.di_uid = geteuid(); | |||
875 | node.dp2.di_gid = getegid(); | |||
876 | } | |||
877 | node.dp2.di_nlink = PREDEFDIR2; | |||
878 | node.dp2.di_size = makedir(root_dir, PREDEFDIR2); | |||
879 | ||||
880 | node.dp2.di_db[0] = alloc(sblockfsun->fs.fs_fsize, node.dp2.di_mode); | |||
881 | if (node.dp2.di_db[0] == 0) | |||
882 | return (1); | |||
883 | ||||
884 | node.dp2.di_blocks = btodb(fragroundup(&sblock, node.dp2.di_size))(((((node.dp2.di_size) + (&fsun->fs)->fs_qfmask) & (&fsun->fs)->fs_fmask)) >> 9); | |||
885 | ||||
886 | wtfs(fsbtodb(&sblock, node.dp2.di_db[0])((node.dp2.di_db[0]) << (&fsun->fs)->fs_fsbtodb ), sblockfsun->fs.fs_fsize, iobuf); | |||
887 | iput(&node, ROOTINO((ufsino_t)2)); | |||
888 | ||||
889 | #ifdef notyet | |||
890 | /* | |||
891 | * Create the .snap directory. | |||
892 | */ | |||
893 | node.dp2.di_mode |= 020; | |||
894 | node.dp2.di_gid = gid; | |||
895 | node.dp2.di_nlink = SNAPLINKCNT; | |||
896 | node.dp2.di_size = makedir(snap_dir, SNAPLINKCNT); | |||
897 | ||||
898 | node.dp2.di_db[0] = alloc(sblockfsun->fs.fs_fsize, node.dp2.di_mode); | |||
899 | if (node.dp2.di_db[0] == 0) | |||
900 | return (1); | |||
901 | ||||
902 | node.dp2.di_blocks = btodb(fragroundup(&sblock, node.dp2.di_size))(((((node.dp2.di_size) + (&fsun->fs)->fs_qfmask) & (&fsun->fs)->fs_fmask)) >> 9); | |||
903 | ||||
904 | wtfs(fsbtodb(&sblock, node.dp2.di_db[0])((node.dp2.di_db[0]) << (&fsun->fs)->fs_fsbtodb ), sblockfsun->fs.fs_fsize, iobuf); | |||
905 | iput(&node, ROOTINO((ufsino_t)2) + 1); | |||
906 | #endif | |||
907 | return (0); | |||
908 | } | |||
909 | ||||
910 | /* | |||
911 | * construct a set of directory entries in "buf". | |||
912 | * return size of directory. | |||
913 | */ | |||
914 | int | |||
915 | makedir(struct direct *protodir, int entries) | |||
916 | { | |||
917 | char *cp; | |||
918 | int i, spcleft; | |||
919 | ||||
920 | spcleft = DIRBLKSIZ(1 << 9); | |||
921 | for (cp = iobuf, i = 0; i < entries - 1; i++) { | |||
922 | protodir[i].d_reclen = DIRSIZ(0, &protodir[i])((0) ? ((sizeof(struct direct) - (255 +1)) + (((&protodir [i])->d_type+1 + 3) &~ 3)) : ((sizeof(struct direct) - (255 +1)) + (((&protodir[i])->d_namlen+1 + 3) &~ 3 ))); | |||
923 | memcpy(cp, &protodir[i], protodir[i].d_reclen); | |||
924 | cp += protodir[i].d_reclen; | |||
925 | spcleft -= protodir[i].d_reclen; | |||
926 | } | |||
927 | protodir[i].d_reclen = spcleft; | |||
928 | memcpy(cp, &protodir[i], DIRSIZ(0, &protodir[i])((0) ? ((sizeof(struct direct) - (255 +1)) + (((&protodir [i])->d_type+1 + 3) &~ 3)) : ((sizeof(struct direct) - (255 +1)) + (((&protodir[i])->d_namlen+1 + 3) &~ 3 )))); | |||
929 | return (DIRBLKSIZ(1 << 9)); | |||
930 | } | |||
931 | ||||
932 | /* | |||
933 | * allocate a block or frag | |||
934 | */ | |||
935 | daddr_t | |||
936 | alloc(int size, int mode) | |||
937 | { | |||
938 | int i, frag; | |||
939 | daddr_t d, blkno; | |||
940 | ||||
941 | rdfs(fsbtodb(&sblock, cgtod(&sblock, 0))((((((daddr_t)(&fsun->fs)->fs_fpg * (0)) + (&fsun ->fs)->fs_cgoffset * ((0) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_cblkno)) << (& fsun->fs)->fs_fsbtodb), sblockfsun->fs.fs_cgsize, | |||
942 | (char *)&acgcgun->cg); | |||
943 | if (acgcgun->cg.cg_magic != CG_MAGIC0x090255) { | |||
944 | warnx("cg 0: bad magic number"); | |||
945 | return (0); | |||
946 | } | |||
947 | if (acgcgun->cg.cg_cs.cs_nbfree == 0) { | |||
948 | warnx("first cylinder group ran out of space"); | |||
949 | return (0); | |||
950 | } | |||
951 | for (d = 0; d < acgcgun->cg.cg_ndblk; d += sblockfsun->fs.fs_frag) | |||
952 | if (isblock(&sblockfsun->fs, cg_blksfree(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff))), d / sblockfsun->fs.fs_frag)) | |||
953 | goto goth; | |||
954 | warnx("internal error: can't find block in cyl 0"); | |||
955 | return (0); | |||
956 | goth: | |||
957 | blkno = fragstoblks(&sblock, d)((d) >> (&fsun->fs)->fs_fragshift); | |||
958 | clrblock(&sblockfsun->fs, cg_blksfree(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff))), blkno); | |||
959 | acgcgun->cg.cg_cs.cs_nbfree--; | |||
960 | sblockfsun->fs.fs_cstotal.cs_nbfree--; | |||
961 | fscs[0].cs_nbfree--; | |||
962 | if (mode & IFDIR0040000) { | |||
963 | acgcgun->cg.cg_cs.cs_ndir++; | |||
964 | sblockfsun->fs.fs_cstotal.cs_ndir++; | |||
965 | fscs[0].cs_ndir++; | |||
966 | } | |||
967 | if (Oflag <= 1) { | |||
968 | cg_blktot(&acg)(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_btot) : ((int32_t *)((u_int8_t * )(&cgun->cg) + (&cgun->cg)->cg_btotoff)))[cbtocylno(&sblock, d)(((d) << (&fsun->fs)->fs_fsbtodb) / (&fsun ->fs)->fs_spc)]--; | |||
969 | cg_blks(&sblock, &acg, cbtocylno(&sblock, d))(((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_b[(((d) << (&fsun-> fs)->fs_fsbtodb) / (&fsun->fs)->fs_spc)]) : ((int16_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_boff ) + ((((d) << (&fsun->fs)->fs_fsbtodb) / (& fsun->fs)->fs_spc)) * (&fsun->fs)->fs_nrpos)) | |||
970 | [cbtorpos(&sblock, d)((&fsun->fs)->fs_nrpos <= 1 ? 0 : (((d) << (&fsun->fs)->fs_fsbtodb) % (&fsun->fs)-> fs_spc / (&fsun->fs)->fs_nsect * (&fsun->fs) ->fs_trackskew + ((d) << (&fsun->fs)->fs_fsbtodb ) % (&fsun->fs)->fs_spc % (&fsun->fs)->fs_nsect * (&fsun->fs)->fs_interleave) % (&fsun->fs) ->fs_nsect * (&fsun->fs)->fs_nrpos / (&fsun-> fs)->fs_npsect)]--; | |||
971 | } | |||
972 | if (size != sblockfsun->fs.fs_bsize) { | |||
973 | frag = howmany(size, sblock.fs_fsize)(((size) + ((fsun->fs.fs_fsize) - 1)) / (fsun->fs.fs_fsize )); | |||
974 | fscs[0].cs_nffree += sblockfsun->fs.fs_frag - frag; | |||
975 | sblockfsun->fs.fs_cstotal.cs_nffree += sblockfsun->fs.fs_frag - frag; | |||
976 | acgcgun->cg.cg_cs.cs_nffree += sblockfsun->fs.fs_frag - frag; | |||
977 | acgcgun->cg.cg_frsum[sblockfsun->fs.fs_frag - frag]++; | |||
978 | for (i = frag; i < sblockfsun->fs.fs_frag; i++) | |||
979 | setbit(cg_blksfree(&acg), d + i)(((((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_free) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_freeoff)))) [(d + i)>>3] |= 1<<((d + i)&(8 -1))); | |||
980 | } | |||
981 | wtfs(fsbtodb(&sblock, cgtod(&sblock, 0))((((((daddr_t)(&fsun->fs)->fs_fpg * (0)) + (&fsun ->fs)->fs_cgoffset * ((0) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_cblkno)) << (& fsun->fs)->fs_fsbtodb), sblockfsun->fs.fs_cgsize, | |||
982 | (char *)&acgcgun->cg); | |||
983 | return (d); | |||
984 | } | |||
985 | ||||
986 | /* | |||
987 | * Allocate an inode on the disk | |||
988 | */ | |||
989 | void | |||
990 | iput(union dinode *ip, ino_t ino) | |||
991 | { | |||
992 | daddr_t d; | |||
993 | ||||
994 | if (Oflag <= 1) | |||
995 | ip->dp1.di_gen = arc4random(); | |||
996 | else | |||
997 | ip->dp2.di_gen = arc4random(); | |||
998 | ||||
999 | rdfs(fsbtodb(&sblock, cgtod(&sblock, 0))((((((daddr_t)(&fsun->fs)->fs_fpg * (0)) + (&fsun ->fs)->fs_cgoffset * ((0) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_cblkno)) << (& fsun->fs)->fs_fsbtodb), sblockfsun->fs.fs_cgsize, | |||
1000 | (char *)&acgcgun->cg); | |||
1001 | if (acgcgun->cg.cg_magic != CG_MAGIC0x090255) | |||
1002 | errx(41, "cg 0: bad magic number"); | |||
1003 | ||||
1004 | acgcgun->cg.cg_cs.cs_nifree--; | |||
1005 | setbit(cg_inosused(&acg), ino)(((((&cgun->cg)->cg_magic != 0x090255) ? (((struct ocg *)(&cgun->cg))->cg_iused) : ((u_int8_t *)((u_int8_t *)(&cgun->cg) + (&cgun->cg)->cg_iusedoff))) )[(ino)>>3] |= 1<<((ino)&(8 -1))); | |||
1006 | ||||
1007 | wtfs(fsbtodb(&sblock, cgtod(&sblock, 0))((((((daddr_t)(&fsun->fs)->fs_fpg * (0)) + (&fsun ->fs)->fs_cgoffset * ((0) & ~((&fsun->fs)-> fs_cgmask))) + (&fsun->fs)->fs_cblkno)) << (& fsun->fs)->fs_fsbtodb), sblockfsun->fs.fs_cgsize, | |||
1008 | (char *)&acgcgun->cg); | |||
1009 | ||||
1010 | sblockfsun->fs.fs_cstotal.cs_nifree--; | |||
1011 | fscs[0].cs_nifree--; | |||
1012 | if (ino >= sblockfsun->fs.fs_ipg * sblockfsun->fs.fs_ncg) | |||
1013 | errx(32, "fsinit: inode value %llu out of range", | |||
1014 | (unsigned long long)ino); | |||
1015 | d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino))((((daddr_t)(((((daddr_t)(&fsun->fs)->fs_fpg * (((ino ) / (&fsun->fs)->fs_ipg))) + (&fsun->fs)-> fs_cgoffset * ((((ino) / (&fsun->fs)->fs_ipg)) & ~((&fsun->fs)->fs_cgmask))) + (&fsun->fs)-> fs_iblkno) + ((((((ino) % (&fsun->fs)->fs_ipg) / (( &fsun->fs)->fs_inopb))) << ((&fsun->fs ))->fs_fragshift))))) << (&fsun->fs)->fs_fsbtodb ); | |||
1016 | rdfs(d, sblockfsun->fs.fs_bsize, iobuf); | |||
1017 | ||||
1018 | if (Oflag <= 1) | |||
1019 | ((struct ufs1_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)((ino) % ((&fsun->fs)->fs_inopb))] = | |||
1020 | ip->dp1; | |||
1021 | else | |||
1022 | ((struct ufs2_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)((ino) % ((&fsun->fs)->fs_inopb))] = | |||
1023 | ip->dp2; | |||
1024 | ||||
1025 | wtfs(d, sblockfsun->fs.fs_bsize, iobuf); | |||
1026 | } | |||
1027 | ||||
1028 | /* | |||
1029 | * read a block from the file system | |||
1030 | */ | |||
1031 | void | |||
1032 | rdfs(daddr_t bno, int size, void *bf) | |||
1033 | { | |||
1034 | int n; | |||
1035 | ||||
1036 | if (mfs) { | |||
1037 | memcpy(bf, membase + bno * DEV_BSIZE(1 << 9), size); | |||
1038 | return; | |||
1039 | } | |||
1040 | n = pread(fsi, bf, size, (off_t)bno * DEV_BSIZE(1 << 9)); | |||
1041 | if (n != size) { | |||
1042 | err(34, "rdfs: read error on block %lld", (long long)bno); | |||
1043 | } | |||
1044 | } | |||
1045 | ||||
1046 | /* | |||
1047 | * write a block to the file system | |||
1048 | */ | |||
1049 | void | |||
1050 | wtfs(daddr_t bno, int size, void *bf) | |||
1051 | { | |||
1052 | int n; | |||
1053 | ||||
1054 | if (mfs) { | |||
1055 | memcpy(membase + bno * DEV_BSIZE(1 << 9), bf, size); | |||
1056 | return; | |||
1057 | } | |||
1058 | if (Nflag) | |||
1059 | return; | |||
1060 | n = pwrite(fso, bf, size, (off_t)bno * DEV_BSIZE(1 << 9)); | |||
1061 | if (n != size) { | |||
1062 | err(36, "wtfs: write error on block %lld", (long long)bno); | |||
1063 | } | |||
1064 | } | |||
1065 | ||||
1066 | /* | |||
1067 | * check if a block is available | |||
1068 | */ | |||
1069 | int | |||
1070 | isblock(struct fs *fs, unsigned char *cp, int h) | |||
1071 | { | |||
1072 | unsigned char mask; | |||
1073 | ||||
1074 | switch (fs->fs_frag) { | |||
1075 | case 8: | |||
1076 | return (cp[h] == 0xff); | |||
1077 | case 4: | |||
1078 | mask = 0x0f << ((h & 0x1) << 2); | |||
1079 | return ((cp[h >> 1] & mask) == mask); | |||
1080 | case 2: | |||
1081 | mask = 0x03 << ((h & 0x3) << 1); | |||
1082 | return ((cp[h >> 2] & mask) == mask); | |||
1083 | case 1: | |||
1084 | mask = 0x01 << (h & 0x7); | |||
1085 | return ((cp[h >> 3] & mask) == mask); | |||
1086 | default: | |||
1087 | #ifdef STANDALONE | |||
1088 | printf("isblock bad fs_frag %d\n", fs->fs_frag); | |||
1089 | #else | |||
1090 | warnx("isblock bad fs_frag %d", fs->fs_frag); | |||
1091 | #endif | |||
1092 | return (0); | |||
1093 | } | |||
1094 | } | |||
1095 | ||||
1096 | /* | |||
1097 | * take a block out of the map | |||
1098 | */ | |||
1099 | void | |||
1100 | clrblock(struct fs *fs, unsigned char *cp, int h) | |||
1101 | { | |||
1102 | switch ((fs)->fs_frag) { | |||
1103 | case 8: | |||
1104 | cp[h] = 0; | |||
1105 | return; | |||
1106 | case 4: | |||
1107 | cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); | |||
1108 | return; | |||
1109 | case 2: | |||
1110 | cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); | |||
1111 | return; | |||
1112 | case 1: | |||
1113 | cp[h >> 3] &= ~(0x01 << (h & 0x7)); | |||
1114 | return; | |||
1115 | default: | |||
1116 | #ifdef STANDALONE | |||
1117 | printf("clrblock bad fs_frag %d\n", fs->fs_frag); | |||
1118 | #else | |||
1119 | warnx("clrblock bad fs_frag %d", fs->fs_frag); | |||
1120 | #endif | |||
1121 | return; | |||
1122 | } | |||
1123 | } | |||
1124 | ||||
1125 | /* | |||
1126 | * put a block into the map | |||
1127 | */ | |||
1128 | void | |||
1129 | setblock(struct fs *fs, unsigned char *cp, int h) | |||
1130 | { | |||
1131 | switch (fs->fs_frag) { | |||
1132 | case 8: | |||
1133 | cp[h] = 0xff; | |||
1134 | return; | |||
1135 | case 4: | |||
1136 | cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); | |||
1137 | return; | |||
1138 | case 2: | |||
1139 | cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); | |||
1140 | return; | |||
1141 | case 1: | |||
1142 | cp[h >> 3] |= (0x01 << (h & 0x7)); | |||
1143 | return; | |||
1144 | default: | |||
1145 | #ifdef STANDALONE | |||
1146 | printf("setblock bad fs_frag %d\n", fs->fs_frag); | |||
1147 | #else | |||
1148 | warnx("setblock bad fs_frag %d", fs->fs_frag); | |||
1149 | #endif | |||
1150 | return; | |||
1151 | } | |||
1152 | } | |||
1153 | ||||
1154 | /* | |||
1155 | * Determine the number of characters in a | |||
1156 | * single line. | |||
1157 | */ | |||
1158 | static int | |||
1159 | charsperline(void) | |||
1160 | { | |||
1161 | int columns; | |||
1162 | char *cp; | |||
1163 | struct winsize ws; | |||
1164 | ||||
1165 | columns = 0; | |||
1166 | if ((cp = getenv("COLUMNS")) != NULL((void *)0)) | |||
1167 | columns = strtonum(cp, 1, INT_MAX2147483647, NULL((void *)0)); | |||
1168 | if (columns == 0 && ioctl(STDOUT_FILENO1, TIOCGWINSZ((unsigned long)0x40000000 | ((sizeof(struct winsize) & 0x1fff ) << 16) | ((('t')) << 8) | ((104))), &ws) == 0 && | |||
1169 | ws.ws_col > 0) | |||
1170 | columns = ws.ws_col; | |||
1171 | if (columns == 0) | |||
1172 | columns = 80; | |||
1173 | ||||
1174 | return columns; | |||
1175 | } | |||
1176 | ||||
1177 | static int | |||
1178 | ilog2(int val) | |||
1179 | { | |||
1180 | int n; | |||
1181 | ||||
1182 | for (n = 0; n < sizeof(n) * CHAR_BIT8; n++) | |||
1183 | if (1 << n == val) | |||
1184 | return (n); | |||
1185 | ||||
1186 | errx(1, "ilog2: %d is not a power of 2\n", val); | |||
1187 | } | |||
1188 | ||||
1189 | struct inoinfo { | |||
1190 | struct inoinfo *i_nexthash; /* next entry in hash chain */ | |||
1191 | struct inoinfo *i_child, *i_sibling, *i_parentp; | |||
1192 | size_t i_isize; /* size of inode */ | |||
1193 | ino_t i_number; /* inode number of this entry */ | |||
1194 | ino_t i_parent; /* inode number of parent */ | |||
1195 | ||||
1196 | ino_t i_dotdot; /* inode number of `..' */ | |||
1197 | u_int i_numblks; /* size of block array in bytes */ | |||
1198 | daddr_t i_blks[1]; /* actually longer */ | |||
1199 | }; | |||
1200 | ||||
1201 | static void | |||
1202 | checksz(void) | |||
1203 | { | |||
1204 | unsigned long long allocate, maxino, maxfsblock, ndir, bound; | |||
1205 | extern int64_t physmem; | |||
1206 | struct rlimit datasz; | |||
1207 | ||||
1208 | if (getrlimit(RLIMIT_DATA2, &datasz) != 0) | |||
1209 | err(1, "can't get rlimit"); | |||
1210 | ||||
1211 | bound = MINIMUM(datasz.rlim_max, physmem)(((datasz.rlim_max) < (physmem)) ? (datasz.rlim_max) : (physmem )); | |||
1212 | ||||
1213 | allocate = 0; | |||
1214 | maxino = sblockfsun->fs.fs_ncg * (unsigned long long)sblockfsun->fs.fs_ipg; | |||
1215 | maxfsblock = sblockfsun->fs.fs_size; | |||
1216 | ndir = maxino / avgfilesperdir; | |||
1217 | ||||
1218 | allocate += roundup(howmany(maxfsblock, NBBY), sizeof(int16_t))(((((((maxfsblock) + ((8) - 1)) / (8)))+((sizeof(int16_t))-1) )/(sizeof(int16_t)))*(sizeof(int16_t))); | |||
1219 | allocate += (maxino + 1) * 3; | |||
1220 | allocate += sblockfsun->fs.fs_ncg * sizeof(long); | |||
1221 | allocate += (MAXIMUM(ndir, 128)(((ndir) > (128)) ? (ndir) : (128)) + 10) * sizeof(struct inoinfo); | |||
1222 | allocate += MAXIMUM(ndir, 128)(((ndir) > (128)) ? (ndir) : (128)) * sizeof(struct inoinfo); | |||
1223 | ||||
1224 | if (allocate > bound) | |||
1225 | warnx("warning: fsck_ffs will need %lluMB; " | |||
1226 | "min(ulimit -dH,physmem) is %lluMB", | |||
1227 | allocate / (1024ULL * 1024ULL), | |||
1228 | bound / (1024ULL * 1024ULL)); | |||
1229 | } |