diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/backup/dump/dumpmain.c | 20 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/clri/clri.c | 9 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/df/df.c | 11 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/ff/ff.c | 11 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/fsck/setup.c | 6 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/fsdb/fsdb.c | 27 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/fsirand/fsirand.c | 8 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/fstyp/fstyp.c | 4 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/ident/ident_ufs.c | 6 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/labelit/labelit.c | 21 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/mkfs/mkfs.c | 486 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/ncheck/ncheck.c | 11 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/newfs/newfs.c | 51 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/tunefs/tunefs.c | 9 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/ufs/volcopy/volcopy.c | 12 | ||||
-rw-r--r-- | usr/src/cmd/volmgt/vold/ufs_partition.c | 23 | ||||
-rw-r--r-- | usr/src/uts/common/fs/ufs/ufs_vfsops.c | 44 | ||||
-rw-r--r-- | usr/src/uts/common/sys/fs/ufs_fs.h | 23 |
18 files changed, 637 insertions, 145 deletions
diff --git a/usr/src/cmd/backup/dump/dumpmain.c b/usr/src/cmd/backup/dump/dumpmain.c index f6671313f5..1b288a8246 100644 --- a/usr/src/cmd/backup/dump/dumpmain.c +++ b/usr/src/cmd/backup/dump/dumpmain.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-1998, 2000-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -693,6 +693,15 @@ main(argc, argv) /*NOTREACHED*/ } + if (sblock->fs_magic == FS_MAGIC && + (sblock->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock->fs_version != UFS_VERSION_MIN)) { + msg(gettext("Unrecognized UFS version: %d\n"), + sblock->fs_version); + dumpabort(); + /*NOTREACHED*/ + } + if (sblock->fs_magic == MTB_UFS_MAGIC && (sblock->fs_version < MTB_UFS_VERSION_MIN || sblock->fs_version > MTB_UFS_VERSION_1)) { @@ -730,6 +739,15 @@ restart: /*NOTREACHED*/ } + if (sblock->fs_magic == FS_MAGIC && + (sblock->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock->fs_version != UFS_VERSION_MIN)) { + msg(gettext("Unrecognized UFS version: %d\n"), + sblock->fs_version); + dumpabort(); + /*NOTREACHED*/ + } + if (sblock->fs_magic == MTB_UFS_MAGIC && (sblock->fs_version < MTB_UFS_VERSION_MIN || sblock->fs_version > MTB_UFS_VERSION_1)) { diff --git a/usr/src/cmd/fs.d/ufs/clri/clri.c b/usr/src/cmd/fs.d/ufs/clri/clri.c index 5cc7976e42..8b8f8f8ba3 100644 --- a/usr/src/cmd/fs.d/ufs/clri/clri.c +++ b/usr/src/cmd/fs.d/ufs/clri/clri.c @@ -102,6 +102,15 @@ main(int argc, char *argv[]) return (35); } + if (sblock.fs_magic == FS_MAGIC && + (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock.fs_version != UFS_VERSION_MIN)) { + (void) printf( + "unrecognized version of UFS on-disk format: %d\n", + sblock.fs_version); + return (35); + } + if (sblock.fs_magic == MTB_UFS_MAGIC && (sblock.fs_version > MTB_UFS_VERSION_1 || sblock.fs_version < MTB_UFS_VERSION_MIN)) { diff --git a/usr/src/cmd/fs.d/ufs/df/df.c b/usr/src/cmd/fs.d/ufs/df/df.c index 0d5ae57680..37660f2d02 100644 --- a/usr/src/cmd/fs.d/ufs/df/df.c +++ b/usr/src/cmd/fs.d/ufs/df/df.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -487,6 +487,15 @@ dfreedev(file) (void) close(fi); return; } + if (sblock.fs_magic == FS_MAGIC && + (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock.fs_version != UFS_VERSION_MIN)) { + (void) fprintf(stderr, gettext( +"df: %s: unrecognized version of UFS: %d\n"), + file, sblock.fs_version); + (void) close(fi); + return; + } if (sblock.fs_magic == MTB_UFS_MAGIC && (sblock.fs_version > MTB_UFS_VERSION_1 || sblock.fs_version < MTB_UFS_VERSION_MIN)) { diff --git a/usr/src/cmd/fs.d/ufs/ff/ff.c b/usr/src/cmd/fs.d/ufs/ff/ff.c index ddf94b69cf..937ca5a086 100644 --- a/usr/src/cmd/fs.d/ufs/ff/ff.c +++ b/usr/src/cmd/fs.d/ufs/ff/ff.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -318,6 +318,15 @@ check(char *file) return; } + if (sblock.fs_magic == FS_MAGIC && + (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock.fs_version != UFS_VERSION_MIN)) { + (void) fprintf(stderr, "%s: unrecognized version of UFS: %d\n", + file, sblock.fs_version); + nerror++; + return; + } + if (sblock.fs_magic == MTB_UFS_MAGIC && (sblock.fs_version > MTB_UFS_VERSION_1 || sblock.fs_version < MTB_UFS_VERSION_MIN)) { diff --git a/usr/src/cmd/fs.d/ufs/fsck/setup.c b/usr/src/cmd/fs.d/ufs/fsck/setup.c index e742965270..7c30c509e7 100644 --- a/usr/src/cmd/fs.d/ufs/fsck/setup.c +++ b/usr/src/cmd/fs.d/ufs/fsck/setup.c @@ -138,6 +138,12 @@ read_super_block(int listerr) err = "MAGIC NUMBER WRONG"; goto fail; } + if (sblock.fs_magic == FS_MAGIC && + (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock.fs_version != UFS_VERSION_MIN)) { + err = "UNRECOGNIZED VERSION"; + goto fail; + } if (sblock.fs_magic == MTB_UFS_MAGIC && (sblock.fs_version > MTB_UFS_VERSION_1 || sblock.fs_version < MTB_UFS_VERSION_MIN)) { diff --git a/usr/src/cmd/fs.d/ufs/fsdb/fsdb.c b/usr/src/cmd/fs.d/ufs/fsdb/fsdb.c index 4603d55719..d741fcff0d 100644 --- a/usr/src/cmd/fs.d/ufs/fsdb/fsdb.c +++ b/usr/src/cmd/fs.d/ufs/fsdb/fsdb.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -533,9 +533,12 @@ main(argc, argv) } } - if (fs->fs_magic == MTB_UFS_MAGIC && + if ((fs->fs_magic == FS_MAGIC && + (fs->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + fs->fs_version != UFS_VERSION_MIN)) || + (fs->fs_magic == MTB_UFS_MAGIC && (fs->fs_version > MTB_UFS_VERSION_1 || - fs->fs_version < MTB_UFS_VERSION_MIN)) { + fs->fs_version < MTB_UFS_VERSION_MIN))) { if (!override) { printf("%s: Unrecognized UFS version number: %d\n", special, fs->fs_version); @@ -4185,13 +4188,26 @@ empty: return; } } + if (sb->fs_magic == FS_MAGIC && + (sb->fs_version != + UFS_EFISTYLE4NONEFI_VERSION_2 && + sb->fs_version != UFS_VERSION_MIN)) { + cur_cgrp = 0; + if (!override) { + printf("invalid super block "); + printf("version number\n"); + cur_cgrp--; + error++; + return; + } + } if (sb->fs_magic == MTB_UFS_MAGIC && (sb->fs_version > MTB_UFS_VERSION_1 || sb->fs_version < MTB_UFS_VERSION_MIN)) { cur_cgrp = 0; if (!override) { printf("invalid super block "); - printf("magic word\n"); + printf("version number\n"); cur_cgrp--; error++; return; @@ -4584,8 +4600,7 @@ printsb(fs) printf("magic\t%x\ttime\t%s", fs->fs_magic, ctime(&t)); #endif - if (fs->fs_magic == MTB_UFS_MAGIC) - printf("version\t%x\n", fs->fs_version); + printf("version\t%x\n", fs->fs_version); printf("nbfree\t%ld\tndir\t%ld\tnifree\t%ld\tnffree\t%ld\n", fs->fs_cstotal.cs_nbfree, fs->fs_cstotal.cs_ndir, fs->fs_cstotal.cs_nifree, fs->fs_cstotal.cs_nffree); diff --git a/usr/src/cmd/fs.d/ufs/fsirand/fsirand.c b/usr/src/cmd/fs.d/ufs/fsirand/fsirand.c index 3a4c3b6803..52385b5a45 100644 --- a/usr/src/cmd/fs.d/ufs/fsirand/fsirand.c +++ b/usr/src/cmd/fs.d/ufs/fsirand/fsirand.c @@ -108,6 +108,14 @@ main(int argc, char *argv[]) "fsirand: Not a file system (bad magic number in superblock)\n"); exit(1); } + if (fs->fs_magic == FS_MAGIC && + (fs->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + fs->fs_version != UFS_VERSION_MIN)) { + (void) fprintf(stderr, + "fsirand: Unrecognized UFS format version number %d (in superblock)\n", + fs->fs_version); + exit(1); + } if (fs->fs_magic == MTB_UFS_MAGIC && (fs->fs_version > MTB_UFS_VERSION_1 || fs->fs_version < MTB_UFS_VERSION_MIN)) { diff --git a/usr/src/cmd/fs.d/ufs/fstyp/fstyp.c b/usr/src/cmd/fs.d/ufs/fstyp/fstyp.c index d0116e2014..3dac0a1c04 100644 --- a/usr/src/cmd/fs.d/ufs/fstyp/fstyp.c +++ b/usr/src/cmd/fs.d/ufs/fstyp/fstyp.c @@ -203,6 +203,10 @@ dumpfs(const char *name) } if ((afs.fs_magic != FS_MAGIC) && (afs.fs_magic != MTB_UFS_MAGIC)) return (31+1); + if ((afs.fs_magic == FS_MAGIC) && + (afs.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + afs.fs_version != UFS_VERSION_MIN)) + return (31+1); if ((afs.fs_magic == MTB_UFS_MAGIC) && (afs.fs_version > MTB_UFS_VERSION_1 || afs.fs_version < MTB_UFS_VERSION_MIN)) diff --git a/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c b/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c index 3ba77f1c3e..4a6a1d2cf9 100644 --- a/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c +++ b/usr/src/cmd/fs.d/ufs/ident/ident_ufs.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -80,7 +80,9 @@ ident_fs(int fd, char *rawpath, int *clean, int verbose) *clean = FALSE; } - if ((fs->fs_magic == FS_MAGIC) || + if ((fs->fs_magic == FS_MAGIC && + (fs->fs_version == UFS_EFISTYLE4NONEFI_VERSION_2 || + fs->fs_version == UFS_VERSION_MIN)) || (fs->fs_magic == MTB_UFS_MAGIC && (fs->fs_version <= MTB_UFS_VERSION_1 && fs->fs_version >= MTB_UFS_VERSION_MIN))) { diff --git a/usr/src/cmd/fs.d/ufs/labelit/labelit.c b/usr/src/cmd/fs.d/ufs/labelit/labelit.c index 9087658e23..736805097c 100644 --- a/usr/src/cmd/fs.d/ufs/labelit/labelit.c +++ b/usr/src/cmd/fs.d/ufs/labelit/labelit.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -175,6 +175,15 @@ label(special, fsname, volume) gettext("bad super block magic number\n")); exit(31+1); } + if ((sblock.fs_magic == FS_MAGIC) && + ((sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2) && + (sblock.fs_version != UFS_VERSION_MIN))) { + (void) fprintf(stderr, gettext("labelit: ")); + (void) fprintf(stderr, + gettext("unrecognized UFS format version: %d\n"), + sblock.fs_version); + exit(31+1); + } if ((sblock.fs_magic == MTB_UFS_MAGIC) && ((sblock.fs_version > MTB_UFS_VERSION_1) || (sblock.fs_version < MTB_UFS_VERSION_MIN))) { @@ -259,6 +268,16 @@ label(special, fsname, volume) gettext("bad alternate super block(%i) magic number\n"), i); exit(31+1); } + if ((altsblock.fs_magic == FS_MAGIC) && + ((altsblock.fs_version != + UFS_EFISTYLE4NONEFI_VERSION_2) && + (altsblock.fs_version != UFS_VERSION_MIN))) { + (void) fprintf(stderr, gettext("labelit: ")); + (void) fprintf(stderr, + gettext("bad alternate super block UFS format version: %d\n"), + altsblock.fs_version); + exit(31+1); + } if ((altsblock.fs_magic == MTB_UFS_MAGIC) && ((altsblock.fs_version > MTB_UFS_VERSION_1) || (altsblock.fs_version < MTB_UFS_VERSION_MIN))) { diff --git a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c index 5e2a4f0c87..2d98605065 100644 --- a/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c +++ b/usr/src/cmd/fs.d/ufs/mkfs/mkfs.c @@ -97,20 +97,20 @@ * 72MB CDC 18 9 * 30MB CDC 18 5 * 720KB Diskette 9 2 + * + * However the defaults will be different for disks larger than CHSLIMIT. */ #define DFLNSECT 32 #define DFLNTRAK 16 /* - * The following two constants set the default block and fragment sizes. - * Both constants must be a power of 2 and meet the following constraints: - * MINBSIZE <= DESBLKSIZE <= MAXBSIZE - * DEV_BSIZE <= DESFRAGSIZE <= DESBLKSIZE - * DESBLKSIZE / DESFRAGSIZE <= 8 + * The following default sectors and tracks values are used for + * non-efi disks that are larger than the CHS addressing limit. The + * existing default cpg of 16 (DESCPG) holds good for larger disks too. */ -#define DESBLKSIZE 8192 -#define DESFRAGSIZE 1024 +#define DEF_SECTORS_EFI 128 +#define DEF_TRACKS_EFI 48 /* * The maximum number of cylinders in a group depends upon how much @@ -121,6 +121,16 @@ #define DESCPG 16 /* desired fs_cpg */ /* + * The following two constants set the default block and fragment sizes. + * Both constants must be a power of 2 and meet the following constraints: + * MINBSIZE <= DESBLKSIZE <= MAXBSIZE + * DEV_BSIZE <= DESFRAGSIZE <= DESBLKSIZE + * DESBLKSIZE / DESFRAGSIZE <= 8 + */ +#define DESBLKSIZE 8192 +#define DESFRAGSIZE 1024 + +/* * MINFREE gives the minimum acceptable percentage of file system * blocks which may be free. If the freelist drops below this level * only the superuser may continue to allocate blocks. This may @@ -171,6 +181,25 @@ */ #define NRPOS 8 /* number distinct rotational positions */ +#ifdef DEBUG +#define dprintf(x) printf x +#else +#define dprintf(x) +#endif + +/* + * For the -N option, when calculating the backup superblocks, do not print + * them if we are not really sure. We may have to try an alternate method of + * arriving at the superblocks. So defer printing till a handful of superblocks + * look good. + */ +#define tprintf(x) if (Nflag && retry) \ + strncat(tmpbuf, x, strlen(x)); \ + else \ + (void) fprintf(stderr, x); + +#define ALTSB 32 /* Location of first backup superblock */ + /* * range_check "user_supplied" flag values. */ @@ -400,8 +429,9 @@ static void dump_sblock(void); union { struct fs fs; char pad[SBSIZE]; -} fsun; +} fsun, altfsun; #define sblock fsun.fs +#define altsblock altfsun.fs struct csum *fscs; @@ -437,6 +467,13 @@ int fso = -1; #define NO_DEFAULT LONG_MIN /* + * INVALIDSBLIMIT is the number of bad backup superblocks that will be + * tolerated before we decide to try arriving at a different set of them + * using a different logic. This is applicable for non-EFI disks only. + */ +#define INVALIDSBLIMIT 10 + +/* * The *_flag variables are used to indicate that the user specified * the values, rather than that we made them up ourselves. We can * complain about the user giving us bogus values. @@ -490,6 +527,7 @@ int Rflag; /* dump the superblock in binary */ char *fsys; time_t mkfstime; char *string; +int label_type; /* * logging support @@ -526,7 +564,7 @@ int isbad; void lockexit(int); void randomgeneration(void); void checksummarysize(void); -void checksblock(void); +int checksblock(struct fs, int); void growinit(char *); void checkdev(char *, char *); void checkmount(struct mnttab *, char *); @@ -578,8 +616,10 @@ main(int argc, char *argv[]) struct mnttab mntp; char *special; struct statvfs64 fs; + struct dk_geom dkg; struct dk_cinfo dkcinfo; char pbuf[sizeof (uint64_t) * 3 + 1]; + char *tmpbuf; int width, plen; uint64_t num; int c, saverr; @@ -589,6 +629,9 @@ main(int argc, char *argv[]) uint64_t nbytes64; int remaining_cg; int do_dot = 0; + int use_efi_dflts = 0, retry = 0; + int invalid_sb_cnt, ret, skip_this_sb; + int save_nsect, save_ntrack, save_cpg; (void) setlocale(LC_ALL, ""); @@ -948,6 +991,7 @@ main(int argc, char *argv[]) } else { maxcontig = tmpmaxcontig; } + dprintf(("DeBuG maxcontig : %ld\n", maxcontig)); if (rotdelay == -1) { /* default by newfs and mkfs */ rotdelay = ROTDELAY; @@ -956,6 +1000,7 @@ main(int argc, char *argv[]) if (cpg_flag == RC_DEFAULT) { /* If not explicity set, use default */ cpg = DESCPG; } + dprintf(("DeBuG cpg : %ld\n", cpg)); /* * Now that we have the semi-sane args, either positional, via -o, @@ -1011,13 +1056,152 @@ main(int argc, char *argv[]) } } - /* - * 32K based on max block size of 64K, and rotational layout - * test of nsect <= (256 * sectors/block). Current block size - * limit is not 64K, but it's growing soon. + * With newer and much larger disks, the newfs(1M) and mkfs_ufs(1M) + * commands had problems in correctly handling the "native" geometries + * for various storage devices. + * + * To handle the new age disks, mkfs_ufs(1M) will use the EFI style + * for non-EFI disks that are larger than the CHS addressing limit + * ( > 8GB approx ) and ignore the disk geometry information for + * these drives. This is what is currently done for multi-terrabyte + * filesystems on EFI disks. + * + * However if the user asked for a specific layout by supplying values + * for these parameters, honour the user supplied parameters. */ - range_check(&nsect, "nsect", 1, 32768, DFLNSECT, nsect_flag); + + if (mtb != 'y' && label_type == LABEL_TYPE_VTOC && + ((nsect == -1 && ntrack == -1) || + (grow && ntrack_flag == RC_DEFAULT))) { + /* + * "-1" indicates that we were called from newfs and these + * arguments were not passed in command line. Calculate nsect + * and ntrack in the same manner as newfs. + * + * This is required because, the defaults for nsect and ntrack + * is hardcoded in mkfs, whereas to generate the alternate + * superblock locations for the -N option, there is a need for + * the geometry based values that newfs would have arrived at. + * Newfs would have arrived at these values as below. + */ + + if (ioctl(fsi, DKIOCGGEOM, &dkg)) { + dprintf(("%s: Unable to read Disk geometry", fsys)); + perror(gettext("Unable to read Disk geometry")); + lockexit(32); + } else { + nsect = dkg.dkg_nsect; + ntrack = dkg.dkg_nhead; +#ifdef i386 /* Bug 1170182 */ + if (ntrack > 32 && (ntrack % 16) != 0) { + ntrack -= (ntrack % 16); + } +#endif + if ((dkg.dkg_ncyl * dkg.dkg_nhead * dkg.dkg_nsect) + > CHSLIMIT) { + use_efi_dflts = 1; + retry = 1; + } + } + dprintf(("DeBuG mkfs: geom = %ld CHSLIMIT = %d\n", + dkg.dkg_ncyl * dkg.dkg_nhead * dkg.dkg_nsect, + CHSLIMIT)); + } + + /* + * For the newfs -N case, even if the disksize is > CHSLIMIT, do not + * blindly follow EFI style. If the fs_version indicates a geometry + * based layout, try that one first. If it fails we can always try the + * other logic. + * + * If we were called from growfs, we will have a problem if we mix + * and match the filesystem creation and growth styles. For example, + * if we create using EFI style and we have to also grow using EFI + * style. So follow the style indicated by the fs_version. + * + * Read and verify the primary superblock. If it looks sane, use the + * fs_version from the superblock. If the primary superblock does + * not look good, read and verify the first alternate superblock at + * ALTSB. Use the fs_version to decide whether to use the + * EFI style logic or the old geometry based logic to calculate + * the alternate superblock locations. + */ + if ((Nflag && use_efi_dflts) || (grow)) { + if (grow && ntrack_flag != RC_DEFAULT) + goto retry_alternate_logic; + rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, + (char *)&altsblock); + ret = checksblock(altsblock, 1); + + if (!ret) { + if (altsblock.fs_magic == MTB_UFS_MAGIC) { + mtb = 'y'; + goto retry_alternate_logic; + } + use_efi_dflts = (altsblock.fs_version == + UFS_EFISTYLE4NONEFI_VERSION_2) ? 1 : 0; + } else { + /* + * The primary superblock didn't help in determining + * the fs_version. Try the first alternate superblock. + */ + dprintf(("DeBuG checksblock() failed - error : %d" + " for sb : %d\n", ret, SBOFF/sectorsize)); + rdfs((diskaddr_t)ALTSB, (int)sbsize, + (char *)&altsblock); + ret = checksblock(altsblock, 1); + + if (!ret) { + if (altsblock.fs_magic == MTB_UFS_MAGIC) { + mtb = 'y'; + goto retry_alternate_logic; + } + use_efi_dflts = (altsblock.fs_version == + UFS_EFISTYLE4NONEFI_VERSION_2) ? 1 : 0; + } else + dprintf(("DeBuG checksblock() failed - error : %d" + " for sb : %d\n", ret, ALTSB)); + } + } + +retry_alternate_logic: + invalid_sb_cnt = 0; + if (use_efi_dflts) { + save_nsect = nsect; + save_ntrack = ntrack; + save_cpg = cpg; + + nsect = DEF_SECTORS_EFI; + ntrack = DEF_TRACKS_EFI; + cpg = DESCPG; + + dprintf(("\nDeBuG Using EFI defaults\n")); + dprintf(("DeBuG save_nsect=%d, save_ntrack=%d, save_cpg=%d\n", + save_nsect, save_ntrack, save_cpg)); + } else { + save_nsect = DEF_SECTORS_EFI; + save_ntrack = DEF_TRACKS_EFI; + save_cpg = DESCPG; + dprintf(("\n\nDeBuG mkfs: Using Geometry\n")); + dprintf(("DeBuG save_nsect=%d, save_ntrack=%d, save_cpg=%d\n", + save_nsect, save_ntrack, save_cpg)); + /* + * 32K based on max block size of 64K, and rotational layout + * test of nsect <= (256 * sectors/block). Current block size + * limit is not 64K, but it's growing soon. + */ + range_check(&nsect, "nsect", 1, 32768, DFLNSECT, nsect_flag); + /* + * ntrack is the number of tracks per cylinder. + * The ntrack value must be between 1 and the total number of + * sectors in the file system. + */ + range_check(&ntrack, "ntrack", 1, + fssize_db > INT_MAX ? INT_MAX : (uint32_t)fssize_db, + DFLNTRAK, ntrack_flag); + } + range_check(&apc, "apc", 0, nsect - 1, 0, apc_flag); if (mtb == 'y') @@ -1061,15 +1245,6 @@ main(int argc, char *argv[]) range_check(&nrpos, "nrpos", 1, nsect, MIN(nsect, NRPOS), nrpos_flag); /* - * ntrack is the number of tracks per cylinder. - * The ntrack value must be between 1 and the total number of - * sectors in the file system. - */ - range_check(&ntrack, "ntrack", 1, - fssize_db > INT_MAX ? INT_MAX : (uint32_t)fssize_db, - DFLNTRAK, ntrack_flag); - - /* * nbpi is variable, but 2MB seems a reasonable upper limit, * as 4MB tends to cause problems (using otherwise-default * parameters). The true limit is where we end up with one @@ -1121,8 +1296,11 @@ main(int argc, char *argv[]) nsect * ntrack); } + dprintf(("DeBuG cpg : %ld\n", cpg)); if (cpg == -1) cpg = maxcpg; + dprintf(("DeBuG cpg : %ld\n", cpg)); + /* * mincpg is variable in complex ways, so we really can't * do a sane lower-end limit check at this point. @@ -1791,6 +1969,10 @@ grow30: sblock.fs_version = MTB_UFS_VERSION_1; } else { sblock.fs_magic = FS_MAGIC; + if (use_efi_dflts) + sblock.fs_version = UFS_EFISTYLE4NONEFI_VERSION_2; + else + sblock.fs_version = UFS_VERSION_MIN; } if (grow) { @@ -1836,27 +2018,85 @@ grow40: (float)sblock.fs_size * sblock.fs_fsize / MB, sblock.fs_ncg, sblock.fs_cpg, (float)sblock.fs_fpg * sblock.fs_fsize / MB, sblock.fs_ipg); + + tmpbuf = calloc(sblock.fs_ncg / 50 + 500, 1); + if (tmpbuf == NULL) { + perror("calloc"); + lockexit(32); + } /* * Now build the cylinders group blocks and * then print out indices of cylinder groups. */ - (void) fprintf(stderr, gettext( + tprintf(gettext( "super-block backups (for fsck -F ufs -o b=#) at:\n")); for (width = cylno = 0; cylno < sblock.fs_ncg && cylno < 10; cylno++) { if ((grow == 0) || (cylno >= grow_fs_ncg)) initcg(cylno); num = fsbtodb(&sblock, (uint64_t)cgsblock(&sblock, cylno)); + /* + * If Nflag and if the disk is larger than the CHSLIMIT, + * then sanity test the superblocks before reporting. If there + * are too many superblocks which look insane, we probably + * have to retry with alternate logic. If we are already + * retrying, then our efforts to arrive at alternate + * superblocks failed, so complain and exit. + */ + if (Nflag && retry) { + skip_this_sb = 0; + rdfs((diskaddr_t)num, sbsize, (char *)&altsblock); + ret = checksblock(altsblock, 1); + if (ret) { + skip_this_sb = 1; + invalid_sb_cnt++; + dprintf(("DeBuG checksblock() failed - error : %d" + " for sb : %llu invalid_sb_cnt : %d\n", + ret, num, invalid_sb_cnt)); + } else { + /* + * Though the superblock looks sane, verify if the + * fs_version in the superblock and the logic that + * we are using to arrive at the superblocks match. + */ + if (use_efi_dflts && altsblock.fs_version + != UFS_EFISTYLE4NONEFI_VERSION_2) { + skip_this_sb = 1; + invalid_sb_cnt++; + } + } + if (invalid_sb_cnt >= INVALIDSBLIMIT) { + if (retry > 1) { + (void) fprintf(stderr, gettext( + "Error determining alternate " + "superblock locations\n")); + free(tmpbuf); + lockexit(32); + } + retry++; + use_efi_dflts = !use_efi_dflts; + nsect = save_nsect; + ntrack = save_ntrack; + cpg = save_cpg; + free(tmpbuf); + goto retry_alternate_logic; + } + if (skip_this_sb) + continue; + } (void) sprintf(pbuf, " %llu,", num); plen = strlen(pbuf); if ((width + plen) > (WIDTH - 1)) { width = plen; - (void) fprintf(stderr, "\n"); + tprintf("\n"); } else { width += plen; } - (void) fprintf(stderr, "%s", pbuf); + if (Nflag && retry) + strncat(tmpbuf, pbuf, strlen(pbuf)); + else + (void) fprintf(stderr, "%s", pbuf); } - (void) fprintf(stderr, "\n"); + tprintf("\n"); remaining_cg = sblock.fs_ncg - cylno; @@ -1865,8 +2105,7 @@ grow40: * initialized, print a "." for every 50 cylinder groups. */ if (remaining_cg > 300) { - (void) fprintf(stderr, gettext( - "Initializing cylinder groups:\n")); + tprintf(gettext("Initializing cylinder groups:\n")); do_dot = 1; } @@ -1887,10 +2126,10 @@ grow40: if ((grow == 0) || (cylno >= grow_fs_ncg)) initcg(cylno); if (do_dot && cylno % 50 == 0) { - (void) fprintf(stderr, "."); + tprintf("."); i++; if (i == WIDTH - 1) { - (void) fprintf(stderr, "\n"); + tprintf("\n"); i = 0; } } @@ -1902,26 +2141,80 @@ grow40: */ if (do_dot) { - (void) fprintf(stderr, gettext( + tprintf(gettext( "\nsuper-block backups for last 10 cylinder groups at:\n")); } for (width = 0; cylno < sblock.fs_ncg; cylno++) { if ((grow == 0) || (cylno >= grow_fs_ncg)) initcg(cylno); num = fsbtodb(&sblock, (uint64_t)cgsblock(&sblock, cylno)); - (void) sprintf(pbuf, " %llu,", num); + if (Nflag && retry) { + skip_this_sb = 0; + rdfs((diskaddr_t)num, sbsize, (char *)&altsblock); + ret = checksblock(altsblock, 1); + if (ret) { + skip_this_sb = 1; + invalid_sb_cnt++; + dprintf(("DeBuG checksblock() failed - error : %d" + " for sb : %llu invalid_sb_cnt : %d\n", + ret, num, invalid_sb_cnt)); + } else { + /* + * Though the superblock looks sane, verify if the + * fs_version in the superblock and the logic that + * we are using to arrive at the superblocks match. + */ + if (use_efi_dflts && altsblock.fs_version + != UFS_EFISTYLE4NONEFI_VERSION_2) { + skip_this_sb = 1; + invalid_sb_cnt++; + } + } + if (invalid_sb_cnt >= INVALIDSBLIMIT) { + if (retry > 1) { + (void) fprintf(stderr, gettext( + "Error determining alternate " + "superblock locations\n")); + free(tmpbuf); + lockexit(32); + } + retry++; + use_efi_dflts = !use_efi_dflts; + nsect = save_nsect; + ntrack = save_ntrack; + cpg = save_cpg; + free(tmpbuf); + goto retry_alternate_logic; + } + if (skip_this_sb) + continue; + } + /* Don't print ',' for the last superblock */ + if (cylno == sblock.fs_ncg-1) + (void) sprintf(pbuf, " %llu", num); + else + (void) sprintf(pbuf, " %llu,", num); plen = strlen(pbuf); if ((width + plen) > (WIDTH - 1)) { width = plen; - (void) fprintf(stderr, "\n"); + tprintf("\n"); } else { width += plen; } - (void) fprintf(stderr, "%s", pbuf); + if (Nflag && retry) + strncat(tmpbuf, pbuf, strlen(pbuf)); + else + (void) fprintf(stderr, "%s", pbuf); } - (void) fprintf(stderr, "\n"); - if (Nflag) + tprintf("\n"); + if (Nflag) { + if (retry) + fprintf(stderr, "%s", tmpbuf); + free(tmpbuf); lockexit(0); + } + + free(tmpbuf); if (grow) goto grow50; @@ -2028,16 +2321,17 @@ get_max_size(int fd) { struct vtoc vtoc; dk_gpt_t *efi_vtoc; - int is_efi = 0; diskaddr_t slicesize; int index = read_vtoc(fd, &vtoc); - if (index < 0) { + if (index >= 0) { + label_type = LABEL_TYPE_VTOC; + } else { if (index == VT_ENOTSUP || index == VT_ERROR) { /* it might be an EFI label */ - is_efi = 1; index = efi_alloc_and_read(fd, &efi_vtoc); + label_type = LABEL_TYPE_EFI; } } @@ -2055,7 +2349,7 @@ get_max_size(int fd) lockexit(32); } - if (is_efi) { + if (label_type == LABEL_TYPE_EFI) { slicesize = efi_vtoc->efi_parts[index].p_size; efi_free(efi_vtoc); } else { @@ -2071,11 +2365,8 @@ get_max_size(int fd) slicesize = (uint32_t)vtoc.v_part[index].p_size; } - if (debug) { - (void) fprintf(stderr, - "get_max_size: index = %d, p_size = %lld, dolimit = %d\n", - index, slicesize, (slicesize > FS_MAX)); - } + dprintf(("DeBuG get_max_size index = %d, p_size = %lld, dolimit = %d\n", + index, slicesize, (slicesize > FS_MAX))); /* * The next line limits a UFS file system to the maximum @@ -3154,6 +3445,14 @@ dump_fscmd(char *fsys, int fsi) lockexit(32); } + if (sblock.fs_magic == FS_MAGIC && + (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sblock.fs_version != UFS_VERSION_MIN)) { + (void) fprintf(stderr, gettext( + "Unknown version of UFS format: %d\n"), sblock.fs_version); + lockexit(32); + } + if (sblock.fs_magic == MTB_UFS_MAGIC && (sblock.fs_version > MTB_UFS_VERSION_1 || sblock.fs_version < MTB_UFS_VERSION_MIN)) { @@ -3556,45 +3855,56 @@ checksummarysize() } } -void -checksblock() -{ - /* - * make sure this is a file system - */ - if ((sblock.fs_magic != FS_MAGIC) && - (sblock.fs_magic != MTB_UFS_MAGIC)) { - (void) fprintf(stderr, - gettext("Bad superblock; magic number wrong\n")); - lockexit(32); - } - - if (sblock.fs_magic == MTB_UFS_MAGIC && - sblock.fs_version > MTB_UFS_VERSION_1) { - (void) fprintf(stderr, - gettext("Unrecognized version of UFS\n")); - lockexit(32); - } +/* + * checksblock() has two uses: + * - One is to sanity test the superblock and is used when newfs(1M) + * is invoked with the "-N" option. If any discrepancy was found, + * just return whatever error was found and do not exit. + * - the other use of it is in places where you expect the superblock + * to be sane, and if it isn't, then we exit. + * Which of the above two actions to take is indicated with the second argument. + */ - if (sblock.fs_ncg < 1) { - (void) fprintf(stderr, - gettext("Bad superblock; ncg out of range\n")); - lockexit(32); - } - if (sblock.fs_cpg < 1) { - (void) fprintf(stderr, - gettext("Bad superblock; cpg out of range\n")); - lockexit(32); - } - if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || - (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) { - (void) fprintf(stderr, - gettext("Bad superblock; ncyl out of range\n")); - lockexit(32); - } - if (sblock.fs_sbsize <= 0 || sblock.fs_sbsize > sblock.fs_bsize) { - (void) fprintf(stderr, gettext( - "Bad superblock; superblock size out of range\n")); +int +checksblock(struct fs sb, int proceed) +{ + int err = 0; + char *errmsg; + + if ((sb.fs_magic != FS_MAGIC) && (sb.fs_magic != MTB_UFS_MAGIC)) { + err = 1; + errmsg = gettext("Bad superblock; magic number wrong\n"); + } else if ((sb.fs_magic == FS_MAGIC && + (sb.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + sb.fs_version != UFS_VERSION_MIN)) || + (sb.fs_magic == MTB_UFS_MAGIC && + (sb.fs_version > MTB_UFS_VERSION_1 || + sb.fs_version < MTB_UFS_VERSION_MIN))) { + err = 2; + errmsg = gettext("Unrecognized version of UFS\n"); + } else if (sb.fs_ncg < 1) { + err = 3; + errmsg = gettext("Bad superblock; ncg out of range\n"); + } else if (sb.fs_cpg < 1) { + err = 4; + errmsg = gettext("Bad superblock; cpg out of range\n"); + } else if (sb.fs_ncg * sb.fs_cpg < sb.fs_ncyl || + (sb.fs_ncg - 1) * sb.fs_cpg >= sb.fs_ncyl) { + err = 5; + errmsg = gettext("Bad superblock; ncyl out of range\n"); + } else if (sb.fs_sbsize <= 0 || sb.fs_sbsize > sb.fs_bsize) { + err = 6; + errmsg = gettext("Bad superblock; superblock size out of range\n"); + } + + + if (proceed) { + if (err) dprintf(("%s", errmsg)); + return (err); + } + + if (err) { + fprintf(stderr, "%s", errmsg); lockexit(32); } } @@ -3693,7 +4003,7 @@ growinit(char *devstr) * Read and verify the superblock */ rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, (char *)&sblock); - checksblock(); + (void) checksblock(sblock, 0); if (sblock.fs_postblformat != FS_DYNAMICPOSTBLFMT) { (void) fprintf(stderr, gettext("old file system format; can't growfs\n")); @@ -4238,7 +4548,7 @@ probe_summaryinfo() * read and verify the superblock */ rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, (char *)&sblock); - checksblock(); + (void) checksblock(sblock, 0); /* * check how much we can extend the cg summary info block @@ -4978,6 +5288,9 @@ static void range_check(long *varp, char *name, long minimum, long maximum, long def_val, int user_supplied) { + dprintf(("DeBuG %s : %ld (%ld %ld %ld)\n", + name, *varp, minimum, maximum, def_val)); + if ((*varp < minimum) || (*varp > maximum)) { if (user_supplied != RC_DEFAULT) { (void) fprintf(stderr, gettext( @@ -4991,6 +5304,7 @@ range_check(long *varp, char *name, long minimum, long maximum, name, def_val); } *varp = def_val; + dprintf(("DeBuG %s : %ld\n", name, *varp)); return; } lockexit(2); diff --git a/usr/src/cmd/fs.d/ufs/ncheck/ncheck.c b/usr/src/cmd/fs.d/ufs/ncheck/ncheck.c index 58a3e83d24..8a3ff5f0cd 100644 --- a/usr/src/cmd/fs.d/ufs/ncheck/ncheck.c +++ b/usr/src/cmd/fs.d/ufs/ncheck/ncheck.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -257,6 +257,15 @@ check(file) return; } + if ((sblock.fs_magic == FS_MAGIC) && + ((sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2) && + (sblock.fs_version != UFS_VERSION_MIN))) { + (void) printf("%s: unrecognized ufs version number %d\n", + file, sblock.fs_version); + nerror++; + return; + } + if ((sblock.fs_magic == MTB_UFS_MAGIC) && ((sblock.fs_version > MTB_UFS_VERSION_1) || (sblock.fs_version < MTB_UFS_VERSION_MIN))) { diff --git a/usr/src/cmd/fs.d/ufs/newfs/newfs.c b/usr/src/cmd/fs.d/ufs/newfs/newfs.c index 6ff1bcef98..f0ce84170f 100644 --- a/usr/src/cmd/fs.d/ufs/newfs/newfs.c +++ b/usr/src/cmd/fs.d/ufs/newfs/newfs.c @@ -106,6 +106,9 @@ static void fatal(char *fmt, ...); #define DESBLKSIZE 8192 #define DESFRAGSIZE 1024 +#define dprintf(x) if (debug) printf x + +int debug = 0; /* enable debug output */ static int Nflag; /* run mkfs without writing file system */ static int Tflag; /* set up file system for growth to over 1 TB */ static int verbose; /* show mkfs line before exec */ @@ -116,6 +119,7 @@ static int ntracks; /* # tracks/cylinder */ static int ntracks_set = 0; /* true if the user specified ntracks */ static int optim = FS_OPTTIME; /* optimization, t(ime) or s(pace) */ static int nsectors; /* # sectors/track */ +static int geom_nsectors; /* # sectors/track as returned by GEOM ioctl */ static int cpg; /* cylinders/cylinder group */ static int cpg_set = 0; /* true if the user specified cpg */ static int minfree = -1; /* free space threshold */ @@ -134,9 +138,12 @@ static int text_sb = 0; /* no disk changes; just final sb text dump */ static int binary_sb = 0; /* no disk changes; just final sb binary dump */ static int label_type; /* see types below */ -#define LABEL_TYPE_VTOC 1 -#define LABEL_TYPE_EFI 2 -#define LABEL_TYPE_OTHER 3 +/* + * The variable use_efi_dflts is an indicator of whether to use EFI logic + * or the geometry logic in laying out the filesystem. This is decided + * based on the size of the disk and is used only for non-EFI labeled disks. + */ +static int use_efi_dflts = 0; static char device[MAXPATHLEN]; static char cmd[BUFSIZ]; @@ -150,6 +157,7 @@ main(int argc, char *argv[]) struct stat64 st; int status; int option; + int nsect; struct fs *sbp; /* Pointer to superblock (if present) */ diskaddr_t actual_fssize; diskaddr_t max_possible_fssize; @@ -407,11 +415,14 @@ main(int argc, char *argv[]) } if (label_type == LABEL_TYPE_VTOC) { - if (nsectors < 0) - fatal(gettext("%s: no default #sectors/track"), - special); - if (ntracks < 0) - fatal(gettext("%s: no default #tracks"), special); + if (!use_efi_dflts) { + if (nsectors < 0) + fatal(gettext("%s: no default #sectors/track"), + special); + if (ntracks < 0) + fatal(gettext("%s: no default #tracks"), + special); + } if (rpm < 0) fatal(gettext( "%s: no default revolutions/minute value"), @@ -562,9 +573,12 @@ main(int argc, char *argv[]) maxipg = roundup(bsize * NBBY / 3, bsize / sizeof (struct inode)); + + nsect = (nsectors == -1) ? geom_nsectors : nsectors; + maxcpg = (bsize - sizeof (struct cg) - howmany(maxipg, NBBY)) / (sizeof (long) + nrpos * sizeof (short) + - nsectors / (MAXFRAG * NBBY)); + nsect / (MAXFRAG * NBBY)); cpg = (fssize / GBSEC) * 32; if (cpg > maxcpg) cpg = maxcpg; @@ -604,6 +618,8 @@ main(int argc, char *argv[]) if (!yes()) exit(0); } + dprintf(("DeBuG newfs : nsect=%d ntrak=%d cpg=%d\n", + nsectors, ntracks, cpg)); /* * If alternates-per-cylinder is ever implemented: * need to get apc from dp->d_apc if no -a switch??? @@ -718,10 +734,23 @@ getdiskbydev(char *disk) if (ioctl(fd, DKIOCGGEOM, &g)) fatal(gettext( "%s: Unable to read Disk geometry"), disk); + dprintf(("DeBuG newfs : geom=%ld, CHSLIMIT=%d\n", + g.dkg_ncyl * g.dkg_nhead * g.dkg_nsect, CHSLIMIT)); + if (((g.dkg_ncyl * g.dkg_nhead * g.dkg_nsect) > CHSLIMIT) && + !Tflag) { + dprintf(("DeBuG newfs : geom > CHSLIMIT\n")); + use_efi_dflts = 1; + } + /* + * Though the nsector that is passed to mkfs is decided here + * based on use_efi_dflts, we still need the geometry + * based dkg_nsect for the cpg calculation later. + */ + geom_nsectors = g.dkg_nsect; if (nsectors == 0) - nsectors = g.dkg_nsect; + nsectors = use_efi_dflts ? -1 : g.dkg_nsect; if (ntracks == 0) - ntracks = g.dkg_nhead; + ntracks = use_efi_dflts ? -1 : g.dkg_nhead; if (rpm == 0) rpm = ((int)g.dkg_rpm <= 0) ? 3600: g.dkg_rpm; } diff --git a/usr/src/cmd/fs.d/ufs/tunefs/tunefs.c b/usr/src/cmd/fs.d/ufs/tunefs/tunefs.c index caa2143120..54ce0b399d 100644 --- a/usr/src/cmd/fs.d/ufs/tunefs/tunefs.c +++ b/usr/src/cmd/fs.d/ufs/tunefs/tunefs.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -385,6 +385,13 @@ getsb(fs, file) fprintf(stderr, "%s: bad magic number\n", file); exit(31+5); } + if (fs->fs_magic == FS_MAGIC && + (fs->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + fs->fs_version != UFS_VERSION_MIN)) { + fprintf(stderr, "%s: unrecognized ufs version: %d\n", file, + fs->fs_version); + exit(31+5); + } if (fs->fs_magic == MTB_UFS_MAGIC && (fs->fs_version > MTB_UFS_VERSION_1 || fs->fs_version < MTB_UFS_VERSION_MIN)) { diff --git a/usr/src/cmd/fs.d/ufs/volcopy/volcopy.c b/usr/src/cmd/fs.d/ufs/volcopy/volcopy.c index 5c9b6357a9..ebba1140cb 100644 --- a/usr/src/cmd/fs.d/ufs/volcopy/volcopy.c +++ b/usr/src/cmd/fs.d/ufs/volcopy/volcopy.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -427,6 +427,11 @@ fsname /devfrom volfrom /devto volto\n"); (Sptr->fs_magic != MTB_UFS_MAGIC)) perr(10, "File System type unknown--get help\n"); + if (Sptr->fs_magic == FS_MAGIC && + (Sptr->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + Sptr->fs_version != UFS_VERSION_MIN)) + perr(10, "Unrecognized version of UFS--get help\n"); + if (Sptr->fs_magic == MTB_UFS_MAGIC && (Sptr->fs_version > MTB_UFS_VERSION_1 || Sptr->fs_version < MTB_UFS_VERSION_MIN)) @@ -579,6 +584,11 @@ fsname /devfrom volfrom /devto volto\n"); (Sptr -> fs_magic != MTB_UFS_MAGIC)) perr(10, "File System type unknown--get help!\n"); + if (Sptr->fs_magic == FS_MAGIC && + (Sptr->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + Sptr->fs_version != UFS_VERSION_MIN)) + perr(10, "Unrecognized version of UFS--get help\n"); + if (Sptr->fs_magic == MTB_UFS_MAGIC && (Sptr->fs_version > MTB_UFS_VERSION_1 || Sptr->fs_version < MTB_UFS_VERSION_MIN)) diff --git a/usr/src/cmd/volmgt/vold/ufs_partition.c b/usr/src/cmd/volmgt/vold/ufs_partition.c index 810b690f8a..b5a29b3cc3 100644 --- a/usr/src/cmd/volmgt/vold/ufs_partition.c +++ b/usr/src/cmd/volmgt/vold/ufs_partition.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -219,12 +219,21 @@ get_label(partition_private_t *partition_privatep) (void) memcpy(file_system_structp, super_blockp, sizeof (struct fs)); } - if ((partition_result == PARTITION_SUCCESS) && - ((file_system_structp->fs_magic != FS_MAGIC) && - (file_system_structp->fs_magic != MTB_UFS_MAGIC) || - ((file_system_structp->fs_magic == MTB_UFS_MAGIC) && - ((file_system_structp->fs_version > MTB_UFS_VERSION_1) || - (file_system_structp->fs_version < MTB_UFS_VERSION_MIN))))) { + if (partition_result == PARTITION_SUCCESS && + file_system_structp->fs_magic != FS_MAGIC && + file_system_structp->fs_magic != MTB_UFS_MAGIC) { + partition_result = PARTITION_NOT_THIS_TYPE; + } + if (partition_result == PARTITION_SUCCESS && + file_system_structp->fs_magic == FS_MAGIC && + file_system_structp->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + file_system_structp->fs_version != UFS_VERSION_MIN) { + partition_result = PARTITION_NOT_THIS_TYPE; + } + if (partition_result == PARTITION_SUCCESS && + file_system_structp->fs_magic == MTB_UFS_MAGIC && + (file_system_structp->fs_version > MTB_UFS_VERSION_1 || + file_system_structp->fs_version < MTB_UFS_VERSION_MIN)) { partition_result = PARTITION_NOT_THIS_TYPE; } if (partition_result == PARTITION_SUCCESS) { diff --git a/usr/src/uts/common/fs/ufs/ufs_vfsops.c b/usr/src/uts/common/fs/ufs/ufs_vfsops.c index 02fe689ef5..62bac1b42e 100644 --- a/usr/src/uts/common/fs/ufs/ufs_vfsops.c +++ b/usr/src/uts/common/fs/ufs/ufs_vfsops.c @@ -644,6 +644,9 @@ remountfs(struct vfs *vfsp, dev_t dev, void *raw_argsp, int args_len) fspt = (struct fs *)tpt->b_un.b_addr; if (((fspt->fs_magic != FS_MAGIC) && (fspt->fs_magic != MTB_UFS_MAGIC)) || + (fspt->fs_magic == FS_MAGIC && + (fspt->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + fspt->fs_version != UFS_VERSION_MIN)) || (fspt->fs_magic == MTB_UFS_MAGIC && (fspt->fs_version > MTB_UFS_VERSION_1 || fspt->fs_version < MTB_UFS_VERSION_MIN)) || @@ -841,13 +844,20 @@ mountfs(struct vfs *vfsp, enum whymountroot why, struct vnode *devvp, if (tp->b_flags & B_ERROR) goto out; fsp = (struct fs *)tp->b_un.b_addr; -#ifdef _LP64 + if ((fsp->fs_magic != FS_MAGIC) && (fsp->fs_magic != MTB_UFS_MAGIC)) { - if (why == ROOT_INIT) { - cmn_err(CE_NOTE, - "mount: not a UFS magic number (0x%x)", - fsp->fs_magic); - } + cmn_err(CE_NOTE, + "mount: not a UFS magic number (0x%x)", fsp->fs_magic); + error = EINVAL; + goto out; + } + + if ((fsp->fs_magic == FS_MAGIC) && + (fsp->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + fsp->fs_version != UFS_VERSION_MIN)) { + cmn_err(CE_NOTE, + "mount: unrecognized version of UFS on-disk format: %d", + fsp->fs_version); error = EINVAL; goto out; } @@ -862,17 +872,8 @@ mountfs(struct vfs *vfsp, enum whymountroot why, struct vnode *devvp, goto out; } -#else +#ifndef _LP64 if (fsp->fs_magic == MTB_UFS_MAGIC) { - if (fsp->fs_version > MTB_UFS_VERSION_1 || - fsp->fs_version < MTB_UFS_VERSION_MIN) { - cmn_err(CE_NOTE, - "mount: unrecognized version of UFS" - " on-disk format: %d", fsp->fs_version); - error = EINVAL; - goto out; - } - /* * Find the size of the device in sectors. If the * the size in sectors is greater than INT_MAX, it's @@ -894,13 +895,8 @@ mountfs(struct vfs *vfsp, enum whymountroot why, struct vnode *devvp, goto out; } - } else if (fsp->fs_magic != FS_MAGIC) { - cmn_err(CE_NOTE, - "mount: not a UFS magic number (0x%x)", fsp->fs_magic); - error = EINVAL; - goto out; } -#endif /* _LP64 */ +#endif if (fsp->fs_bsize > MAXBSIZE || fsp->fs_frag > MAXFRAG || fsp->fs_bsize < sizeof (struct fs) || fsp->fs_bsize < PAGESIZE) { @@ -1749,6 +1745,10 @@ ufs_statvfs(struct vfs *vfsp, struct statvfs64 *sp) fsp = ufsvfsp->vfs_fs; if ((fsp->fs_magic != FS_MAGIC) && (fsp->fs_magic != MTB_UFS_MAGIC)) return (EINVAL); + if (fsp->fs_magic == FS_MAGIC && + (fsp->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && + fsp->fs_version != UFS_VERSION_MIN)) + return (EINVAL); if (fsp->fs_magic == MTB_UFS_MAGIC && (fsp->fs_version > MTB_UFS_VERSION_1 || fsp->fs_version < MTB_UFS_VERSION_MIN)) diff --git a/usr/src/uts/common/sys/fs/ufs_fs.h b/usr/src/uts/common/sys/fs/ufs_fs.h index 4a7b17edef..ae6b1baa16 100644 --- a/usr/src/uts/common/sys/fs/ufs_fs.h +++ b/usr/src/uts/common/sys/fs/ufs_fs.h @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -52,12 +52,13 @@ extern "C" { /* * The following values are minor release values for UFS. - * The fs_version field in the superblock will equal one of them - * if the file system's magic number is MTB_UFS_MAGIC. + * The fs_version field in the superblock will equal one of them. */ #define MTB_UFS_VERSION_MIN 1 #define MTB_UFS_VERSION_1 1 +#define UFS_VERSION_MIN 0 +#define UFS_EFISTYLE4NONEFI_VERSION_2 2 /* * Each disk drive contains some number of file systems. @@ -151,6 +152,20 @@ extern "C" { #define MAXMNTLEN 512 #define MAXCSBUFS 32 +#define LABEL_TYPE_VTOC 1 +#define LABEL_TYPE_EFI 2 +#define LABEL_TYPE_OTHER 3 + +/* + * The following constant is taken from the ANSI T13 ATA Specification + * and defines the maximum size (in sectors) that an ATA disk can be + * and still has to provide CHS translation. For a disk above this + * size all sectors are to be accessed via their LBA address. This + * makes a good cut off value to move from disk provided geometry + * to the predefined defaults used in efi label disks. + */ +#define CHSLIMIT (63 * 256 * 1024) + /* * Per cylinder group information; summarized in blocks allocated * from first cylinder group data blocks. These blocks have to be @@ -323,7 +338,7 @@ struct fs { int32_t fs_cpc; /* cyl per cycle in postbl */ short fs_opostbl[16][8]; /* old rotation block list head */ int32_t fs_sparecon[51]; /* reserved for future constants */ - int32_t fs_version; /* minor version of MTB ufs */ + int32_t fs_version; /* minor version of ufs */ int32_t fs_logbno; /* block # of embedded log */ int32_t fs_reclaim; /* reclaim open, deleted files */ int32_t fs_sparecon2; /* reserved for future constant */ |