1*21184Sdist /* 2*21184Sdist * Copyright (c) 1983 Regents of the University of California. 3*21184Sdist * All rights reserved. The Berkeley software License Agreement 4*21184Sdist * specifies the terms and conditions for redistribution. 5*21184Sdist */ 6*21184Sdist 711288Smckusick #ifndef lint 8*21184Sdist char copyright[] = 9*21184Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*21184Sdist All rights reserved.\n"; 11*21184Sdist #endif not lint 1211288Smckusick 13*21184Sdist #ifndef lint 14*21184Sdist static char sccsid[] = "@(#)tunefs.c 5.1 (Berkeley) 05/28/85"; 15*21184Sdist #endif not lint 16*21184Sdist 1711288Smckusick /* 1811288Smckusick * tunefs: change layout parameters to an existing file system. 1911288Smckusick */ 2011288Smckusick 2111288Smckusick #include <sys/param.h> 2211288Smckusick #include <sys/stat.h> 2311288Smckusick #include <sys/fs.h> 2411288Smckusick #include <sys/inode.h> 2511288Smckusick 2613120Ssam #include <stdio.h> 2713120Ssam #include <fstab.h> 2813120Ssam 2911288Smckusick union { 3011288Smckusick struct fs sb; 3111288Smckusick char pad[MAXBSIZE]; 3211288Smckusick } sbun; 3311288Smckusick #define sblock sbun.sb 3411288Smckusick 3511288Smckusick int fi; 3611288Smckusick 3711288Smckusick main(argc, argv) 3811288Smckusick int argc; 3911288Smckusick char *argv[]; 4011288Smckusick { 4111288Smckusick char *cp, *special, *name; 4211288Smckusick struct stat st; 4311288Smckusick int i; 4411288Smckusick int Aflag = 0; 4511288Smckusick char device[MAXPATHLEN]; 4611288Smckusick extern char *sprintf(); 4713120Ssam struct fstab *fs; 4811288Smckusick 4911288Smckusick argc--, argv++; 5011288Smckusick if (argc < 2) 5111288Smckusick goto usage; 5211288Smckusick special = argv[argc - 1]; 5313120Ssam fs = getfsfile(special); 5413120Ssam if (fs) 5513120Ssam special = fs->fs_spec; 5611288Smckusick again: 5711288Smckusick if (stat(special, &st) < 0) { 5811288Smckusick if (*special != '/') { 5911288Smckusick if (*special == 'r') 6011288Smckusick special++; 6111288Smckusick special = sprintf(device, "/dev/%s", special); 6211288Smckusick goto again; 6311288Smckusick } 6411288Smckusick fprintf(stderr, "tunefs: "); perror(special); 6511288Smckusick exit(1); 6611288Smckusick } 6711288Smckusick if ((st.st_mode & S_IFMT) != S_IFBLK && 6811288Smckusick (st.st_mode & S_IFMT) != S_IFCHR) 6911288Smckusick fatal("%s: not a block or character device", special); 7011288Smckusick getsb(&sblock, special); 7111288Smckusick for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { 7211288Smckusick for (cp = &argv[0][1]; *cp; cp++) 7311288Smckusick switch (*cp) { 7411288Smckusick 7511288Smckusick case 'A': 7611288Smckusick Aflag++; 7711288Smckusick continue; 7811288Smckusick 7911288Smckusick case 'a': 8011288Smckusick name = "maximum contiguous block count"; 8111288Smckusick if (argc < 1) 8211288Smckusick fatal("-a: missing %s", name); 8311288Smckusick argc--, argv++; 8411288Smckusick i = atoi(*argv); 8511288Smckusick if (i < 1) 8611288Smckusick fatal("%s: %s must be >= 1", 8711288Smckusick *argv, name); 8811288Smckusick fprintf(stdout, "%s changes from %d to %d\n", 8911288Smckusick name, sblock.fs_maxcontig, i); 9011288Smckusick sblock.fs_maxcontig = i; 9111288Smckusick continue; 9211288Smckusick 9311288Smckusick case 'd': 9411288Smckusick name = 9511288Smckusick "rotational delay between contiguous blocks"; 9611288Smckusick if (argc < 1) 9711288Smckusick fatal("-d: missing %s", name); 9811288Smckusick argc--, argv++; 9911288Smckusick i = atoi(*argv); 10011288Smckusick if (i < 0) 10111288Smckusick fatal("%s: bad %s", *argv, name); 10211288Smckusick fprintf(stdout, 10311288Smckusick "%s changes from %dms to %dms\n", 10411288Smckusick name, sblock.fs_rotdelay, i); 10511288Smckusick sblock.fs_rotdelay = i; 10611288Smckusick continue; 10711288Smckusick 10811288Smckusick case 'e': 10911288Smckusick name = 11011288Smckusick "maximum blocks per file in a cylinder group"; 11111288Smckusick if (argc < 1) 11211288Smckusick fatal("-e: missing %s", name); 11311288Smckusick argc--, argv++; 11411288Smckusick i = atoi(*argv); 11511288Smckusick if (i < 1) 11611288Smckusick fatal("%s: %s must be >= 1", 11711288Smckusick *argv, name); 11811288Smckusick fprintf(stdout, "%s changes from %d to %d\n", 11911288Smckusick name, sblock.fs_maxbpg, i); 12011288Smckusick sblock.fs_maxbpg = i; 12111288Smckusick continue; 12211288Smckusick 12311288Smckusick case 'm': 12411288Smckusick name = "minimum percentage of free space"; 12511288Smckusick if (argc < 1) 12611288Smckusick fatal("-m: missing %s", name); 12711288Smckusick argc--, argv++; 12811288Smckusick i = atoi(*argv); 12911288Smckusick if (i < 0 || i > 99) 13011288Smckusick fatal("%s: bad %s", *argv, name); 13111288Smckusick fprintf(stdout, 13211288Smckusick "%s changes from %d%% to %d%%\n", 13311288Smckusick name, sblock.fs_minfree, i); 13411288Smckusick sblock.fs_minfree = i; 13511288Smckusick continue; 13611288Smckusick 13711288Smckusick default: 13811288Smckusick fatal("-%c: unknown flag", *cp); 13911288Smckusick } 14011288Smckusick } 14111288Smckusick if (argc != 1) 14211288Smckusick goto usage; 14311288Smckusick bwrite(SBLOCK, (char *)&sblock, SBSIZE); 14411288Smckusick if (Aflag) 14511288Smckusick for (i = 0; i < sblock.fs_ncg; i++) 14611288Smckusick bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 14711288Smckusick (char *)&sblock, SBSIZE); 14811288Smckusick close(fi); 14911288Smckusick exit(0); 15011288Smckusick usage: 15111288Smckusick fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); 15211288Smckusick fprintf(stderr, "where tuneup-options are:\n"); 15313555Ssam fprintf(stderr, "\t-a maximum contiguous blocks\n"); 15411288Smckusick fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 15511288Smckusick fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 15611288Smckusick fprintf(stderr, "\t-m minimum percentage of free space\n"); 15711288Smckusick exit(2); 15811288Smckusick } 15911288Smckusick 16011288Smckusick getsb(fs, file) 16111288Smckusick register struct fs *fs; 16211288Smckusick char *file; 16311288Smckusick { 16411288Smckusick 16511288Smckusick fi = open(file, 2); 16611288Smckusick if (fi < 0) { 16711288Smckusick fprintf(stderr, "cannot open"); 16811288Smckusick perror(file); 16911288Smckusick exit(3); 17011288Smckusick } 17111288Smckusick if (bread(SBLOCK, (char *)fs, SBSIZE)) { 17211288Smckusick fprintf(stderr, "bad super block"); 17311288Smckusick perror(file); 17411288Smckusick exit(4); 17511288Smckusick } 17611288Smckusick if (fs->fs_magic != FS_MAGIC) { 17711288Smckusick fprintf(stderr, "%s: bad magic number\n", file); 17811288Smckusick exit(5); 17911288Smckusick } 18011288Smckusick } 18111288Smckusick 18211288Smckusick bwrite(blk, buf, size) 18311288Smckusick char *buf; 18411288Smckusick daddr_t blk; 18511288Smckusick register size; 18611288Smckusick { 18711288Smckusick if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 18811288Smckusick perror("FS SEEK"); 18911288Smckusick exit(6); 19011288Smckusick } 19111288Smckusick if (write(fi, buf, size) != size) { 19211288Smckusick perror("FS WRITE"); 19311288Smckusick exit(7); 19411288Smckusick } 19511288Smckusick } 19611288Smckusick 19711288Smckusick bread(bno, buf, cnt) 19811288Smckusick daddr_t bno; 19911288Smckusick char *buf; 20011288Smckusick { 20111288Smckusick register i; 20211288Smckusick 20311288Smckusick if (lseek(fi, bno * DEV_BSIZE, 0) < 0) 20411288Smckusick return(1); 20511288Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 20611288Smckusick for(i=0; i<sblock.fs_bsize; i++) 20711288Smckusick buf[i] = 0; 20811288Smckusick return (1); 20911288Smckusick } 21011288Smckusick return (0); 21111288Smckusick } 21211288Smckusick 21311288Smckusick /* VARARGS1 */ 21411288Smckusick fatal(fmt, arg1, arg2) 21511288Smckusick char *fmt, *arg1, *arg2; 21611288Smckusick { 21711288Smckusick 21811295Ssam fprintf(stderr, "tunefs: "); 21911288Smckusick fprintf(stderr, fmt, arg1, arg2); 22011288Smckusick putc('\n', stderr); 22111288Smckusick exit(10); 22211288Smckusick } 223