newfs.c revision 126254
11558Srgrimes/* 298542Smckusick * Copyright (c) 2002 Networks Associates Technology, Inc. 398542Smckusick * All rights reserved. 498542Smckusick * 598542Smckusick * This software was developed for the FreeBSD Project by Marshall 698542Smckusick * Kirk McKusick and Network Associates Laboratories, the Security 798542Smckusick * Research Division of Network Associates, Inc. under DARPA/SPAWAR 898542Smckusick * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS 9110884Smckusick * research program. 1098542Smckusick * 111558Srgrimes * Copyright (c) 1983, 1989, 1993, 1994 121558Srgrimes * The Regents of the University of California. All rights reserved. 131558Srgrimes * 141558Srgrimes * Redistribution and use in source and binary forms, with or without 151558Srgrimes * modification, are permitted provided that the following conditions 161558Srgrimes * are met: 171558Srgrimes * 1. Redistributions of source code must retain the above copyright 181558Srgrimes * notice, this list of conditions and the following disclaimer. 191558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 201558Srgrimes * notice, this list of conditions and the following disclaimer in the 211558Srgrimes * documentation and/or other materials provided with the distribution. 221558Srgrimes * 3. All advertising materials mentioning features or use of this software 231558Srgrimes * must display the following acknowledgement: 241558Srgrimes * This product includes software developed by the University of 251558Srgrimes * California, Berkeley and its contributors. 261558Srgrimes * 4. Neither the name of the University nor the names of its contributors 271558Srgrimes * may be used to endorse or promote products derived from this software 281558Srgrimes * without specific prior written permission. 291558Srgrimes * 301558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 311558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 321558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 331558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 341558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 351558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 361558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 371558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 381558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 391558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 401558Srgrimes * SUCH DAMAGE. 411558Srgrimes */ 421558Srgrimes 43114589Sobrien#if 0 441558Srgrimes#ifndef lint 4537664Scharnierstatic const char copyright[] = 4637664Scharnier"@(#) Copyright (c) 1983, 1989, 1993, 1994\n\ 4737664Scharnier The Regents of the University of California. All rights reserved.\n"; 481558Srgrimes#endif /* not lint */ 491558Srgrimes 501558Srgrimes#ifndef lint 5137664Scharnierstatic char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95"; 52114589Sobrien#endif /* not lint */ 5337664Scharnier#endif 54114589Sobrien#include <sys/cdefs.h> 55114589Sobrien__FBSDID("$FreeBSD: head/sbin/newfs/newfs.c 126254 2004-02-26 01:14:27Z rwatson $"); 561558Srgrimes 571558Srgrimes/* 581558Srgrimes * newfs: friendly front end to mkfs 591558Srgrimes */ 601558Srgrimes#include <sys/param.h> 611558Srgrimes#include <sys/stat.h> 6295357Sphk#include <sys/disk.h> 631558Srgrimes#include <sys/disklabel.h> 641558Srgrimes#include <sys/file.h> 651558Srgrimes#include <sys/mount.h> 661558Srgrimes 6737707Scharnier#include <ufs/ufs/dir.h> 6837707Scharnier#include <ufs/ufs/dinode.h> 691558Srgrimes#include <ufs/ffs/fs.h> 7023682Speter#include <ufs/ufs/ufsmount.h> 711558Srgrimes 721558Srgrimes#include <ctype.h> 7337664Scharnier#include <err.h> 741558Srgrimes#include <errno.h> 751558Srgrimes#include <paths.h> 7693777Sbde#include <stdarg.h> 771558Srgrimes#include <stdio.h> 781558Srgrimes#include <stdlib.h> 791558Srgrimes#include <string.h> 801558Srgrimes#include <syslog.h> 811558Srgrimes#include <unistd.h> 821558Srgrimes 8392717Sphk#include "newfs.h" 841558Srgrimes 851558Srgrimes/* 861558Srgrimes * The following two constants set the default block and fragment sizes. 871558Srgrimes * Both constants must be a power of 2 and meet the following constraints: 881558Srgrimes * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 891558Srgrimes * sectorsize <= DESFRAGSIZE <= DESBLKSIZE 901558Srgrimes * DESBLKSIZE / DESFRAGSIZE <= 8 911558Srgrimes */ 9287661Ssheldonh#define DFL_FRAGSIZE 2048 9387661Ssheldonh#define DFL_BLKSIZE 16384 941558Srgrimes 951558Srgrimes/* 9698542Smckusick * Cylinder groups may have up to MAXBLKSPERCG blocks. The actual 971558Srgrimes * number used depends upon how much information can be stored 98102231Strhodes * in a cylinder group map which must fit in a single file system 9998542Smckusick * block. The default is to use as many as possible blocks per group. 1001558Srgrimes */ 10198542Smckusick#define MAXBLKSPERCG 0x7fffffff /* desired fs_fpg ("infinity") */ 1021558Srgrimes 1031558Srgrimes/* 1041558Srgrimes * MAXBLKPG determines the maximum number of data blocks which are 1051558Srgrimes * placed in a single cylinder group. The default is one indirect 1061558Srgrimes * block worth of data blocks. 1071558Srgrimes */ 10898542Smckusick#define MAXBLKPG(bsize) ((bsize) / sizeof(ufs2_daddr_t)) 1091558Srgrimes 1101558Srgrimes/* 111102231Strhodes * Each file system has a number of inodes statically allocated. 1121558Srgrimes * We allocate one inode slot per NFPI fragments, expecting this 1131558Srgrimes * to be far more than we will ever need. 1141558Srgrimes */ 1151558Srgrimes#define NFPI 4 1161558Srgrimes 117110174Sgordonint Lflag; /* add a volume label */ 118102231Strhodesint Nflag; /* run without writing file system */ 119113751Srwatsonint Oflag = 2; /* file system format (1 => UFS1, 2 => UFS2) */ 12092722Sphkint Rflag; /* regression test */ 121102231Strhodesint Uflag; /* enable soft updates for file system */ 122122785Swesint Eflag = 0; /* exit in middle of newfs for testing */ 123126254Srwatsonint lflag; /* enable multilabel for file system */ 12498542Smckusickquad_t fssize; /* file system size */ 12598542Smckusickint sectorsize; /* bytes/sector */ 1261558Srgrimesint realsectorsize; /* bytes/sector in hardware */ 1271558Srgrimesint fsize = 0; /* fragment size */ 1281558Srgrimesint bsize = 0; /* block size */ 12998542Smckusickint maxbsize = 0; /* maximum clustering */ 13098542Smckusickint maxblkspercg = MAXBLKSPERCG; /* maximum blocks per cylinder group */ 1311558Srgrimesint minfree = MINFREE; /* free space threshold */ 1321558Srgrimesint opt = DEFAULTOPT; /* optimization preference (space or time) */ 1331558Srgrimesint density; /* number of bytes per inode */ 1341558Srgrimesint maxcontig = 0; /* max contiguous blocks to allocate */ 1351558Srgrimesint maxbpg; /* maximum blocks per file in a cyl group */ 13675377Smckusickint avgfilesize = AVFILESIZ;/* expected average file size */ 13775377Smckusickint avgfilesperdir = AFPDIR;/* expected number of files per directory */ 138110174Sgordonu_char *volumelabel = NULL; /* volume label for filesystem */ 139110671Sjmallettstruct uufsd disk; /* libufs disk structure */ 1401558Srgrimes 14192763Sphkstatic char device[MAXPATHLEN]; 14293777Sbdestatic char *disktype; 14393777Sbdestatic int unlabeled; 1441558Srgrimes 14595357Sphkstatic struct disklabel *getdisklabel(char *s); 14695357Sphkstatic void rewritelabel(char *s, struct disklabel *lp); 14793777Sbdestatic void usage(void); 14837664Scharnier 1491558Srgrimesint 15092711Siedowsemain(int argc, char *argv[]) 1511558Srgrimes{ 15292483Sphk struct partition *pp; 15392483Sphk struct disklabel *lp; 1541558Srgrimes struct partition oldpartition; 1551558Srgrimes struct stat st; 15695357Sphk char *cp, *special; 157110174Sgordon int ch, i; 15895357Sphk off_t mediasize; 1591558Srgrimes 16092717Sphk while ((ch = getopt(argc, argv, 161126254Srwatson "EL:NO:RS:T:Ua:b:c:d:e:f:g:h:i:lm:o:s:")) != -1) 1621558Srgrimes switch (ch) { 163122785Swes case 'E': 164122785Swes Eflag++; 165122785Swes break; 166110174Sgordon case 'L': 167110174Sgordon volumelabel = optarg; 168110174Sgordon i = -1; 169110174Sgordon while (isalnum(volumelabel[++i])); 170110174Sgordon if (volumelabel[i] != '\0') { 171110174Sgordon errx(1, "bad volume label. Valid characters are alphanumerics."); 172110174Sgordon } 173110174Sgordon if (strlen(volumelabel) >= MAXVOLLEN) { 174110174Sgordon errx(1, "bad volume label. Length is longer than %d.", 175110174Sgordon MAXVOLLEN); 176110174Sgordon } 177110174Sgordon Lflag = 1; 178110174Sgordon break; 1791558Srgrimes case 'N': 1801558Srgrimes Nflag = 1; 1811558Srgrimes break; 18298542Smckusick case 'O': 18398542Smckusick if ((Oflag = atoi(optarg)) < 1 || Oflag > 2) 184102231Strhodes errx(1, "%s: bad file system format value", 18598542Smckusick optarg); 18698542Smckusick break; 18792722Sphk case 'R': 18892722Sphk Rflag = 1; 18992722Sphk break; 1901558Srgrimes case 'S': 1911558Srgrimes if ((sectorsize = atoi(optarg)) <= 0) 19295357Sphk errx(1, "%s: bad sector size", optarg); 1931558Srgrimes break; 1941558Srgrimes case 'T': 1951558Srgrimes disktype = optarg; 1961558Srgrimes break; 19775078Sobrien case 'U': 19875078Sobrien Uflag = 1; 19975078Sobrien break; 2001558Srgrimes case 'a': 2011558Srgrimes if ((maxcontig = atoi(optarg)) <= 0) 20295357Sphk errx(1, "%s: bad maximum contiguous blocks", 2031558Srgrimes optarg); 2041558Srgrimes break; 2051558Srgrimes case 'b': 2061558Srgrimes if ((bsize = atoi(optarg)) < MINBSIZE) 207107412Smckusick errx(1, "%s: block size too small, min is %d", 208107412Smckusick optarg, MINBSIZE); 209107412Smckusick if (bsize > MAXBSIZE) 210107412Smckusick errx(1, "%s: block size too large, max is %d", 211107412Smckusick optarg, MAXBSIZE); 2121558Srgrimes break; 2131558Srgrimes case 'c': 21498542Smckusick if ((maxblkspercg = atoi(optarg)) <= 0) 21598542Smckusick errx(1, "%s: bad blocks per cylinder group", 21698542Smckusick optarg); 2171558Srgrimes break; 21898542Smckusick case 'd': 21998542Smckusick if ((maxbsize = atoi(optarg)) < MINBSIZE) 22098542Smckusick errx(1, "%s: bad extent block size", optarg); 22198542Smckusick break; 2221558Srgrimes case 'e': 2231558Srgrimes if ((maxbpg = atoi(optarg)) <= 0) 22498542Smckusick errx(1, "%s: bad blocks per file in a cylinder group", 2251558Srgrimes optarg); 2261558Srgrimes break; 2271558Srgrimes case 'f': 2281558Srgrimes if ((fsize = atoi(optarg)) <= 0) 22995357Sphk errx(1, "%s: bad fragment size", optarg); 2301558Srgrimes break; 23175377Smckusick case 'g': 23275377Smckusick if ((avgfilesize = atoi(optarg)) <= 0) 23395357Sphk errx(1, "%s: bad average file size", optarg); 23475377Smckusick break; 23575377Smckusick case 'h': 23675377Smckusick if ((avgfilesperdir = atoi(optarg)) <= 0) 23798542Smckusick errx(1, "%s: bad average files per dir", optarg); 23875377Smckusick break; 2391558Srgrimes case 'i': 2401558Srgrimes if ((density = atoi(optarg)) <= 0) 24195357Sphk errx(1, "%s: bad bytes per inode", optarg); 2421558Srgrimes break; 243126254Srwatson case 'l': 244126254Srwatson lflag = 1; 245126254Srwatson break; 2461558Srgrimes case 'm': 2471558Srgrimes if ((minfree = atoi(optarg)) < 0 || minfree > 99) 24895357Sphk errx(1, "%s: bad free space %%", optarg); 2491558Srgrimes break; 2501558Srgrimes case 'o': 25177420Sphk if (strcmp(optarg, "space") == 0) 25277420Sphk opt = FS_OPTSPACE; 25377420Sphk else if (strcmp(optarg, "time") == 0) 25477420Sphk opt = FS_OPTTIME; 25577420Sphk else 25695357Sphk errx(1, 25792533Sbde "%s: unknown optimization preference: use `space' or `time'", 25892533Sbde optarg); 2591558Srgrimes break; 2601558Srgrimes case 's': 2611558Srgrimes if ((fssize = atoi(optarg)) <= 0) 262102231Strhodes errx(1, "%s: bad file system size", optarg); 2631558Srgrimes break; 2641558Srgrimes case '?': 2651558Srgrimes default: 2661558Srgrimes usage(); 2671558Srgrimes } 2681558Srgrimes argc -= optind; 2691558Srgrimes argv += optind; 2701558Srgrimes 27195357Sphk if (argc != 1) 2721558Srgrimes usage(); 2731558Srgrimes 2741558Srgrimes special = argv[0]; 27523682Speter cp = strrchr(special, '/'); 2761558Srgrimes if (cp == 0) { 2771558Srgrimes /* 27892533Sbde * No path prefix; try prefixing _PATH_DEV. 2791558Srgrimes */ 28092533Sbde snprintf(device, sizeof(device), "%s%s", _PATH_DEV, special); 2811558Srgrimes special = device; 2821558Srgrimes } 2831558Srgrimes 284110671Sjmallett if (ufs_disk_fillout_blank(&disk, special) == -1 || 285110671Sjmallett (!Nflag && ufs_disk_write(&disk) == -1)) { 286110671Sjmallett if (disk.d_error != NULL) 287110671Sjmallett errx(1, "%s: %s", special, disk.d_error); 288110671Sjmallett else 289110671Sjmallett err(1, "%s", special); 290110671Sjmallett } 291110671Sjmallett if (fstat(disk.d_fd, &st) < 0) 29295357Sphk err(1, "%s", special); 29395357Sphk if ((st.st_mode & S_IFMT) != S_IFCHR) 29495357Sphk errx(1, "%s: not a character-special device", special); 2951558Srgrimes 296110671Sjmallett if (sectorsize == 0) 297110671Sjmallett ioctl(disk.d_fd, DIOCGSECTORSIZE, §orsize); 298110671Sjmallett if (sectorsize && !ioctl(disk.d_fd, DIOCGMEDIASIZE, &mediasize)) { 29995357Sphk if (fssize == 0) 30095357Sphk fssize = mediasize / sectorsize; 30195357Sphk else if (fssize > mediasize / sectorsize) 302102231Strhodes errx(1, "%s: maximum file system size is %u", 30395357Sphk special, (u_int)(mediasize / sectorsize)); 3041558Srgrimes } 30595357Sphk pp = NULL; 30695357Sphk lp = getdisklabel(special); 30795357Sphk if (lp != NULL) { 30895357Sphk cp = strchr(special, '\0'); 30995357Sphk cp--; 31095360Sphk if ((*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 311102231Strhodes errx(1, "%s: can't figure out file system partition", 31295357Sphk special); 31395360Sphk if (isdigit(*cp)) 31495360Sphk pp = &lp->d_partitions[RAW_PART]; 31595357Sphk else 31695357Sphk pp = &lp->d_partitions[*cp - 'a']; 31795357Sphk oldpartition = *pp; 31895357Sphk if (pp->p_size == 0) 31995357Sphk errx(1, "%s: `%c' partition is unavailable", 32095357Sphk special, *cp); 32195357Sphk if (pp->p_fstype == FS_BOOT) 32295357Sphk errx(1, "%s: `%c' partition overlaps boot program", 32395357Sphk special, *cp); 32495357Sphk if (fssize == 0) 32595357Sphk fssize = pp->p_size; 32695357Sphk if (fssize > pp->p_size) 32795357Sphk errx(1, 328102231Strhodes "%s: maximum file system size %d", special, pp->p_size); 32995357Sphk if (sectorsize == 0) 33095357Sphk sectorsize = lp->d_secsize; 33195357Sphk if (fsize == 0) 33295357Sphk fsize = pp->p_fsize; 33395357Sphk if (bsize == 0) 33495357Sphk bsize = pp->p_frag * pp->p_fsize; 3351558Srgrimes } 33695357Sphk if (sectorsize <= 0) 33795357Sphk errx(1, "%s: no default sector size", special); 33895357Sphk if (fsize <= 0) 33995357Sphk fsize = MAX(DFL_FRAGSIZE, sectorsize); 34095357Sphk if (bsize <= 0) 34195357Sphk bsize = MIN(DFL_BLKSIZE, 8 * fsize); 34298542Smckusick if (maxbsize == 0) 34398542Smckusick maxbsize = bsize; 3441558Srgrimes /* 3451558Srgrimes * Maxcontig sets the default for the maximum number of blocks 346102231Strhodes * that may be allocated sequentially. With file system clustering 3471558Srgrimes * it is possible to allocate contiguous blocks up to the maximum 3481558Srgrimes * transfer size permitted by the controller or buffering. 3491558Srgrimes */ 3501558Srgrimes if (maxcontig == 0) 35198542Smckusick maxcontig = MAX(1, MAXPHYS / bsize); 3521558Srgrimes if (density == 0) 3531558Srgrimes density = NFPI * fsize; 3541558Srgrimes if (minfree < MINFREE && opt != FS_OPTSPACE) { 3551558Srgrimes fprintf(stderr, "Warning: changing optimization to space "); 3561558Srgrimes fprintf(stderr, "because minfree is less than %d%%\n", MINFREE); 3571558Srgrimes opt = FS_OPTSPACE; 3581558Srgrimes } 3591558Srgrimes if (maxbpg == 0) 3601558Srgrimes maxbpg = MAXBLKPG(bsize); 3611558Srgrimes realsectorsize = sectorsize; 3621558Srgrimes if (sectorsize != DEV_BSIZE) { /* XXX */ 36320061Ssos int secperblk = sectorsize / DEV_BSIZE; 36420061Ssos 36520061Ssos sectorsize = DEV_BSIZE; 36620061Ssos fssize *= secperblk; 367104308Sphk if (pp != NULL) 36895357Sphk pp->p_size *= secperblk; 36920061Ssos } 37095357Sphk mkfs(pp, special); 37195357Sphk if (!unlabeled) { 37295357Sphk if (realsectorsize != DEV_BSIZE) 37398542Smckusick pp->p_size /= realsectorsize / DEV_BSIZE; 37495357Sphk if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 37595357Sphk rewritelabel(special, lp); 37695357Sphk } 377110671Sjmallett ufs_disk_close(&disk); 3781558Srgrimes exit(0); 3791558Srgrimes} 3801558Srgrimes 3811558Srgrimesstruct disklabel * 38295357Sphkgetdisklabel(char *s) 3831558Srgrimes{ 3841558Srgrimes static struct disklabel lab; 38595357Sphk struct disklabel *lp; 3861558Srgrimes 387110671Sjmallett if (!ioctl(disk.d_fd, DIOCGDINFO, (char *)&lab)) 38895357Sphk return (&lab); 38995357Sphk unlabeled++; 39095357Sphk if (disktype) { 39195357Sphk lp = getdiskbyname(disktype); 39295357Sphk if (lp != NULL) 3931558Srgrimes return (lp); 3941558Srgrimes } 39595357Sphk return (NULL); 3961558Srgrimes} 3971558Srgrimes 39877420Sphkvoid 39995357Sphkrewritelabel(char *s, struct disklabel *lp) 40037775Sbde{ 40137775Sbde if (unlabeled) 40237775Sbde return; 40337775Sbde lp->d_checksum = 0; 40437775Sbde lp->d_checksum = dkcksum(lp); 405110671Sjmallett if (ioctl(disk.d_fd, DIOCWDINFO, (char *)lp) < 0) 406103797Sphk warn("ioctl (WDINFO): %s: can't rewrite disk label", s); 40737775Sbde} 40837775Sbde 40937664Scharnierstatic void 410110065Sjmallettusage() 4111558Srgrimes{ 41277420Sphk fprintf(stderr, 41377420Sphk "usage: %s [ -fsoptions ] special-device%s\n", 41495357Sphk getprogname(), 41577420Sphk " [device-type]"); 4161558Srgrimes fprintf(stderr, "where fsoptions are:\n"); 417110174Sgordon fprintf(stderr, "\t-L volume label to add to superblock\n"); 4181558Srgrimes fprintf(stderr, 419102231Strhodes "\t-N do not create file system, just print out parameters\n"); 420102231Strhodes fprintf(stderr, "\t-O file system format: 1 => UFS1, 2 => UFS2\n"); 42192722Sphk fprintf(stderr, "\t-R regression test, supress random factors\n"); 4221558Srgrimes fprintf(stderr, "\t-S sector size\n"); 4231558Srgrimes fprintf(stderr, "\t-T disktype\n"); 42475078Sobrien fprintf(stderr, "\t-U enable soft updates\n"); 4251558Srgrimes fprintf(stderr, "\t-a maximum contiguous blocks\n"); 4261558Srgrimes fprintf(stderr, "\t-b block size\n"); 42798542Smckusick fprintf(stderr, "\t-c blocks per cylinders group\n"); 42898542Smckusick fprintf(stderr, "\t-d maximum extent size\n"); 4291558Srgrimes fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 4301558Srgrimes fprintf(stderr, "\t-f frag size\n"); 43175377Smckusick fprintf(stderr, "\t-g average file size\n"); 43275377Smckusick fprintf(stderr, "\t-h average files per directory\n"); 4331558Srgrimes fprintf(stderr, "\t-i number of bytes per inode\n"); 4341558Srgrimes fprintf(stderr, "\t-m minimum free space %%\n"); 4351558Srgrimes fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 43698542Smckusick fprintf(stderr, "\t-s file systemsize (sectors)\n"); 4371558Srgrimes exit(1); 4381558Srgrimes} 439