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