Annotation of src/sbin/fsck_ext2fs/setup.c, Revision 1.16
1.16 ! dsl 1: /* $NetBSD: setup.c,v 1.15 2004/03/22 19:46:53 bouyer Exp $ */
1.1 bouyer 2:
3: /*
4: * Copyright (c) 1980, 1986, 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.
1.13 agc 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) 1997 Manuel Bouyer.
34: *
35: * Redistribution and use in source and binary forms, with or without
36: * modification, are permitted provided that the following conditions
37: * are met:
38: * 1. Redistributions of source code must retain the above copyright
39: * notice, this list of conditions and the following disclaimer.
40: * 2. Redistributions in binary form must reproduce the above copyright
41: * notice, this list of conditions and the following disclaimer in the
42: * documentation and/or other materials provided with the distribution.
1.1 bouyer 43: * 3. All advertising materials mentioning features or use of this software
44: * must display the following acknowledgement:
1.14 bouyer 45: * This product includes software developed by Manuel Bouyer.
46: * 4. The name of the author may not be used to endorse or promote products
47: * derived from this software without specific prior written permission.
1.1 bouyer 48: *
1.15 bouyer 49: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.1 bouyer 59: */
60:
1.4 lukem 61: #include <sys/cdefs.h>
1.1 bouyer 62: #ifndef lint
63: #if 0
64: static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94";
65: #else
1.16 ! dsl 66: __RCSID("$NetBSD: setup.c,v 1.15 2004/03/22 19:46:53 bouyer Exp $");
1.1 bouyer 67: #endif
68: #endif /* not lint */
69:
1.8 christos 70: #define FSTYPENAMES
1.1 bouyer 71: #include <sys/param.h>
72: #include <sys/time.h>
73: #include <ufs/ext2fs/ext2fs_dinode.h>
74: #include <ufs/ext2fs/ext2fs.h>
75: #include <sys/stat.h>
76: #include <sys/ioctl.h>
77: #include <sys/disklabel.h>
78: #include <sys/file.h>
79:
80: #include <errno.h>
81: #include <stdio.h>
82: #include <stdlib.h>
83: #include <string.h>
84: #include <ctype.h>
85:
86: #include "fsck.h"
87: #include "extern.h"
88: #include "fsutil.h"
89:
90: #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
91:
92: void badsb __P((int, char *));
1.7 mycroft 93: int calcsb __P((const char *, int, struct m_ext2fs *));
94: static struct disklabel *getdisklabel __P((const char *, int));
1.1 bouyer 95: static int readsb __P((int));
96:
97: int
98: setup(dev)
1.7 mycroft 99: const char *dev;
1.1 bouyer 100: {
1.4 lukem 101: long cg, asked, i;
1.1 bouyer 102: long bmapsize;
103: struct disklabel *lp;
104: off_t sizepb;
105: struct stat statb;
106: struct m_ext2fs proto;
107: int doskipclean;
108: u_int64_t maxfilesize;
109:
110: havesb = 0;
111: fswritefd = -1;
112: doskipclean = skipclean;
113: if (stat(dev, &statb) < 0) {
114: printf("Can't stat %s: %s\n", dev, strerror(errno));
115: return (0);
116: }
117: if (!S_ISCHR(statb.st_mode)) {
118: pfatal("%s is not a character device", dev);
119: if (reply("CONTINUE") == 0)
120: return (0);
121: }
122: if ((fsreadfd = open(dev, O_RDONLY)) < 0) {
123: printf("Can't open %s: %s\n", dev, strerror(errno));
124: return (0);
125: }
126: if (preen == 0)
127: printf("** %s", dev);
128: if (nflag || (fswritefd = open(dev, O_WRONLY)) < 0) {
129: fswritefd = -1;
130: if (preen)
131: pfatal("NO WRITE ACCESS");
132: printf(" (NO WRITE)");
133: }
134: if (preen == 0)
135: printf("\n");
136: fsmodified = 0;
137: lfdir = 0;
138: initbarea(&sblk);
139: initbarea(&asblk);
1.6 bouyer 140: sblk.b_un.b_buf = malloc(SBSIZE);
141: asblk.b_un.b_buf = malloc(SBSIZE);
1.1 bouyer 142: if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
143: errexit("cannot allocate space for superblock\n");
144: if ((lp = getdisklabel((char *)NULL, fsreadfd)) != NULL)
145: dev_bsize = secsize = lp->d_secsize;
146: else
147: dev_bsize = secsize = DEV_BSIZE;
148: /*
149: * Read in the superblock, looking for alternates if necessary
150: */
151: if (readsb(1) == 0) {
152: if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
153: return(0);
154: if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
155: return (0);
156: for (cg = 1; cg < proto.e2fs_ncg; cg++) {
157: bflag = fsbtodb(&proto,
158: cg * proto.e2fs.e2fs_bpg + proto.e2fs.e2fs_first_dblock);
159: if (readsb(0) != 0)
160: break;
161: }
162: if (cg >= proto.e2fs_ncg) {
163: printf("%s %s\n%s %s\n%s %s\n",
164: "SEARCH FOR ALTERNATE SUPER-BLOCK",
165: "FAILED. YOU MUST USE THE",
166: "-b OPTION TO FSCK_FFS TO SPECIFY THE",
167: "LOCATION OF AN ALTERNATE",
168: "SUPER-BLOCK TO SUPPLY NEEDED",
169: "INFORMATION; SEE fsck_ext2fs(8).");
170: return(0);
171: }
172: doskipclean = 0;
173: pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
174: }
175: if (debug)
176: printf("state = %d\n", sblock.e2fs.e2fs_state);
177: if (sblock.e2fs.e2fs_state == E2FS_ISCLEAN) {
178: if (doskipclean) {
179: pwarn("%sile system is clean; not checking\n",
180: preen ? "f" : "** F");
181: return (-1);
182: }
183: if (!preen)
184: pwarn("** File system is already clean\n");
185: }
186: maxfsblock = sblock.e2fs.e2fs_bcount;
187: maxino = sblock.e2fs_ncg * sblock.e2fs.e2fs_ipg;
188: sizepb = sblock.e2fs_bsize;
189: maxfilesize = sblock.e2fs_bsize * NDADDR - 1;
190: for (i = 0; i < NIADDR; i++) {
191: sizepb *= NINDIR(&sblock);
192: maxfilesize += sizepb;
193: }
194: /*
195: * Check and potentially fix certain fields in the super block.
196: */
197: if ((sblock.e2fs.e2fs_rbcount < 0) ||
198: (sblock.e2fs.e2fs_rbcount > sblock.e2fs.e2fs_bcount)) {
199: pfatal("IMPOSSIBLE RESERVED BLOCK COUNT=%d IN SUPERBLOCK",
200: sblock.e2fs.e2fs_rbcount);
201: if (reply("SET TO DEFAULT") == 1) {
202: sblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_bcount * 0.1;
203: sbdirty();
1.6 bouyer 204: dirty(&asblk);
1.1 bouyer 205: }
206: }
207: if (sblock.e2fs.e2fs_bpg != sblock.e2fs.e2fs_fpg) {
208: pfatal("WRONG FPG=%d (BPG=%d) IN SUPERBLOCK",
209: sblock.e2fs.e2fs_fpg, sblock.e2fs.e2fs_bpg);
210: return 0;
211: }
212: if (asblk.b_dirty && !bflag) {
1.6 bouyer 213: copyback_sb(&asblk);
1.1 bouyer 214: flush(fswritefd, &asblk);
215: }
216: /*
217: * read in the summary info.
218: */
219:
220: sblock.e2fs_gd = malloc(sblock.e2fs_ngdb * sblock.e2fs_bsize);
1.9 bouyer 221: if (sblock.e2fs_gd == NULL)
222: errexit("out of memory\n");
1.1 bouyer 223: asked = 0;
224: for (i=0; i < sblock.e2fs_ngdb; i++) {
225: if (bread(fsreadfd,(char *)
226: &sblock.e2fs_gd[i* sblock.e2fs_bsize / sizeof(struct ext2_gd)],
227: fsbtodb(&sblock, ((sblock.e2fs_bsize>1024)?0:1)+i+1),
228: sblock.e2fs_bsize) != 0 && !asked) {
229: pfatal("BAD SUMMARY INFORMATION");
230: if (reply("CONTINUE") == 0)
231: errexit("%s\n", "");
232: asked++;
233: }
234: }
235: /*
236: * allocate and initialize the necessary maps
237: */
238: bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(int16_t));
239: blockmap = calloc((unsigned)bmapsize, sizeof (char));
240: if (blockmap == NULL) {
241: printf("cannot alloc %u bytes for blockmap\n",
242: (unsigned)bmapsize);
243: goto badsblabel;
244: }
245: statemap = calloc((unsigned)(maxino + 2), sizeof(char));
246: if (statemap == NULL) {
247: printf("cannot alloc %u bytes for statemap\n",
248: (unsigned)(maxino + 1));
249: goto badsblabel;
250: }
1.11 bouyer 251: typemap = calloc((unsigned)(maxino + 1), sizeof(char));
252: if (typemap == NULL) {
253: printf("cannot alloc %u bytes for typemap\n",
254: (unsigned)(maxino + 1));
255: goto badsblabel;
256: }
1.1 bouyer 257: lncntp = (int16_t *)calloc((unsigned)(maxino + 1), sizeof(int16_t));
258: if (lncntp == NULL) {
259: printf("cannot alloc %u bytes for lncntp\n",
1.5 mrg 260: (unsigned)((maxino + 1) * sizeof(int16_t)));
1.1 bouyer 261: goto badsblabel;
262: }
263: for (numdirs = 0, cg = 0; cg < sblock.e2fs_ncg; cg++) {
1.6 bouyer 264: numdirs += fs2h16(sblock.e2fs_gd[cg].ext2bgd_ndirs);
1.1 bouyer 265: }
266: inplast = 0;
267: listmax = numdirs + 10;
268: inpsort = (struct inoinfo **)calloc((unsigned)listmax,
269: sizeof(struct inoinfo *));
270: inphead = (struct inoinfo **)calloc((unsigned)numdirs,
271: sizeof(struct inoinfo *));
272: if (inpsort == NULL || inphead == NULL) {
273: printf("cannot alloc %u bytes for inphead\n",
1.5 mrg 274: (unsigned)(numdirs * sizeof(struct inoinfo *)));
1.1 bouyer 275: goto badsblabel;
276: }
277: bufinit();
278: return (1);
279:
280: badsblabel:
281: ckfini(0);
282: return (0);
283: }
284:
285: /*
1.6 bouyer 286: * Read in the super block and its summary info, convert to host byte order.
1.1 bouyer 287: */
288: static int
289: readsb(listerr)
290: int listerr;
291: {
292: daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
293:
1.6 bouyer 294: if (bread(fsreadfd, (char *)sblk.b_un.b_fs, super, (long)SBSIZE) != 0)
1.1 bouyer 295: return (0);
296: sblk.b_bno = super;
297: sblk.b_size = SBSIZE;
1.6 bouyer 298:
299: /* Copy the superblock in memory */
1.12 bouyer 300: e2fs_sbload(sblk.b_un.b_fs, &sblock.e2fs);
1.6 bouyer 301:
1.1 bouyer 302: /*
303: * run a few consistency checks of the super block
304: */
305: if (sblock.e2fs.e2fs_magic != E2FS_MAGIC) {
306: badsb(listerr, "MAGIC NUMBER WRONG"); return (0);
307: }
308: if (sblock.e2fs.e2fs_log_bsize > 2) {
309: badsb(listerr, "BAD LOG_BSIZE"); return (0);
310: }
311:
312: /* compute the dynamic fields of the in-memory sb */
313: /* compute dynamic sb infos */
314: sblock.e2fs_ncg =
315: howmany(sblock.e2fs.e2fs_bcount - sblock.e2fs.e2fs_first_dblock,
316: sblock.e2fs.e2fs_bpg);
317: /* XXX assume hw bsize = 512 */
318: sblock.e2fs_fsbtodb = sblock.e2fs.e2fs_log_bsize + 1;
319: sblock.e2fs_bsize = 1024 << sblock.e2fs.e2fs_log_bsize;
320: sblock.e2fs_bshift = LOG_MINBSIZE + sblock.e2fs.e2fs_log_bsize;
321: sblock.e2fs_qbmask = sblock.e2fs_bsize - 1;
322: sblock.e2fs_bmask = ~sblock.e2fs_qbmask;
323: sblock.e2fs_ngdb = howmany(sblock.e2fs_ncg,
324: sblock.e2fs_bsize / sizeof(struct ext2_gd));
325: sblock.e2fs_ipb = sblock.e2fs_bsize / sizeof(struct ext2fs_dinode);
326: sblock.e2fs_itpg = sblock.e2fs.e2fs_ipg/sblock.e2fs_ipb;
327:
328: /*
329: * Compute block size that the filesystem is based on,
330: * according to fsbtodb, and adjust superblock block number
331: * so we can tell if this is an alternate later.
332: */
333: super *= dev_bsize;
334: dev_bsize = sblock.e2fs_bsize / fsbtodb(&sblock, 1);
335: sblk.b_bno = super / dev_bsize;
1.6 bouyer 336:
337: getblk(&asblk, 1 * sblock.e2fs.e2fs_bpg + sblock.e2fs.e2fs_first_dblock,
338: (long)SBSIZE);
339: if (asblk.b_errs)
340: return (0);
1.1 bouyer 341: if (bflag) {
342: havesb = 1;
343: return (1);
344: }
345:
346: /*
347: * Set all possible fields that could differ, then do check
348: * of whole super block against an alternate super block.
349: * When an alternate super-block is specified this check is skipped.
350: */
1.6 bouyer 351: asblk.b_un.b_fs->e2fs_rbcount = sblk.b_un.b_fs->e2fs_rbcount;
352: asblk.b_un.b_fs->e2fs_fbcount = sblk.b_un.b_fs->e2fs_fbcount;
353: asblk.b_un.b_fs->e2fs_ficount = sblk.b_un.b_fs->e2fs_ficount;
354: asblk.b_un.b_fs->e2fs_mtime = sblk.b_un.b_fs->e2fs_mtime;
355: asblk.b_un.b_fs->e2fs_wtime = sblk.b_un.b_fs->e2fs_wtime;
356: asblk.b_un.b_fs->e2fs_mnt_count = sblk.b_un.b_fs->e2fs_mnt_count;
357: asblk.b_un.b_fs->e2fs_max_mnt_count = sblk.b_un.b_fs->e2fs_max_mnt_count;
358: asblk.b_un.b_fs->e2fs_state = sblk.b_un.b_fs->e2fs_state;
359: asblk.b_un.b_fs->e2fs_beh = sblk.b_un.b_fs->e2fs_beh;
360: asblk.b_un.b_fs->e2fs_lastfsck = sblk.b_un.b_fs->e2fs_lastfsck;
361: asblk.b_un.b_fs->e2fs_fsckintv = sblk.b_un.b_fs->e2fs_fsckintv;
362: asblk.b_un.b_fs->e2fs_ruid = sblk.b_un.b_fs->e2fs_ruid;
363: asblk.b_un.b_fs->e2fs_rgid = sblk.b_un.b_fs->e2fs_rgid;
1.10 bouyer 364: asblk.b_un.b_fs->e2fs_block_group_nr =
365: sblk.b_un.b_fs->e2fs_block_group_nr;
1.12 bouyer 366: if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
367: ((sblock.e2fs.e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) ||
368: (sblock.e2fs.e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP))) {
1.10 bouyer 369: if (debug) {
370: printf("compat 0x%08x, incompat 0x%08x, compat_ro "
371: "0x%08x\n",
1.12 bouyer 372: sblock.e2fs.e2fs_features_compat,
373: sblock.e2fs.e2fs_features_incompat,
374: sblock.e2fs.e2fs_features_rocompat);
1.10 bouyer 375: }
1.11 bouyer 376: badsb(listerr,"INCOMPATIBLE FEATURE BITS IN SUPER BLOCK");
1.10 bouyer 377: return 0;
378: }
1.6 bouyer 379: if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) {
1.1 bouyer 380: if (debug) {
1.6 bouyer 381: u_int32_t *nlp, *olp, *endlp;
1.1 bouyer 382:
383: printf("superblock mismatches\n");
1.6 bouyer 384: nlp = (u_int32_t *)asblk.b_un.b_fs;
385: olp = (u_int32_t *)sblk.b_un.b_fs;
1.1 bouyer 386: endlp = olp + (SBSIZE / sizeof *olp);
387: for ( ; olp < endlp; olp++, nlp++) {
388: if (*olp == *nlp)
389: continue;
1.5 mrg 390: printf("offset %ld, original %ld, alternate %ld\n",
1.6 bouyer 391: (long)(olp - (u_int32_t *)sblk.b_un.b_fs),
392: (long)fs2h32(*olp),
393: (long)fs2h32(*nlp));
1.1 bouyer 394: }
395: }
396: badsb(listerr,
397: "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
398: return (0);
399: }
400: havesb = 1;
401: return (1);
402: }
403:
404: void
1.6 bouyer 405: copyback_sb(bp)
406: struct bufarea *bp;
407: {
408: /* Copy the in-memory superblock back to buffer */
409: bp->b_un.b_fs->e2fs_icount = fs2h32(sblock.e2fs.e2fs_icount);
410: bp->b_un.b_fs->e2fs_bcount = fs2h32(sblock.e2fs.e2fs_bcount);
411: bp->b_un.b_fs->e2fs_rbcount = fs2h32(sblock.e2fs.e2fs_rbcount);
412: bp->b_un.b_fs->e2fs_fbcount = fs2h32(sblock.e2fs.e2fs_fbcount);
413: bp->b_un.b_fs->e2fs_ficount = fs2h32(sblock.e2fs.e2fs_ficount);
414: bp->b_un.b_fs->e2fs_first_dblock =
1.12 bouyer 415: fs2h32(sblock.e2fs.e2fs_first_dblock);
1.6 bouyer 416: bp->b_un.b_fs->e2fs_log_bsize = fs2h32(sblock.e2fs.e2fs_log_bsize);
417: bp->b_un.b_fs->e2fs_fsize = fs2h32(sblock.e2fs.e2fs_fsize);
418: bp->b_un.b_fs->e2fs_bpg = fs2h32(sblock.e2fs.e2fs_bpg);
419: bp->b_un.b_fs->e2fs_fpg = fs2h32(sblock.e2fs.e2fs_fpg);
420: bp->b_un.b_fs->e2fs_ipg = fs2h32(sblock.e2fs.e2fs_ipg);
421: bp->b_un.b_fs->e2fs_mtime = fs2h32(sblock.e2fs.e2fs_mtime);
422: bp->b_un.b_fs->e2fs_wtime = fs2h32(sblock.e2fs.e2fs_wtime);
423: bp->b_un.b_fs->e2fs_lastfsck = fs2h32(sblock.e2fs.e2fs_lastfsck);
424: bp->b_un.b_fs->e2fs_fsckintv = fs2h32(sblock.e2fs.e2fs_fsckintv);
425: bp->b_un.b_fs->e2fs_creator = fs2h32(sblock.e2fs.e2fs_creator);
426: bp->b_un.b_fs->e2fs_rev = fs2h32(sblock.e2fs.e2fs_rev);
427: bp->b_un.b_fs->e2fs_mnt_count = fs2h16(sblock.e2fs.e2fs_mnt_count);
428: bp->b_un.b_fs->e2fs_max_mnt_count =
1.12 bouyer 429: fs2h16(sblock.e2fs.e2fs_max_mnt_count);
1.6 bouyer 430: bp->b_un.b_fs->e2fs_magic = fs2h16(sblock.e2fs.e2fs_magic);
431: bp->b_un.b_fs->e2fs_state = fs2h16(sblock.e2fs.e2fs_state);
432: bp->b_un.b_fs->e2fs_beh = fs2h16(sblock.e2fs.e2fs_beh);
433: bp->b_un.b_fs->e2fs_ruid = fs2h16(sblock.e2fs.e2fs_ruid);
434: bp->b_un.b_fs->e2fs_rgid = fs2h16(sblock.e2fs.e2fs_rgid);
435: }
436:
437: void
1.1 bouyer 438: badsb(listerr, s)
439: int listerr;
440: char *s;
441: {
442:
443: if (!listerr)
444: return;
445: if (preen)
446: printf("%s: ", cdevname());
447: pfatal("BAD SUPER BLOCK: %s\n", s);
448: }
449:
450: /*
451: * Calculate a prototype superblock based on information in the disk label.
452: * When done the cgsblock macro can be calculated and the fs_ncg field
453: * can be used. Do NOT attempt to use other macros without verifying that
454: * their needed information is available!
455: */
456:
457: int
458: calcsb(dev, devfd, fs)
1.7 mycroft 459: const char *dev;
1.1 bouyer 460: int devfd;
1.4 lukem 461: struct m_ext2fs *fs;
1.1 bouyer 462: {
1.4 lukem 463: struct disklabel *lp;
464: struct partition *pp;
465: char *cp;
1.1 bouyer 466:
1.16 ! dsl 467: cp = strchr(dev, '\0');
! 468: if (cp-- == dev ||
! 469: ((*cp < 'a' || *cp > 'h') && !isdigit((unsigned char)*cp))) {
1.1 bouyer 470: pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
471: return (0);
472: }
473: lp = getdisklabel(dev, devfd);
1.16 ! dsl 474: if (isdigit((unsigned char)*cp))
1.1 bouyer 475: pp = &lp->d_partitions[0];
476: else
477: pp = &lp->d_partitions[*cp - 'a'];
1.6 bouyer 478: if (pp->p_fstype != FS_EX2FS) {
479: pfatal("%s: NOT LABELED AS A EXT2 FILE SYSTEM (%s)\n",
1.1 bouyer 480: dev, pp->p_fstype < FSMAXTYPES ?
481: fstypenames[pp->p_fstype] : "unknown");
482: return (0);
483: }
484: memset(fs, 0, sizeof(struct m_ext2fs));
1.6 bouyer 485: fs->e2fs_bsize = pp->p_fsize;
486: fs->e2fs.e2fs_log_bsize = pp->p_fsize / 1024;
1.1 bouyer 487: fs->e2fs.e2fs_bcount = (pp->p_size * DEV_BSIZE) / fs->e2fs_bsize;
1.6 bouyer 488: fs->e2fs.e2fs_first_dblock = (fs->e2fs.e2fs_log_bsize == 0) ? 1 : 0;
1.1 bouyer 489: fs->e2fs.e2fs_bpg = fs->e2fs_bsize * NBBY;
490: fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize;
491: fs->e2fs_qbmask = fs->e2fs_bsize - 1;
492: fs->e2fs_bmask = ~fs->e2fs_qbmask;
493: fs->e2fs_ncg =
494: howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock,
495: fs->e2fs.e2fs_bpg);
496: fs->e2fs_fsbtodb = fs->e2fs.e2fs_log_bsize + 1;
497: fs->e2fs_ngdb = howmany(fs->e2fs_ncg,
498: fs->e2fs_bsize / sizeof(struct ext2_gd));
499:
500: return (1);
501: }
502:
503: static struct disklabel *
504: getdisklabel(s, fd)
1.7 mycroft 505: const char *s;
1.1 bouyer 506: int fd;
507: {
508: static struct disklabel lab;
509:
510: if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
511: if (s == NULL)
512: return ((struct disklabel *)NULL);
513: pwarn("ioctl (GCINFO): %s\n", strerror(errno));
514: errexit("%s: can't read disk label\n", s);
515: }
516: return (&lab);
1.12 bouyer 517: }
518:
519: daddr_t
520: cgoverhead(c)
521: int c;
522: {
523: int overh;
524: overh = 1 /* block bitmap */ +
525: 1 /* inode bitmap */ +
526: sblock.e2fs_itpg;
527: if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
528: sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) {
529: if (cg_has_sb(c) == 0)
530: return overh;
531: }
532: overh += 1 + sblock.e2fs_ngdb;
533: return overh;
1.1 bouyer 534: }
CVSweb <webmaster@jp.NetBSD.org>