+ if (sblock.fs_interleave < 1) {
+ sblock.fs_interleave);
+ sblock.fs_interleave = 1;
+ sbdirty();
+ dirty(&asblk);
+ }
+ }
+ if (sblock.fs_npsect < sblock.fs_nsect) {
+ sblock.fs_npsect);
+ sblock.fs_npsect = sblock.fs_nsect;
+ sbdirty();
+ dirty(&asblk);
+ }
+ }
+ if (cvtflag) {
+ if (sblock.fs_postblformat == FS_42POSTBLFMT) {
+ /*
+ * Requested to convert from old format to new format
+ */
+ if (preen)
+ pwarn("CONVERTING TO NEW FILE SYSTEM FORMAT\n");
+ else if (!reply("CONVERT TO NEW FILE SYSTEM FORMAT"))
+ return(0);
+ sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT;
+ sblock.fs_nrpos = 8;
+ sblock.fs_postbloff =
+ (char *)(&sblock.fs_opostbl[0][0]) -
+ (char *)(&sblock.fs_link);
+ sblock.fs_rotbloff = &sblock.fs_space[0] -
+ (u_char *)(&sblock.fs_link);
+ sblock.fs_cgsize =
+ fragroundup(&sblock, CGSIZE(&sblock));
+ /*
+ * Planning now for future expansion.
+ */
+# if (BYTE_ORDER == BIG_ENDIAN)
+ sblock.fs_qbmask.val[0] = 0;
+ sblock.fs_qbmask.val[1] = ~sblock.fs_bmask;
+ sblock.fs_qfmask.val[0] = 0;
+ sblock.fs_qfmask.val[1] = ~sblock.fs_fmask;
+# endif /* BIG_ENDIAN */
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+ sblock.fs_qbmask.val[0] = ~sblock.fs_bmask;
+ sblock.fs_qbmask.val[1] = 0;
+ sblock.fs_qfmask.val[0] = ~sblock.fs_fmask;
+ sblock.fs_qfmask.val[1] = 0;
+# endif /* LITTLE_ENDIAN */
+ sbdirty();
+ dirty(&asblk);
+ } else if (sblock.fs_postblformat == FS_DYNAMICPOSTBLFMT) {
+ /*
+ * Requested to convert from new format to old format
+ */
+ if (sblock.fs_nrpos != 8 || sblock.fs_ipg > 2048 ||
+ sblock.fs_cpg > 32 || sblock.fs_cpc > 16) {
+ printf(
+ "PARAMETERS OF CURRENT FILE SYSTEM DO NOT\n\t");
+ errexit(
+ "ALLOW CONVERSION TO OLD FILE SYSTEM FORMAT\n");
+ }
+ if (preen)
+ pwarn("CONVERTING TO OLD FILE SYSTEM FORMAT\n");
+ else if (!reply("CONVERT TO OLD FILE SYSTEM FORMAT"))
+ return(0);
+ sblock.fs_postblformat = FS_42POSTBLFMT;
+ sblock.fs_cgsize = fragroundup(&sblock,
+ sizeof(struct ocg) + howmany(sblock.fs_fpg, NBBY));
+ sbdirty();
+ dirty(&asblk);
+ } else {
+ errexit("UNKNOWN FILE SYSTEM FORMAT\n");
+ }
+ }
+ if (asblk.b_dirty) {
+ bcopy((char *)&sblock, (char *)&altsblock,
+ (int)sblock.fs_sbsize);
+ flush(fswritefd, &asblk);
+ }
+ /*
+ * read in the summary info.
+ */
+ asked = 0;
+ for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
+ size = sblock.fs_cssize - i < sblock.fs_bsize ?
+ sblock.fs_cssize - i : sblock.fs_bsize;
+ sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size);
+ if (bread(fsreadfd, (char *)sblock.fs_csp[j],
+ fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
+ size) != 0 && !asked) {
+ pfatal("BAD SUMMARY INFORMATION");
+ if (reply("CONTINUE") == 0)
+ errexit("");
+ asked++;
+ }
+ }
+ /*
+ * allocate and initialize the necessary maps
+ */
+ bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(short));
+ blockmap = calloc((unsigned)bmapsize, sizeof (char));
+ if (blockmap == NULL) {
+ printf("cannot alloc %d bytes for blockmap\n", bmapsize);
+ goto badsb;
+ }
+ statemap = calloc((unsigned)(maxino + 1), sizeof(char));
+ if (statemap == NULL) {
+ printf("cannot alloc %d bytes for statemap\n", maxino + 1);
+ goto badsb;
+ }
+ lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short));
+ if (lncntp == NULL) {
+ printf("cannot alloc %d bytes for lncntp\n",
+ (maxino + 1) * sizeof(short));
+ goto badsb;
+ }
+ numdirs = sblock.fs_cstotal.cs_ndir;
+ inplast = 0;
+ listmax = numdirs + 10;
+ inpsort = (struct inoinfo **)calloc((unsigned)listmax,
+ sizeof(struct inoinfo *));
+ inphead = (struct inoinfo **)calloc((unsigned)numdirs,
+ sizeof(struct inoinfo *));
+ if (inpsort == NULL || inphead == NULL) {
+ printf("cannot alloc %d bytes for inphead\n",
+ numdirs * sizeof(struct inoinfo *));
+ goto badsb;
+ }
+ bufinit();
+ return (1);
+
+badsb:
+ ckfini();
+ return (0);
+}
+
+/*
+ * Read in the super block and its summary info.
+ */
+readsb(listerr)
+ int listerr;
+{
+ daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
+
+ if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0)
+ return (0);
+ sblk.b_bno = super;
+ sblk.b_size = SBSIZE;
+ /*
+ * run a few consistency checks of the super block
+ */
+ if (sblock.fs_magic != FS_MAGIC)
+ { badsb(listerr, "MAGIC NUMBER WRONG"); return (0); }
+ if (sblock.fs_ncg < 1)
+ { badsb(listerr, "NCG OUT OF RANGE"); return (0); }
+ if (sblock.fs_cpg < 1)
+ { badsb(listerr, "CPG OUT OF RANGE"); return (0); }
+ if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl ||
+ (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl)
+ { badsb(listerr, "NCYL LESS THAN NCG*CPG"); return (0); }
+ if (sblock.fs_sbsize > SBSIZE)
+ { badsb(listerr, "SIZE PREPOSTEROUSLY LARGE"); return (0); }
+ /*
+ * Compute block size that the filesystem is based on,
+ * according to fsbtodb, and adjust superblock block number
+ * so we can tell if this is an alternate later.
+ */
+ super *= dev_bsize;
+ dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
+ sblk.b_bno = super / dev_bsize;