121184Sdist /* 235484Sbostic * Copyright (c) 1983 The Regents of the University of California. 335484Sbostic * All rights reserved. 435484Sbostic * 535484Sbostic * Redistribution and use in source and binary forms are permitted 635484Sbostic * provided that the above copyright notice and this paragraph are 735484Sbostic * duplicated in all such forms and that any documentation, 835484Sbostic * advertising materials, and other materials related to such 935484Sbostic * distribution and use acknowledge that the software was developed 1035484Sbostic * by the University of California, Berkeley. The name of the 1135484Sbostic * University may not be used to endorse or promote products derived 1235484Sbostic * from this software without specific prior written permission. 1335484Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435484Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535484Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621184Sdist */ 1721184Sdist 1811288Smckusick #ifndef lint 1921184Sdist char copyright[] = 2035484Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 2121184Sdist All rights reserved.\n"; 2235484Sbostic #endif /* not lint */ 2311288Smckusick 2421184Sdist #ifndef lint 25*38514Sbostic static char sccsid[] = "@(#)tunefs.c 5.9 (Berkeley) 07/30/89"; 2635484Sbostic #endif /* not lint */ 2721184Sdist 2811288Smckusick /* 2911288Smckusick * tunefs: change layout parameters to an existing file system. 3011288Smckusick */ 3111288Smckusick #include <sys/param.h> 3211288Smckusick #include <sys/stat.h> 33*38514Sbostic #include <sys/time.h> 34*38514Sbostic #include <sys/vnode.h> 35*38514Sbostic #include <ufs/inode.h> 36*38514Sbostic #include <ufs/fs.h> 3737959Sbostic #include <fstab.h> 3813120Ssam #include <stdio.h> 3937959Sbostic #include <paths.h> 4013120Ssam 4111288Smckusick union { 4211288Smckusick struct fs sb; 4311288Smckusick char pad[MAXBSIZE]; 4411288Smckusick } sbun; 4511288Smckusick #define sblock sbun.sb 4611288Smckusick 4711288Smckusick int fi; 4830558Smckusick long dev_bsize = 1; 4911288Smckusick 5011288Smckusick main(argc, argv) 5111288Smckusick int argc; 5211288Smckusick char *argv[]; 5311288Smckusick { 5411288Smckusick char *cp, *special, *name; 5511288Smckusick struct stat st; 5611288Smckusick int i; 5711288Smckusick int Aflag = 0; 5824700Smckusick struct fstab *fs; 5924700Smckusick char *chg[2], device[MAXPATHLEN]; 6011288Smckusick 6111288Smckusick argc--, argv++; 6211288Smckusick if (argc < 2) 6311288Smckusick goto usage; 6411288Smckusick special = argv[argc - 1]; 6513120Ssam fs = getfsfile(special); 6613120Ssam if (fs) 6713120Ssam special = fs->fs_spec; 6811288Smckusick again: 6911288Smckusick if (stat(special, &st) < 0) { 7011288Smckusick if (*special != '/') { 7111288Smckusick if (*special == 'r') 7211288Smckusick special++; 7337959Sbostic (void)sprintf(device, "%s/%s", _PATH_DEV, special); 7432453Sbostic special = device; 7511288Smckusick goto again; 7611288Smckusick } 7711288Smckusick fprintf(stderr, "tunefs: "); perror(special); 7811288Smckusick exit(1); 7911288Smckusick } 8011288Smckusick if ((st.st_mode & S_IFMT) != S_IFBLK && 8111288Smckusick (st.st_mode & S_IFMT) != S_IFCHR) 8211288Smckusick fatal("%s: not a block or character device", special); 8311288Smckusick getsb(&sblock, special); 8411288Smckusick for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { 8511288Smckusick for (cp = &argv[0][1]; *cp; cp++) 8611288Smckusick switch (*cp) { 8711288Smckusick 8811288Smckusick case 'A': 8911288Smckusick Aflag++; 9011288Smckusick continue; 9111288Smckusick 9211288Smckusick case 'a': 9311288Smckusick name = "maximum contiguous block count"; 9411288Smckusick if (argc < 1) 9511288Smckusick fatal("-a: missing %s", name); 9611288Smckusick argc--, argv++; 9711288Smckusick i = atoi(*argv); 9811288Smckusick if (i < 1) 9911288Smckusick fatal("%s: %s must be >= 1", 10011288Smckusick *argv, name); 10111288Smckusick fprintf(stdout, "%s changes from %d to %d\n", 10211288Smckusick name, sblock.fs_maxcontig, i); 10311288Smckusick sblock.fs_maxcontig = i; 10411288Smckusick continue; 10511288Smckusick 10611288Smckusick case 'd': 10711288Smckusick name = 10811288Smckusick "rotational delay between contiguous blocks"; 10911288Smckusick if (argc < 1) 11011288Smckusick fatal("-d: missing %s", name); 11111288Smckusick argc--, argv++; 11211288Smckusick i = atoi(*argv); 11311288Smckusick fprintf(stdout, 11411288Smckusick "%s changes from %dms to %dms\n", 11511288Smckusick name, sblock.fs_rotdelay, i); 11611288Smckusick sblock.fs_rotdelay = i; 11711288Smckusick continue; 11811288Smckusick 11911288Smckusick case 'e': 12011288Smckusick name = 12111288Smckusick "maximum blocks per file in a cylinder group"; 12211288Smckusick if (argc < 1) 12311288Smckusick fatal("-e: missing %s", name); 12411288Smckusick argc--, argv++; 12511288Smckusick i = atoi(*argv); 12611288Smckusick if (i < 1) 12711288Smckusick fatal("%s: %s must be >= 1", 12811288Smckusick *argv, name); 12911288Smckusick fprintf(stdout, "%s changes from %d to %d\n", 13011288Smckusick name, sblock.fs_maxbpg, i); 13111288Smckusick sblock.fs_maxbpg = i; 13211288Smckusick continue; 13311288Smckusick 13411288Smckusick case 'm': 13511288Smckusick name = "minimum percentage of free space"; 13611288Smckusick if (argc < 1) 13711288Smckusick fatal("-m: missing %s", name); 13811288Smckusick argc--, argv++; 13911288Smckusick i = atoi(*argv); 14011288Smckusick if (i < 0 || i > 99) 14111288Smckusick fatal("%s: bad %s", *argv, name); 14211288Smckusick fprintf(stdout, 14311288Smckusick "%s changes from %d%% to %d%%\n", 14411288Smckusick name, sblock.fs_minfree, i); 14511288Smckusick sblock.fs_minfree = i; 14624704Smckusick if (i >= 10 && sblock.fs_optim == FS_OPTSPACE) 14724704Smckusick fprintf(stdout, "should optimize %s", 14824704Smckusick "for time with minfree >= 10%\n"); 14924704Smckusick if (i < 10 && sblock.fs_optim == FS_OPTTIME) 15024704Smckusick fprintf(stdout, "should optimize %s", 15124704Smckusick "for space with minfree < 10%\n"); 15211288Smckusick continue; 15311288Smckusick 15424700Smckusick case 'o': 15524700Smckusick name = "optimization preference"; 15624700Smckusick if (argc < 1) 15724700Smckusick fatal("-o: missing %s", name); 15824700Smckusick argc--, argv++; 15924700Smckusick chg[FS_OPTSPACE] = "space"; 16024700Smckusick chg[FS_OPTTIME] = "time"; 16124700Smckusick if (strcmp(*argv, chg[FS_OPTSPACE]) == 0) 16224700Smckusick i = FS_OPTSPACE; 16324700Smckusick else if (strcmp(*argv, chg[FS_OPTTIME]) == 0) 16424700Smckusick i = FS_OPTTIME; 16524700Smckusick else 16624700Smckusick fatal("%s: bad %s (options are `space' or `time')", 16724700Smckusick *argv, name); 16824700Smckusick if (sblock.fs_optim == i) { 16924700Smckusick fprintf(stdout, 17024700Smckusick "%s remains unchanged as %s\n", 17124700Smckusick name, chg[i]); 17224700Smckusick continue; 17324700Smckusick } 17424700Smckusick fprintf(stdout, 17524700Smckusick "%s changes from %s to %s\n", 17624700Smckusick name, chg[sblock.fs_optim], chg[i]); 17724700Smckusick sblock.fs_optim = i; 17824704Smckusick if (sblock.fs_minfree >= 10 && i == FS_OPTSPACE) 17924704Smckusick fprintf(stdout, "should optimize %s", 18024704Smckusick "for time with minfree >= 10%\n"); 18124704Smckusick if (sblock.fs_minfree < 10 && i == FS_OPTTIME) 18224704Smckusick fprintf(stdout, "should optimize %s", 18324704Smckusick "for space with minfree < 10%\n"); 18424700Smckusick continue; 18524700Smckusick 18611288Smckusick default: 18711288Smckusick fatal("-%c: unknown flag", *cp); 18811288Smckusick } 18911288Smckusick } 19011288Smckusick if (argc != 1) 19111288Smckusick goto usage; 19230558Smckusick bwrite(SBOFF / dev_bsize, (char *)&sblock, SBSIZE); 19311288Smckusick if (Aflag) 19411288Smckusick for (i = 0; i < sblock.fs_ncg; i++) 19511288Smckusick bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 19611288Smckusick (char *)&sblock, SBSIZE); 19711288Smckusick close(fi); 19811288Smckusick exit(0); 19911288Smckusick usage: 20011288Smckusick fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); 20111288Smckusick fprintf(stderr, "where tuneup-options are:\n"); 20213555Ssam fprintf(stderr, "\t-a maximum contiguous blocks\n"); 20311288Smckusick fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 20411288Smckusick fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 20511288Smckusick fprintf(stderr, "\t-m minimum percentage of free space\n"); 20624700Smckusick fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 20711288Smckusick exit(2); 20811288Smckusick } 20911288Smckusick 21011288Smckusick getsb(fs, file) 21111288Smckusick register struct fs *fs; 21211288Smckusick char *file; 21311288Smckusick { 21411288Smckusick 21511288Smckusick fi = open(file, 2); 21611288Smckusick if (fi < 0) { 21711288Smckusick fprintf(stderr, "cannot open"); 21811288Smckusick perror(file); 21911288Smckusick exit(3); 22011288Smckusick } 22130558Smckusick if (bread(SBOFF, (char *)fs, SBSIZE)) { 22211288Smckusick fprintf(stderr, "bad super block"); 22311288Smckusick perror(file); 22411288Smckusick exit(4); 22511288Smckusick } 22611288Smckusick if (fs->fs_magic != FS_MAGIC) { 22711288Smckusick fprintf(stderr, "%s: bad magic number\n", file); 22811288Smckusick exit(5); 22911288Smckusick } 23030558Smckusick dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 23111288Smckusick } 23211288Smckusick 23311288Smckusick bwrite(blk, buf, size) 23411288Smckusick char *buf; 23511288Smckusick daddr_t blk; 23611288Smckusick register size; 23711288Smckusick { 23830558Smckusick if (lseek(fi, blk * dev_bsize, 0) < 0) { 23911288Smckusick perror("FS SEEK"); 24011288Smckusick exit(6); 24111288Smckusick } 24211288Smckusick if (write(fi, buf, size) != size) { 24311288Smckusick perror("FS WRITE"); 24411288Smckusick exit(7); 24511288Smckusick } 24611288Smckusick } 24711288Smckusick 24811288Smckusick bread(bno, buf, cnt) 24911288Smckusick daddr_t bno; 25011288Smckusick char *buf; 25111288Smckusick { 25211288Smckusick register i; 25311288Smckusick 25430558Smckusick if (lseek(fi, bno * dev_bsize, 0) < 0) 25511288Smckusick return(1); 25611288Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 25711288Smckusick for(i=0; i<sblock.fs_bsize; i++) 25811288Smckusick buf[i] = 0; 25911288Smckusick return (1); 26011288Smckusick } 26111288Smckusick return (0); 26211288Smckusick } 26311288Smckusick 26411288Smckusick /* VARARGS1 */ 26511288Smckusick fatal(fmt, arg1, arg2) 26611288Smckusick char *fmt, *arg1, *arg2; 26711288Smckusick { 26811288Smckusick 26911295Ssam fprintf(stderr, "tunefs: "); 27011288Smckusick fprintf(stderr, fmt, arg1, arg2); 27111288Smckusick putc('\n', stderr); 27211288Smckusick exit(10); 27311288Smckusick } 274