1*11288Smckusick #ifndef lint 2*11288Smckusick static char *sccsid = "@(#)tunefs.c 4.1 (Berkeley) 02/26/83"; 3*11288Smckusick #endif lint 4*11288Smckusick 5*11288Smckusick /* 6*11288Smckusick * tunefs: change layout parameters to an existing file system. 7*11288Smckusick */ 8*11288Smckusick 9*11288Smckusick #include <stdio.h> 10*11288Smckusick #include <sys/param.h> 11*11288Smckusick #include <sys/stat.h> 12*11288Smckusick #include <sys/fs.h> 13*11288Smckusick #include <sys/inode.h> 14*11288Smckusick 15*11288Smckusick union { 16*11288Smckusick struct fs sb; 17*11288Smckusick char pad[MAXBSIZE]; 18*11288Smckusick } sbun; 19*11288Smckusick #define sblock sbun.sb 20*11288Smckusick 21*11288Smckusick int fi; 22*11288Smckusick 23*11288Smckusick main(argc, argv) 24*11288Smckusick int argc; 25*11288Smckusick char *argv[]; 26*11288Smckusick { 27*11288Smckusick char *cp, *special, *name; 28*11288Smckusick struct stat st; 29*11288Smckusick int i; 30*11288Smckusick int Aflag = 0; 31*11288Smckusick char device[MAXPATHLEN]; 32*11288Smckusick extern char *sprintf(); 33*11288Smckusick 34*11288Smckusick argc--, argv++; 35*11288Smckusick if (argc < 2) 36*11288Smckusick goto usage; 37*11288Smckusick special = argv[argc - 1]; 38*11288Smckusick again: 39*11288Smckusick if (stat(special, &st) < 0) { 40*11288Smckusick if (*special != '/') { 41*11288Smckusick if (*special == 'r') 42*11288Smckusick special++; 43*11288Smckusick special = sprintf(device, "/dev/%s", special); 44*11288Smckusick goto again; 45*11288Smckusick } 46*11288Smckusick fprintf(stderr, "tunefs: "); perror(special); 47*11288Smckusick exit(1); 48*11288Smckusick } 49*11288Smckusick if ((st.st_mode & S_IFMT) != S_IFBLK && 50*11288Smckusick (st.st_mode & S_IFMT) != S_IFCHR) 51*11288Smckusick fatal("%s: not a block or character device", special); 52*11288Smckusick getsb(&sblock, special); 53*11288Smckusick for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) { 54*11288Smckusick for (cp = &argv[0][1]; *cp; cp++) 55*11288Smckusick switch (*cp) { 56*11288Smckusick 57*11288Smckusick case 'A': 58*11288Smckusick Aflag++; 59*11288Smckusick continue; 60*11288Smckusick 61*11288Smckusick case 'a': 62*11288Smckusick name = "maximum contiguous block count"; 63*11288Smckusick if (argc < 1) 64*11288Smckusick fatal("-a: missing %s", name); 65*11288Smckusick argc--, argv++; 66*11288Smckusick i = atoi(*argv); 67*11288Smckusick if (i < 1) 68*11288Smckusick fatal("%s: %s must be >= 1", 69*11288Smckusick *argv, name); 70*11288Smckusick fprintf(stdout, "%s changes from %d to %d\n", 71*11288Smckusick name, sblock.fs_maxcontig, i); 72*11288Smckusick sblock.fs_maxcontig = i; 73*11288Smckusick continue; 74*11288Smckusick 75*11288Smckusick case 'd': 76*11288Smckusick name = 77*11288Smckusick "rotational delay between contiguous blocks"; 78*11288Smckusick if (argc < 1) 79*11288Smckusick fatal("-d: missing %s", name); 80*11288Smckusick argc--, argv++; 81*11288Smckusick i = atoi(*argv); 82*11288Smckusick if (i < 0) 83*11288Smckusick fatal("%s: bad %s", *argv, name); 84*11288Smckusick fprintf(stdout, 85*11288Smckusick "%s changes from %dms to %dms\n", 86*11288Smckusick name, sblock.fs_rotdelay, i); 87*11288Smckusick sblock.fs_rotdelay = i; 88*11288Smckusick continue; 89*11288Smckusick 90*11288Smckusick case 'e': 91*11288Smckusick name = 92*11288Smckusick "maximum blocks per file in a cylinder group"; 93*11288Smckusick if (argc < 1) 94*11288Smckusick fatal("-e: missing %s", name); 95*11288Smckusick argc--, argv++; 96*11288Smckusick i = atoi(*argv); 97*11288Smckusick if (i < 1) 98*11288Smckusick fatal("%s: %s must be >= 1", 99*11288Smckusick *argv, name); 100*11288Smckusick fprintf(stdout, "%s changes from %d to %d\n", 101*11288Smckusick name, sblock.fs_maxbpg, i); 102*11288Smckusick sblock.fs_maxbpg = i; 103*11288Smckusick continue; 104*11288Smckusick 105*11288Smckusick case 'm': 106*11288Smckusick name = "minimum percentage of free space"; 107*11288Smckusick if (argc < 1) 108*11288Smckusick fatal("-m: missing %s", name); 109*11288Smckusick argc--, argv++; 110*11288Smckusick i = atoi(*argv); 111*11288Smckusick if (i < 0 || i > 99) 112*11288Smckusick fatal("%s: bad %s", *argv, name); 113*11288Smckusick fprintf(stdout, 114*11288Smckusick "%s changes from %d%% to %d%%\n", 115*11288Smckusick name, sblock.fs_minfree, i); 116*11288Smckusick sblock.fs_minfree = i; 117*11288Smckusick continue; 118*11288Smckusick 119*11288Smckusick default: 120*11288Smckusick fatal("-%c: unknown flag", *cp); 121*11288Smckusick } 122*11288Smckusick } 123*11288Smckusick if (argc != 1) 124*11288Smckusick goto usage; 125*11288Smckusick bwrite(SBLOCK, (char *)&sblock, SBSIZE); 126*11288Smckusick if (Aflag) 127*11288Smckusick for (i = 0; i < sblock.fs_ncg; i++) 128*11288Smckusick bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)), 129*11288Smckusick (char *)&sblock, SBSIZE); 130*11288Smckusick close(fi); 131*11288Smckusick exit(0); 132*11288Smckusick usage: 133*11288Smckusick fprintf(stderr, "Usage: tunefs tuneup-options special-device\n"); 134*11288Smckusick fprintf(stderr, "where tuneup-options are:\n"); 135*11288Smckusick fprintf(stderr, "\t-a maximum contigouous blocks\n"); 136*11288Smckusick fprintf(stderr, "\t-d rotational delay between contiguous blocks\n"); 137*11288Smckusick fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 138*11288Smckusick fprintf(stderr, "\t-m minimum percentage of free space\n"); 139*11288Smckusick exit(2); 140*11288Smckusick } 141*11288Smckusick 142*11288Smckusick getsb(fs, file) 143*11288Smckusick register struct fs *fs; 144*11288Smckusick char *file; 145*11288Smckusick { 146*11288Smckusick 147*11288Smckusick fi = open(file, 2); 148*11288Smckusick if (fi < 0) { 149*11288Smckusick fprintf(stderr, "cannot open"); 150*11288Smckusick perror(file); 151*11288Smckusick exit(3); 152*11288Smckusick } 153*11288Smckusick if (bread(SBLOCK, (char *)fs, SBSIZE)) { 154*11288Smckusick fprintf(stderr, "bad super block"); 155*11288Smckusick perror(file); 156*11288Smckusick exit(4); 157*11288Smckusick } 158*11288Smckusick if (fs->fs_magic != FS_MAGIC) { 159*11288Smckusick fprintf(stderr, "%s: bad magic number\n", file); 160*11288Smckusick exit(5); 161*11288Smckusick } 162*11288Smckusick } 163*11288Smckusick 164*11288Smckusick bwrite(blk, buf, size) 165*11288Smckusick char *buf; 166*11288Smckusick daddr_t blk; 167*11288Smckusick register size; 168*11288Smckusick { 169*11288Smckusick if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 170*11288Smckusick perror("FS SEEK"); 171*11288Smckusick exit(6); 172*11288Smckusick } 173*11288Smckusick if (write(fi, buf, size) != size) { 174*11288Smckusick perror("FS WRITE"); 175*11288Smckusick exit(7); 176*11288Smckusick } 177*11288Smckusick } 178*11288Smckusick 179*11288Smckusick bread(bno, buf, cnt) 180*11288Smckusick daddr_t bno; 181*11288Smckusick char *buf; 182*11288Smckusick { 183*11288Smckusick register i; 184*11288Smckusick 185*11288Smckusick if (lseek(fi, bno * DEV_BSIZE, 0) < 0) 186*11288Smckusick return(1); 187*11288Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 188*11288Smckusick for(i=0; i<sblock.fs_bsize; i++) 189*11288Smckusick buf[i] = 0; 190*11288Smckusick return (1); 191*11288Smckusick } 192*11288Smckusick return (0); 193*11288Smckusick } 194*11288Smckusick 195*11288Smckusick /* VARARGS1 */ 196*11288Smckusick fatal(fmt, arg1, arg2) 197*11288Smckusick char *fmt, *arg1, *arg2; 198*11288Smckusick { 199*11288Smckusick 200*11288Smckusick fprintf(stderr, "newfs: "); 201*11288Smckusick fprintf(stderr, fmt, arg1, arg2); 202*11288Smckusick putc('\n', stderr); 203*11288Smckusick exit(10); 204*11288Smckusick } 205