george@rebel.UUCP (George M. Sipe) (10/12/89)
I've just tested Andy Fyfe's "packdisk" posted to comp.sources.misc, volume 8, issue 93. It's great! Thanks Andy. My system is a UniPlus System V.0 and packdisk worked without fault. When done, fsck reported no problems. Even sparse files (history DBM stuff) were handle correctly (fsck bitches about that, always does). Using Michael Young's "fsanalyze" before and after the "packing" of a 20 MB partition produced the following output: before> File system name = "u", Volume name = "w00c" before> Logical block size = 1024 bytes before> Interleave = 1 sectors; 136 sectors/cyl before> Volume Size = 17272 blocks (17686528 bytes) before> 271 blocks reserved for super block and inodes (4304 inodes) before> 17001 blocks reserved for data before> 38.50% inodes used (1657 used, 2647 free) before> 78.08% data blocks used (13274 used, 3727 free) before> before> Fragmentation = 37.70% Special files = 0 (0.00%) before> Average Seek Distance = 57.31 cyls Indirect files = 154 (9.29%) before> Rotation delays = 4.22% Double indirects = 7 (0.42%) before> Multiply-linked files = 181 (10.92%) Triple indirects = 0 (0.00%) before> Directories = 85 (5.13%) Indirection blks = 172 (1.01%) before> Oversized directories = 0 (0.00%) Sparse files = 1 (0.06%) before> Unused bytes in last blocks = 961397 (5.44%) after> File system name = "u", Volume name = "w00c" after> Logical block size = 1024 bytes after> Interleave = 1 sectors; 136 sectors/cyl after> Volume Size = 17272 blocks (17686528 bytes) after> 271 blocks reserved for super block and inodes (4304 inodes) after> 17001 blocks reserved for data after> 38.50% inodes used (1657 used, 2647 free) after> 78.08% data blocks used (13274 used, 3727 free) after> after> Fragmentation = 0.96% Special files = 0 (0.00%) after> Average Seek Distance = 1.60 cyls Indirect files = 154 (9.29%) after> Rotation delays = 0.08% Double indirects = 7 (0.42%) after> Multiply-linked files = 181 (10.92%) Triple indirects = 0 (0.00%) after> Directories = 85 (5.13%) Indirection blks = 172 (1.01%) after> Oversized directories = 0 (0.00%) Sparse files = 1 (0.06%) after> Unused bytes in last blocks = 961397 (5.44%) Quite an improvement. "Feels" faster too. On my aging 68K system, this took about 3 hours to complete. Packdisk showed it's progess (inode #) as it went. Your mileage may vary... be sure to backup everything before starting. In his posting, Andy noted: > Though this program was developed on a 3b1, it was written with > portability in mind (yes, I know -- you can stop laughing now!). > Perhaps other systems with the System V file system (inherited from > V7?) can also use the program, or adapt it to their needs. Well, it is very portable, except for using gcc as the implementation base. Not to take away from gcc, it's just that some of us (me for instance) don't have it up and are stuck with pcc for now. That mean's, among other things no function prototypes. Slight hacking on the source to allow "OLDC" (#ifdef'ed) produced the following patch file. While I was at it, I also put a few casts in place to humor lint. Again, works well for me... your mileage may vary. Regards, George M. Sipe, Phone: (404) 447-4731 537 Lakeshore Drive, Berkeley Lake, GA 30136-3035 UUCP: ...!{decvax,linus,rutgers}!gatech!rebel!george *** opackdisk.c Wed Oct 11 21:41:07 1989 --- packdisk.c Wed Oct 11 21:42:50 1989 *************** *** 9,14 * andy@csvax.caltech.edu */ #include <sys/filsys.h> #include <sys/ino.h> #include <sys/stat.h> --- 9,19 ----- * andy@csvax.caltech.edu */ + #ifndef OLDC + #include <stdlib.h> + #endif + #include <sys/types.h> + #include <sys/param.h> #include <sys/filsys.h> #include <sys/ino.h> #include <sys/stat.h> *************** *** 13,19 #include <sys/ino.h> #include <sys/stat.h> #include <stdio.h> - #include <stdlib.h> #define NUM_ADDR 13 #define FIRST_INDIR 10 /* 0-9 direct, 10 single, 11 double, 12 triple */ --- 18,23 ----- #include <sys/ino.h> #include <sys/stat.h> #include <stdio.h> #ifndef OLDC #define FsBSIZEdev FsBSIZE(dev) *************** *** 15,20 #include <stdio.h> #include <stdlib.h> #define NUM_ADDR 13 #define FIRST_INDIR 10 /* 0-9 direct, 10 single, 11 double, 12 triple */ #define NUM_INDIR (NUM_ADDR - FIRST_INDIR) --- 19,30 ----- #include <sys/stat.h> #include <stdio.h> + #ifndef OLDC + #define FsBSIZEdev FsBSIZE(dev) + #else + #define FsBSIZEdev 1024 /* BE SURE THIS IS OK FOR YOU */ + #endif + #define NUM_ADDR 13 #define FIRST_INDIR 10 /* 0-9 direct, 10 single, 11 double, 12 triple */ #define NUM_INDIR (NUM_ADDR - FIRST_INDIR) *************** *** 39,44 long *map; /* a map from block numbers to referencing inode/indir block */ static void read_superblk(void); static void write_superblk(void); static void map_inode(ino_t inode); --- 49,55 ----- long *map; /* a map from block numbers to referencing inode/indir block */ + #ifndef OLDC static void read_superblk(void); static void write_superblk(void); static void map_inode(ino_t inode); *************** *** 55,60 extern void l3tol(long *, char *, int length); extern void ltol3(char *, long *, int length); void main(int argc, char *argv[]) --- 66,80 ----- extern void l3tol(long *, char *, int length); extern void ltol3(char *, long *, int length); + #else + #define move_indirect Move_Indirect /* make uniq */ + extern char *calloc(); + extern char *malloc(); + extern char *memcpy(); + extern char *memset(); + extern long lseek(); + extern void exit(); + extern void perror(); static void read_superblk(); static void write_superblk(); *************** *** 56,63 extern void l3tol(long *, char *, int length); extern void ltol3(char *, long *, int length); ! void ! main(int argc, char *argv[]) { ino_t inode, total_inodes; daddr_t block; --- 76,102 ----- extern void exit(); extern void perror(); ! static void read_superblk(); ! static void write_superblk(); ! static void map_inode(); ! static void update_map(); ! static void read_block(); ! static void write_block(); ! static void read_inode(); ! static void write_inode(); ! static void move_block(); ! static void move_inode(); ! static void move_indirect(); ! static void make_hole(); ! static void rebuild_free_list(); ! ! extern void l3tol(); ! extern void ltol3(); ! #endif ! ! int main(argc, argv) ! int argc; ! char *argv[]; { ino_t inode, total_inodes; daddr_t block; *************** *** 62,67 ino_t inode, total_inodes; daddr_t block; int i; char *ctime(long *); #ifndef DEBUG struct stat statb; --- 101,107 ----- ino_t inode, total_inodes; daddr_t block; int i; + #ifndef OLDC char *ctime(long *); #ifndef DEBUG struct stat statb; *************** *** 67,72 struct stat statb; extern int stat(const char *, struct stat *); #endif cmd_name = argv[0]; --- 107,119 ----- struct stat statb; extern int stat(const char *, struct stat *); #endif + #else + char *ctime(); + #ifndef DEBUG + struct stat statb; + extern int stat(); + #endif + #endif cmd_name = argv[0]; *************** *** 71,77 cmd_name = argv[0]; if (argc != 2) { ! fprintf(stderr, "%s: Usage: %s <file system>\n", cmd_name, cmd_name); exit(1); } --- 118,124 ----- cmd_name = argv[0]; if (argc != 2) { ! (void) fprintf(stderr, "%s: Usage: %s <file system>\n", cmd_name, cmd_name); exit(1); } *************** *** 78,84 #ifndef DEBUG if (stat(argv[1], &statb) < 0) { ! fprintf(stderr, "%s: can't stat %s: ", cmd_name, argv[1]); perror(""); exit(1); } --- 125,131 ----- #ifndef DEBUG if (stat(argv[1], &statb) < 0) { ! (void) fprintf(stderr, "%s: can't stat %s: ", cmd_name, argv[1]); perror(""); exit(1); } *************** *** 83,89 exit(1); } if ((statb.st_mode & S_IFMT) != S_IFCHR) { ! fprintf(stderr, "%s: %s is not a character device\n", cmd_name, argv[1]); exit(1); } --- 130,136 ----- exit(1); } if ((statb.st_mode & S_IFMT) != S_IFCHR) { ! (void) fprintf(stderr, "%s: %s is not a character device\n", cmd_name, argv[1]); exit(1); } *************** *** 91,97 disk = open(argv[1], 2, 0); if (disk < 0) { ! fprintf(stderr, "%s: can't open %s: ", cmd_name, argv[1]); perror(""); exit(1); } --- 138,144 ----- disk = open(argv[1], 2, 0); if (disk < 0) { ! (void) fprintf(stderr, "%s: can't open %s: ", cmd_name, argv[1]); perror(""); exit(1); } *************** *** 99,105 read_superblk(); total_inodes = (filsys.s_isize - FsITOD(dev, ROOTINO)) * FsINOPB(dev); ! fprintf(stderr, "File system: name: \"%.6s\", pack: \"%.6s\"\n", filsys.s_fname, filsys.s_fpack); fprintf(stderr, "\tlast modified on %s", ctime(&filsys.s_time)); fprintf(stderr, --- 146,152 ----- read_superblk(); total_inodes = (filsys.s_isize - FsITOD(dev, ROOTINO)) * FsINOPB(dev); ! (void) fprintf(stderr, "File system: name: \"%.6s\", pack: \"%.6s\"\n", filsys.s_fname, filsys.s_fpack); (void) fprintf(stderr, "\tlast modified on %s", ctime(&filsys.s_time)); (void) fprintf(stderr, *************** *** 101,108 total_inodes = (filsys.s_isize - FsITOD(dev, ROOTINO)) * FsINOPB(dev); fprintf(stderr, "File system: name: \"%.6s\", pack: \"%.6s\"\n", filsys.s_fname, filsys.s_fpack); ! fprintf(stderr, "\tlast modified on %s", ctime(&filsys.s_time)); ! fprintf(stderr, "\ttotal inodes = %d, data blocks = %d, total = %d blocks\n", total_inodes, filsys.s_fsize - filsys.s_isize, filsys.s_fsize); fprintf(stderr, "\tfree blocks = %d, free inodes = %d\n", --- 148,155 ----- total_inodes = (filsys.s_isize - FsITOD(dev, ROOTINO)) * FsINOPB(dev); (void) fprintf(stderr, "File system: name: \"%.6s\", pack: \"%.6s\"\n", filsys.s_fname, filsys.s_fpack); ! (void) fprintf(stderr, "\tlast modified on %s", ctime(&filsys.s_time)); ! (void) fprintf(stderr, "\ttotal inodes = %d, data blocks = %d, total = %d blocks\n", total_inodes, filsys.s_fsize - filsys.s_isize, filsys.s_fsize); (void) fprintf(stderr, "\tfree blocks = %d, free inodes = %d\n", *************** *** 105,111 fprintf(stderr, "\ttotal inodes = %d, data blocks = %d, total = %d blocks\n", total_inodes, filsys.s_fsize - filsys.s_isize, filsys.s_fsize); ! fprintf(stderr, "\tfree blocks = %d, free inodes = %d\n", filsys.s_tfree, filsys.s_tinode); for (i = 0; i < NUM_INDIR; ++i) { --- 152,158 ----- (void) fprintf(stderr, "\ttotal inodes = %d, data blocks = %d, total = %d blocks\n", total_inodes, filsys.s_fsize - filsys.s_isize, filsys.s_fsize); ! (void) fprintf(stderr, "\tfree blocks = %d, free inodes = %d\n", filsys.s_tfree, filsys.s_tinode); for (i = 0; i < NUM_INDIR; ++i) { *************** *** 110,116 for (i = 0; i < NUM_INDIR; ++i) { w_indir[i] = 0; ! indir[i] = malloc(FsBSIZE(dev)); if (indir[i] == 0) { fprintf(stderr, "%s: can't malloc indir buffer space: ", cmd_name); perror(""); --- 157,163 ----- for (i = 0; i < NUM_INDIR; ++i) { w_indir[i] = 0; ! indir[i] = (char *) malloc((unsigned) FsBSIZE(dev)); if (indir[i] == 0) { (void) fprintf(stderr, "%s: can't malloc indir buffer space: ", cmd_name); *************** *** 112,118 w_indir[i] = 0; indir[i] = malloc(FsBSIZE(dev)); if (indir[i] == 0) { ! fprintf(stderr, "%s: can't malloc indir buffer space: ", cmd_name); perror(""); exit(1); } --- 159,166 ----- w_indir[i] = 0; indir[i] = (char *) malloc((unsigned) FsBSIZE(dev)); if (indir[i] == 0) { ! (void) fprintf(stderr, "%s: can't malloc indir buffer space: ", ! cmd_name); perror(""); exit(1); } *************** *** 119,125 } w_ino = 0; ! map = calloc(filsys.s_fsize, sizeof(*map)); if (map == 0) { fprintf(stderr, "%s: can't calloc map: ", cmd_name); perror(""); --- 167,173 ----- } w_ino = 0; ! map = (long *) calloc((unsigned) filsys.s_fsize, sizeof(*map)); if (map == 0) { (void) fprintf(stderr, "%s: can't calloc map: ", cmd_name); perror(""); *************** *** 121,127 map = calloc(filsys.s_fsize, sizeof(*map)); if (map == 0) { ! fprintf(stderr, "%s: can't calloc map: ", cmd_name); perror(""); exit(1); } --- 169,175 ----- map = (long *) calloc((unsigned) filsys.s_fsize, sizeof(*map)); if (map == 0) { ! (void) fprintf(stderr, "%s: can't calloc map: ", cmd_name); perror(""); exit(1); } *************** *** 126,132 exit(1); } ! inode_table = malloc(filsys.s_isize * FsBSIZE(dev)); if (inode_table == 0) { fprintf(stderr, "%s: can't malloc space for inode table\n", cmd_name); w_ino_blk = 0; --- 174,180 ----- exit(1); } ! inode_table = (char *) malloc(filsys.s_isize * FsBSIZE(dev)); if (inode_table == 0) { (void) fprintf(stderr, "%s: can't malloc space for inode table\n", cmd_name); *************** *** 128,134 inode_table = malloc(filsys.s_isize * FsBSIZE(dev)); if (inode_table == 0) { ! fprintf(stderr, "%s: can't malloc space for inode table\n", cmd_name); w_ino_blk = 0; inode_block = malloc(FsBSIZE(dev)); if (inode_block == 0) { --- 176,183 ----- inode_table = (char *) malloc(filsys.s_isize * FsBSIZE(dev)); if (inode_table == 0) { ! (void) fprintf(stderr, "%s: can't malloc space for inode table\n", ! cmd_name); w_ino_blk = 0; inode_block = (char *) malloc((unsigned) FsBSIZE(dev)); if (inode_block == 0) { *************** *** 130,136 if (inode_table == 0) { fprintf(stderr, "%s: can't malloc space for inode table\n", cmd_name); w_ino_blk = 0; ! inode_block = malloc(FsBSIZE(dev)); if (inode_block == 0) { fprintf(stderr, "%s: can't malloc inode buffer space: ", cmd_name); perror(""); --- 179,185 ----- (void) fprintf(stderr, "%s: can't malloc space for inode table\n", cmd_name); w_ino_blk = 0; ! inode_block = (char *) malloc((unsigned) FsBSIZE(dev)); if (inode_block == 0) { (void) fprintf(stderr, "%s: can't malloc inode buffer space: ", cmd_name); *************** *** 132,138 w_ino_blk = 0; inode_block = malloc(FsBSIZE(dev)); if (inode_block == 0) { ! fprintf(stderr, "%s: can't malloc inode buffer space: ", cmd_name); perror(""); exit(1); } --- 181,188 ----- w_ino_blk = 0; inode_block = (char *) malloc((unsigned) FsBSIZE(dev)); if (inode_block == 0) { ! (void) fprintf(stderr, "%s: can't malloc inode buffer space: ", ! cmd_name); perror(""); exit(1); } *************** *** 141,147 for (block = FsITOD(dev, ROOTINO); block < filsys.s_isize; ++block) read_block(block, &inode_table[block * FsBSIZE(dev)]); ! fprintf(stderr, "mapping..."); for (inode = ROOTINO; inode <= total_inodes; ++inode) map_inode(inode); fprintf(stderr, "done\n"); --- 191,197 ----- for (block = FsITOD(dev, ROOTINO); block < filsys.s_isize; ++block) read_block(block, &inode_table[block * FsBSIZE(dev)]); ! (void) fprintf(stderr, "mapping..."); for (inode = ROOTINO; inode <= total_inodes; ++inode) map_inode(inode); (void) fprintf(stderr, "done\n"); *************** *** 144,150 fprintf(stderr, "mapping..."); for (inode = ROOTINO; inode <= total_inodes; ++inode) map_inode(inode); ! fprintf(stderr, "done\n"); next_fill = filsys.s_isize; for (inode = ROOTINO; inode <= total_inodes; ++inode) --- 194,200 ----- (void) fprintf(stderr, "mapping..."); for (inode = ROOTINO; inode <= total_inodes; ++inode) map_inode(inode); ! (void) fprintf(stderr, "done\n"); next_fill = filsys.s_isize; for (inode = ROOTINO; inode <= total_inodes; ++inode) *************** *** 150,156 for (inode = ROOTINO; inode <= total_inodes; ++inode) move_inode(inode); ! fprintf(stderr, "\nrebuilding the free list\n"); rebuild_free_list(); fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); --- 200,206 ----- for (inode = ROOTINO; inode <= total_inodes; ++inode) move_inode(inode); ! (void) fprintf(stderr, "\nrebuilding the free list\n"); rebuild_free_list(); (void) fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); *************** *** 153,159 fprintf(stderr, "\nrebuilding the free list\n"); rebuild_free_list(); ! fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); close(disk); exit(0); --- 203,209 ----- (void) fprintf(stderr, "\nrebuilding the free list\n"); rebuild_free_list(); ! (void) fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); (void) close(disk); exit(0); *************** *** 155,161 fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); ! close(disk); exit(0); } --- 205,211 ----- (void) fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); ! (void) close(disk); exit(0); } *************** *** 159,166 exit(0); } ! static void ! read_superblk(void) { if (lseek(disk, SUPERBOFF, 0) != SUPERBOFF) { fprintf(stderr, "%s: can't seek to superblock: ", cmd_name); --- 209,215 ----- exit(0); } ! static void read_superblk() { if (lseek(disk, SUPERBOFF, 0) != (long) SUPERBOFF) { (void) fprintf(stderr, "%s: can't seek to superblock: ", cmd_name); *************** *** 162,169 static void read_superblk(void) { ! if (lseek(disk, SUPERBOFF, 0) != SUPERBOFF) { ! fprintf(stderr, "%s: can't seek to superblock: ", cmd_name); perror(""); exit(1); } --- 211,218 ----- static void read_superblk() { ! if (lseek(disk, SUPERBOFF, 0) != (long) SUPERBOFF) { ! (void) fprintf(stderr, "%s: can't seek to superblock: ", cmd_name); perror(""); exit(1); } *************** *** 168,174 exit(1); } if (read(disk, &filsys, sizeof(filsys)) != sizeof(filsys)) { ! fprintf(stderr, "%s: can't read superblock: ", cmd_name); perror(""); exit(1); } --- 217,223 ----- exit(1); } if (read(disk, &filsys, sizeof(filsys)) != sizeof(filsys)) { ! (void) fprintf(stderr, "%s: can't read superblock: ", cmd_name); perror(""); exit(1); } *************** *** 173,179 exit(1); } if (filsys.s_magic != FsMAGIC) { ! fprintf(stderr, "%s: invalid superblock magic number\n", cmd_name); exit(1); } dev = (filsys.s_type == Fs2b) ? Fs2BLK : 0; --- 222,229 ----- exit(1); } if (filsys.s_magic != FsMAGIC) { ! (void) fprintf(stderr, "%s: invalid superblock magic number\n", ! cmd_name); exit(1); } dev = (filsys.s_type == Fs2b) ? Fs2BLK : 0; *************** *** 179,186 dev = (filsys.s_type == Fs2b) ? Fs2BLK : 0; } ! static void ! write_superblk(void) { lseek(disk, SUPERBOFF, 0); if (write(disk, &filsys, sizeof(filsys)) != sizeof(filsys)) { --- 229,235 ----- dev = (filsys.s_type == Fs2b) ? Fs2BLK : 0; } ! static void write_superblk() { if (lseek(disk, SUPERBOFF, 0) == -1L || write(disk, &filsys, sizeof(filsys)) != sizeof(filsys)) { *************** *** 182,190 static void write_superblk(void) { ! lseek(disk, SUPERBOFF, 0); ! if (write(disk, &filsys, sizeof(filsys)) != sizeof(filsys)) { ! fprintf(stderr, "%s: can't write superblock: ", cmd_name); perror(""); exit(1); } --- 231,239 ----- static void write_superblk() { ! if (lseek(disk, SUPERBOFF, 0) == -1L ! || write(disk, &filsys, sizeof(filsys)) != sizeof(filsys)) { ! (void) fprintf(stderr, "%s: can't write superblock: ", cmd_name); perror(""); exit(1); } *************** *** 190,197 } } ! static void ! map_inode(ino_t inode) { int type, i; long block[NUM_ADDR]; --- 239,246 ----- } } ! static void map_inode(inode) ! ino_t inode; { int type, i; long block[NUM_ADDR]; *************** *** 206,212 l3tol(block, ino.di_addr, NUM_ADDR); for (i = 0; i < NUM_ADDR; ++i) if (block[i] != 0) ! update_map(inode, block[i], (i < FIRST_INDIR) ? 0 : (i - FIRST_INDIR + 1)); } --- 255,261 ----- l3tol(block, ino.di_addr, NUM_ADDR); for (i = 0; i < NUM_ADDR; ++i) if (block[i] != 0) ! update_map((long) inode, block[i], (i < FIRST_INDIR) ? 0 : (i - FIRST_INDIR + 1)); } *************** *** 210,217 (i < FIRST_INDIR) ? 0 : (i - FIRST_INDIR + 1)); } ! static void ! update_map(long map_entry, daddr_t block, int level) { int i; --- 259,268 ----- (i < FIRST_INDIR) ? 0 : (i - FIRST_INDIR + 1)); } ! static void update_map(map_entry, block, level) ! long map_entry; ! daddr_t block; ! int level; { int i; *************** *** 216,222 int i; if (map[block] != 0) { ! fprintf(stderr, "%s: duplicate block %d in %d and %d\n", cmd_name, block, map[block], map_entry); exit(1); } --- 267,273 ----- int i; if (map[block] != 0) { ! (void) fprintf(stderr, "%s: duplicate block %d in %d and %d\n", cmd_name, block, map[block], map_entry); exit(1); } *************** *** 232,239 update_map(-block, ((daddr_t *)indir[level])[i], level); } ! static void ! read_block(daddr_t block, void *buf) { lseek(disk, block * FsBSIZE(dev), 0); if (read(disk, buf, FsBSIZE(dev)) != FsBSIZE(dev)) { --- 283,291 ----- update_map(-block, ((daddr_t *)indir[level])[i], level); } ! static void read_block(block, buf) ! daddr_t block; ! char *buf; { if (lseek(disk, block * FsBSIZE(dev), 0) == -1L || read(disk, buf, (unsigned) FsBSIZE(dev)) != FsBSIZE(dev)) { *************** *** 235,243 static void read_block(daddr_t block, void *buf) { ! lseek(disk, block * FsBSIZE(dev), 0); ! if (read(disk, buf, FsBSIZE(dev)) != FsBSIZE(dev)) { ! fprintf(stderr, "%s: can't read block %d: ", cmd_name, block); perror(""); exit(1); } --- 287,295 ----- daddr_t block; char *buf; { ! if (lseek(disk, block * FsBSIZE(dev), 0) == -1L ! || read(disk, buf, (unsigned) FsBSIZE(dev)) != FsBSIZE(dev)) { ! (void) fprintf(stderr, "%s: can't read block %d: ", cmd_name, block); perror(""); exit(1); } *************** *** 243,250 } } ! static void ! write_block(daddr_t block, void *buf) { lseek(disk, block * FsBSIZE(dev), 0); if (write(disk, buf, FsBSIZE(dev)) != FsBSIZE(dev)) { --- 295,303 ----- } } ! static void write_block(block, buf) ! daddr_t block; ! char *buf; { if (lseek(disk, block * FsBSIZE(dev), 0) == -1L || write(disk, buf, (unsigned) FsBSIZE(dev)) != FsBSIZE(dev)) { *************** *** 246,254 static void write_block(daddr_t block, void *buf) { ! lseek(disk, block * FsBSIZE(dev), 0); ! if (write(disk, buf, FsBSIZE(dev)) != FsBSIZE(dev)) { ! fprintf(stderr, "%s: can't write block %d: ", cmd_name, block); perror(""); exit(1); } --- 299,307 ----- daddr_t block; char *buf; { ! if (lseek(disk, block * FsBSIZE(dev), 0) == -1L ! || write(disk, buf, (unsigned) FsBSIZE(dev)) != FsBSIZE(dev)) { ! (void) fprintf(stderr, "%s: can't write block %d: ", cmd_name, block); perror(""); exit(1); } *************** *** 254,261 } } ! static void ! read_inode(ino_t inode, struct dinode *ino) { daddr_t block; --- 307,315 ----- } } ! static void read_inode(inode, the_ino) ! ino_t inode; ! struct dinode *the_ino; { daddr_t block; *************** *** 265,271 w_ino_blk = block; read_block(block, inode_block); } ! *ino = ((struct dinode *)inode_block)[FsITOO(dev, inode)]; } else { *ino = ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) --- 319,325 ----- w_ino_blk = block; read_block(block, inode_block); } ! *the_ino = ((struct dinode *)inode_block)[FsITOO(dev, inode)]; } else { *the_ino = ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) *************** *** 268,274 *ino = ((struct dinode *)inode_block)[FsITOO(dev, inode)]; } else { ! *ino = ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) [FsITOO(dev, inode)]; } } --- 322,328 ----- *the_ino = ((struct dinode *)inode_block)[FsITOO(dev, inode)]; } else { ! *the_ino = ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) [FsITOO(dev, inode)]; } } *************** *** 273,280 } } ! static void ! write_inode(ino_t inode, struct dinode *ino) { daddr_t block; --- 327,335 ----- } } ! static void write_inode(inode, the_ino) ! ino_t inode; ! struct dinode *the_ino; { daddr_t block; *************** *** 284,290 w_ino_blk = block; read_block(block, inode_block); } ! ((struct dinode *)inode_block)[FsITOO(dev, inode)] = *ino; write_block(block, inode_block); } else { --- 339,345 ----- w_ino_blk = block; read_block(block, inode_block); } ! ((struct dinode *)inode_block)[FsITOO(dev, inode)] = *the_ino; write_block(block, inode_block); } else { *************** *** 289,295 } else { ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) ! [FsITOO(dev, inode)] = *ino; write_block(block, &inode_table[block * FsBSIZE(dev)]); } } --- 344,350 ----- } else { ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) ! [FsITOO(dev, inode)] = *the_ino; write_block(block, &inode_table[block * FsBSIZE(dev)]); } } *************** *** 294,301 } } ! static void ! move_block(daddr_t from, daddr_t to) { char buffer[FsBSIZE(dev)]; daddr_t block; --- 349,357 ----- } } ! static void move_block(from, to) ! daddr_t from; ! daddr_t to; { char buffer[FsBSIZEdev]; daddr_t block; *************** *** 297,303 static void move_block(daddr_t from, daddr_t to) { ! char buffer[FsBSIZE(dev)]; daddr_t block; if (map[to] != 0) --- 353,359 ----- daddr_t from; daddr_t to; { ! char buffer[FsBSIZEdev]; daddr_t block; if (map[to] != 0) *************** *** 314,321 map[block] = -to; } ! static void ! move_inode(ino_t inode) { int type, i; long block[NUM_ADDR]; --- 370,377 ----- map[block] = -to; } ! static void move_inode(inode) ! ino_t inode; { int type, i; long block[NUM_ADDR]; *************** *** 328,334 if (type == S_IFCHR || type == S_IFBLK) return; ! fprintf(stderr, "moving inode %d (size %d) \r", inode, ino.di_size); l3tol(block, ino.di_addr, NUM_ADDR); --- 384,391 ----- if (type == S_IFCHR || type == S_IFBLK) return; ! (void) fprintf(stderr, ! "moving inode %d (size %d) \r", inode, ino.di_size); l3tol(block, ino.di_addr, NUM_ADDR); *************** *** 349,356 move_indirect(block[i], i-FIRST_INDIR); } ! static void ! move_indirect(daddr_t block, int level) { int i; --- 406,414 ----- move_indirect(block[i], i-FIRST_INDIR); } ! static void move_indirect(block, level) ! daddr_t block; ! int level; { int i; *************** *** 378,385 move_indirect(((daddr_t *)indir[level])[i], level-1); } ! static void ! make_hole(void) { char t_indir[FsBSIZE(dev)]; daddr_t *p_indir; --- 436,442 ----- move_indirect(((daddr_t *)indir[level])[i], level-1); } ! static void make_hole() { char t_indir[FsBSIZEdev]; daddr_t *p_indir; *************** *** 381,387 static void make_hole(void) { ! char t_indir[FsBSIZE(dev)]; daddr_t *p_indir; struct dinode t_ino, *p_ino; long block[NUM_ADDR]; --- 438,444 ----- static void make_hole() { ! char t_indir[FsBSIZEdev]; daddr_t *p_indir; struct dinode t_ino, *p_ino; long block[NUM_ADDR]; *************** *** 393,399 --back; if (next_fill >= back) { ! fprintf(stderr, "%s: can't find a free block for %d\n", cmd_name, next_fill); exit(1); } --- 450,456 ----- --back; if (next_fill >= back) { ! (void) fprintf(stderr, "%s: can't find a free block for %d\n", cmd_name, next_fill); exit(1); } *************** *** 419,425 } } if (i == FsNINDIR(dev)) { ! fprintf(stderr, "%s: panic: can't find %d in indirect block %d\n", cmd_name, next_fill, -map[back]); exit(1); --- 476,482 ----- } } if (i == FsNINDIR(dev)) { ! (void) fprintf(stderr, "%s: panic: can't find %d in indirect block %d\n", cmd_name, next_fill, -map[back]); exit(1); *************** *** 424,430 cmd_name, next_fill, -map[back]); exit(1); } ! write_block(block[0], p_indir); } else { if (map[back] == w_ino) { --- 481,487 ----- cmd_name, next_fill, -map[back]); exit(1); } ! write_block(block[0], (char *) p_indir); } else { if (map[back] == w_ino) { *************** *** 432,438 } else { p_ino = &t_ino; ! read_inode(map[back], &t_ino); } l3tol(block, p_ino->di_addr, NUM_ADDR); for (i = 0; i < NUM_ADDR; ++i) { --- 489,495 ----- } else { p_ino = &t_ino; ! read_inode((ino_t) map[back], &t_ino); } l3tol(block, p_ino->di_addr, NUM_ADDR); for (i = 0; i < NUM_ADDR; ++i) { *************** *** 443,449 } } if (i == NUM_ADDR) { ! fprintf(stderr, "%s: panic: can't find %d in inode %d\n", cmd_name, next_fill, map[back]); exit(1); } --- 500,506 ----- } } if (i == NUM_ADDR) { ! (void) fprintf(stderr, "%s: panic: can't find %d in inode %d\n", cmd_name, next_fill, map[back]); exit(1); } *************** *** 447,453 cmd_name, next_fill, map[back]); exit(1); } ! write_inode(map[back], p_ino); } } --- 504,510 ----- cmd_name, next_fill, map[back]); exit(1); } ! write_inode((ino_t) map[back], p_ino); } } *************** *** 451,458 } } ! static void ! rebuild_free_list(void) { int free_size, nfree; daddr_t free[NICFREE], block; --- 508,514 ----- } } ! static void rebuild_free_list() { int free_size, nfree; daddr_t free[NICFREE], block; *************** *** 456,462 { int free_size, nfree; daddr_t free[NICFREE], block; ! char buf[FsBSIZE(dev)]; free_size = filsys.s_fsize - next_fill; if (free_size != filsys.s_tfree) { --- 512,518 ----- { int free_size, nfree; daddr_t free[NICFREE], block; ! char buf[FsBSIZEdev]; free_size = filsys.s_fsize - next_fill; if (free_size != filsys.s_tfree) { *************** *** 460,466 free_size = filsys.s_fsize - next_fill; if (free_size != filsys.s_tfree) { ! fprintf(stderr, "%s: free list changed size from %d to %d\n", cmd_name, filsys.s_tfree, free_size); exit(1); } --- 516,522 ----- free_size = filsys.s_fsize - next_fill; if (free_size != filsys.s_tfree) { ! (void) fprintf(stderr, "%s: free list changed size from %d to %d\n", cmd_name, filsys.s_tfree, free_size); exit(1); } *************** *** 466,473 } nfree = 1; ! memset(free, 0, sizeof(free)); ! memset(buf, 0, sizeof(buf)); for (block = filsys.s_fsize - 1; block >= next_fill; --block) { if (nfree == NICFREE) { --- 522,529 ----- } nfree = 1; ! (void) memset((char *) free, 0, sizeof(free)); ! (void) memset(buf, 0, sizeof(buf)); for (block = filsys.s_fsize - 1; block >= next_fill; --block) { if (nfree == NICFREE) { *************** *** 472,478 for (block = filsys.s_fsize - 1; block >= next_fill; --block) { if (nfree == NICFREE) { ((daddr_t *)buf)[0] = nfree; ! memcpy(&((daddr_t *)buf)[1], free, sizeof(free)); write_block(block, buf); nfree = 0; memset(free, 0, sizeof(free)); --- 528,535 ----- for (block = filsys.s_fsize - 1; block >= next_fill; --block) { if (nfree == NICFREE) { ((daddr_t *)buf)[0] = nfree; ! (void) memcpy((char *) (&((daddr_t *)buf)[1]), (char *) free, ! sizeof(free)); write_block(block, buf); nfree = 0; (void) memset((char *) free, 0, sizeof(free)); *************** *** 475,481 memcpy(&((daddr_t *)buf)[1], free, sizeof(free)); write_block(block, buf); nfree = 0; ! memset(free, 0, sizeof(free)); } free[nfree++] = block; } --- 532,538 ----- sizeof(free)); write_block(block, buf); nfree = 0; ! (void) memset((char *) free, 0, sizeof(free)); } free[nfree++] = block; } *************** *** 481,486 } filsys.s_nfree = nfree; ! memcpy(&filsys.s_free, free, sizeof(free)); write_superblk(); } --- 538,543 ----- } filsys.s_nfree = nfree; ! (void) memcpy((char *) filsys.s_free, (char *) free, sizeof(free)); write_superblk(); } -- George M. Sipe, Phone: (404) 447-4731 537 Lakeshore Drive, Berkeley Lake, GA 30136-3035 UUCP: ...!{decvax,linus,rutgers}!gatech!rebel!george
karl@ddsw1.MCS.COM (Karl Denninger) (10/13/89)
Is anyone working on a port of this monster to SCO Xenix 2.3 286/386? If not, I'm going to dig in, but if someone else has started (or even better, done it already) perhaps we could save some work. The differences can't be THAT large.. -- Karl Denninger (karl@ddsw1.MCS.COM, <well-connected>!ddsw1!karl) Public Access Data Line: [+1 312 566-8911], Voice: [+1 312 566-8910] Macro Computer Solutions, Inc. "Quality Solutions at a Fair Price"
bownesrm@beowulf.UUCP (Mr Mojo Risen') (10/14/89)
From article <1989Oct12.214412.29101@ddsw1.MCS.COM>, by karl@ddsw1.MCS.COM (Karl Denninger): > Is anyone working on a port of this monster to SCO Xenix 2.3 286/386? > > If not, I'm going to dig in, but if someone else has started (or even > better, done it already) perhaps we could save some work. > Well I just finished portingit to Xenix System III and it ended up taking about 2 hours to track all the subtlties down. I want to beat on it a while longer before I give my version to the rest of the world though. Say another week or so. bob -- "Reading legal mush can turn your brain to guacamole." - Commodore/Amiga Manual Bob Bownes, aka iii, aka keptin comrade doktor bobwrench 874 Kari Dr, Eau Claire (Oh Claire!) Wisc, 54701 (715)-835-1934 voice bownesrm@beowulf.uucp {uunet!crdgw1,uunet!ssi}!beowulf!bownesrm
rick@pcrat.uucp (Rick Richardson) (10/14/89)
In article <1383@rebel.UUCP> george@rebel.UUCP (George M. Sipe) writes: >I've just tested Andy Fyfe's "packdisk" posted to comp.sources.misc, >volume 8, issue 93. It's great! Thanks Andy. > >My system is a UniPlus System V.0 and packdisk worked without fault. I would like to warn people that even after applying Georges patches, which are good, there are still some other problems with packdisk. I haven't been brave enough to test my changes on anything other than floppy filesystems. The program has a rather cavalier attitude towards mixing "int" and "long". These show up as calculations that will "lose precision" according to lint, lseek() calls that pass "int" seek offsets, and printf() calls that use "%d" instead of "%ld". The system here that most needs a "packdisk"ing is a 286, so that's why I noticed these problems. After fixing these sorts of things I had to compile it "large model" so that the needed storage could be malloc'ed, then tested it out on a floppy filesystem. It appeared to work, however, it did not construct a valid freelist (although fsck fixed this). This was under Venix System V/286. All of these things made me too nervous to trust it on a big filesystem without a backup. So testing it further will have to wait until I get around to shuffling a zillion floppies. Of course, the whole reason for using "packdisk" is to avoid having to do a backup/restore cycle. Despite the programs deficiencies in a 16 bit environment, I found the program well organized and conceived, and even easy to understand in the absence of comments. -Rick -- Rick Richardson | Looking for FAX software for UNIX/386 ?????? mention PC Research,Inc.| WE'RE SHIPPING your uunet!pcrat!rick| Ask about FaxiX - UNIX Facsimile System (tm) FAX # (201) 389-8963 | Or JetRoff - troff postprocessor for the HP {Laser,Desk}Jet
zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff) (10/15/89)
I use a similar program by Michael Young (sdti!mjy). The performance
increase on a optimized file system is very noticable.
--
Branch Technology | zeeff@b-tech.ann-arbor.mi.us
| Ann Arbor, MI
rick@pcrat.uucp (Rick Richardson) (10/15/89)
In article <1989Oct14.130123.1067@pcrat.uucp> rick@pcrat.UUCP (Rick Richardson) writes: >I would like to warn people that even after applying Georges patches, >which are good, there are still some other problems with packdisk. I fixed the stuff for 16 bit machines, Venix/286 filesystems, and made a performance enhancement. I present the entire package again here, with Georges and my changes, because the "patch" file was twice as big as just sending the whole shar. I believe that the changes are all compatible and integrated with the original package. I've run this on a 44 MB filesystem which was horribly fragmented (46% fragmented, average seek 139 cyls). The filesystem is now less than 2% fragmented with an average seek of 1.02 cyclinders. I'm done with "packdisk", and I doubt I'll need it again for several months. The performance improvement I made (added a reference count) was critical to the success of using packdisk on 16 bit hardware. Before the algorithm change, extrapolation led me to estimate that the process would take some 60 hours to complete. The original algorithm was compute bound, moving a block only every 2-4 seconds. Worse yet, the portion of the algorithm that was compute bound was approximately quadratic with the size of the partition being repacked. After the improvement, the program is nearly I/O bound, and runs some twenty times faster. I repacked the 44MB's in 3 hours flat on an 80286 running at 7.5 Mhz. Standard IBM AT disk controller (3:1), and a Micropolis 28 msec drive. Most people will want to compile with -DOLDC, and pay attention to the definiton of FsBSIZEdev at the beginning of packdisk.c 16 bit folks will need to add -DSMALL and -Ml (large model), and pay attention to the definition of MAXBLKS. Large model is used because you'll need plenty of memory for the block mapping and reference count arrays. This program has been needed for years, and I congratulate Andy Fyfe for getting the job done. -Rick Richardson PC Research, Inc. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # COPYRIGHT # Makefile # packdisk.c # This archive created: Sun Oct 15 03:08:41 1989 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'README' then echo shar: "will not over-write existing file 'README'" else sed 's/^X//' << \SHAR_EOF > 'README' XThis program rearranges the files and directories on a disk Xso that they appear contiguously. This is to counteract the Xfragmentation that occurs after a time under System V. After Xthe program finishes all the free space will be collected at Xthe end of the disk. X XThis program was written on an AT&T 3b1 (running unix version 3.5). XWhile the program was written with portability in mind, it is *not* Xguaranteed to run on *any* machine, not even the 3b1. It has, Xhowever, worked for me. X XYou should run fsck before running this program, and again after Xit's done, just to be sure! X XThe program is *slow*. However, the disk is updated after *every* Xblock is moved, so the file system should be in a consistent state Xif the program is halted for any reason (except for the free list, Xwhich is not rebuilt until the very end). X XI don't guarantee that this program won't destroy your disk. XMake sure you have a backup just in case!!! X XTo run the program, simply give the disk device as its only Xargument. The program will normally ensure that the given name Xis a character special device. If compiled with '-DDEBUG', this Xcheck is eliminated. This allows, for example, you to "dd" a Xfloppy to a disk file (say /tmp/disk) and then run the program Xwith '/tmp/disk' as its argument. When running on a real disk, Xthe disk in question *must* *not* be mounted!!! X XRemember: THIS PROGRAM IS POTENTIALLY VERY DANGEROUS. Use it Xat your own risk. X X Andrew Fyfe X andy@csvax.caltech.edu X X------------------------------------------------------------------- X * I took George Sipe's "-DOLDC" fixes, and added fixes X * for 16 bit machines "-DSMALL", a compatible fix for filesystems X * that store s_nfree as a short (no compile option needed), and X * the most important thing -- an algorithm speedup. Without X * the speedup, I estimated that the program would take 60 hours X * to run in my environment. It now takes 3 hours, and could be X * improved even more. Look for "RERSPEEDUP" below. The speedup X * invloves using a reference count to decide whether the block X * map needs to be scanned for indirect block references. When X * -DSMALL is defined, the filesystem size is limited to 128K X * 1024 byte blocks. These changes worked for me, and should X * be compatible with the original version. Still, USE AT YOUR X * OWN RISK! X * X * Rick Richardson X * 14 October 1989 X * uunet!pcrat!rick SHAR_EOF fi if test -f 'COPYRIGHT' then echo shar: "will not over-write existing file 'COPYRIGHT'" else sed 's/^X//' << \SHAR_EOF > 'COPYRIGHT' X/* X * Copyright (c) Andrew Fyfe, 1989 X * All rights reserved. X * Written by Andrew Fyfe. X * X * Permission is granted to anyone to use this software for any purpose on X * any computer system, and to alter it and redistribute it freely, subject X * to the following restrictions: X * X * 1. The author is not responsible for the consequences of use of this X * software, no matter how awful, even if they arise from flaws in it. X * X * 2. The origin of this software must not be misrepresented, either by X * explicit claim or by omission. Since few users ever read sources, X * credits must appear in the documentation. X * X * 3. Altered versions must be plainly marked as such, and must not be X * misrepresented as being the original software. Since few users X * ever read sources, credits must appear in the documentation. X * X * 4. This notice may not be removed or altered. X */ X X /* X * This notice is copied from that included with cnews, which was X * written (mostly) by Geoffrey Collyer and Henry Spencer. X */ SHAR_EOF fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else sed 's/^X//' << \SHAR_EOF > 'Makefile' X#CC = gcc -Wall XCC = cc XCFLAGS = -O # System V on 32 bit machine with function prototypes compiler XCFLAGS = -O -DOLDC # System V on 32 bit machine without function prototypes XCFLAGS = -Ml -DSMALL -DOLDC -O # Venix/286 XLINTFLAGS = -DSMALL -DOLDC # Venix/286 XLDFLAGS = # -shlib X Xpackdisk: packdisk.o X $(CC) $(CFLAGS) $(LDFLAGS) -o packdisk packdisk.o X Xlint: X lint $(LINTFLAGS) packdisk.c > lint.out X Xshar: X shar -p X README COPYRIGHT Makefile packdisk.c > packdisk.shar SHAR_EOF fi if test -f 'packdisk.c' then echo shar: "will not over-write existing file 'packdisk.c'" else sed 's/^X//' << \SHAR_EOF > 'packdisk.c' X/* X * X * This program takes a disk and makes all the files and directories, X * and the free list, contiguous. X * X * Andrew Fyfe X * 7 October 1989 X * X * andy@csvax.caltech.edu X */ X X/* X * I took George Sipe's "-DOLDC" fixes, and added fixes X * for 16 bit machines "-DSMALL", a compatible fix for filesystems X * that store s_nfree as a short (no compile option needed), and X * the most important thing -- an algorithm speedup. Without X * the speedup, I estimated that the program would take 60 hours X * to run in my environment. It now takes 3 hours, and could be X * improved even more. Look for "RERSPEEDUP" below. The speedup X * invloves using a reference count to decide whether the block X * map needs to be scanned for indirect block references. When X * -DSMALL is defined, the filesystem size is limited to 128K X * 1024 byte blocks. These changes worked for me, and should X * be compatible with the original version. Still, USE AT YOUR X * OWN RISK! X * X * Rick Richardson X * 14 October 1989 X * uunet!pcrat!rick X */ X X#ifndef OLDC X#include <stdlib.h> X#endif X#include <sys/types.h> X#include <sys/param.h> X#include <sys/filsys.h> X#include <sys/ino.h> X#include <sys/stat.h> X#include <stdio.h> X X#ifndef OLDC X#define FsBSIZEdev FsBSIZE(dev) X#else X#define FsBSIZEdev 1024 /* BE SURE THIS IS OK FOR YOU */ X#endif X X#define NUM_ADDR 13 X#define FIRST_INDIR 10 /* 0-9 direct, 10 single, 11 double, 12 triple */ X#define NUM_INDIR (NUM_ADDR - FIRST_INDIR) X Xchar *cmd_name; Xint disk, dev; X Xstruct filsys filsys; X Xstruct dinode ino; /* current working inode, and its number */ Xino_t w_ino; X Xchar *inode_block; /* block containing last read/written inode */ Xdaddr_t w_ino_blk; /* and its number */ X Xchar *indir[NUM_INDIR]; /* current working indirect blocks */ Xdaddr_t w_indir[NUM_INDIR]; /* and their numbers */ X Xdaddr_t next_fill; /* next (sequential) block to fill */ X Xchar *inode_table; /* a cache of the entire inode section of the disk */ X X#ifdef SMALL X#define MAXINT 32767 /* Size of an integer */ X#define MAXBLKS (128L*1024) /* Max blocks in a filesystem */ X#define MAPSEG (4096) /* # blocks in each array */ X#define MN(BLN) (BLN/MAPSEG) /* Map number to use */ X#define BN(BLN) (BLN&(MAPSEG-1)) /* Block index in map */ X#define MB(BLN) (BLN/MAPSEG)][(BLN&(MAPSEG-1)) Xlong *map[MAXBLKS/MAPSEG]; X /* a map from block numbers to referencing inode/indir block */ Xint *ref[MAXBLKS/MAPSEG]; X /* reference count for block number (RERSPEEDUP) */ X#else X#define MAXINT 2147483647 /* Size of an integer */ Xlong *map; /* a map from block numbers to referencing inode/indir block */ Xint *ref; /* a map from block numbers to referencing inode/indir block */ X#endif X X#ifndef OLDC Xstatic void read_superblk(void); Xstatic void write_superblk(void); Xstatic void map_inode(ino_t inode); Xstatic void update_map(long map_entry, daddr_t block, int level); Xstatic void read_block(daddr_t block, void *buf); Xstatic void write_block(daddr_t block, void *buf); Xstatic void read_inode(ino_t inode, struct dinode *buf); Xstatic void write_inode(ino_t inode, struct dinode *buf); Xstatic void move_block(daddr_t from, daddr_t to); Xstatic void move_inode(ino_t inode); Xstatic void move_indirect(daddr_t block, int level); Xstatic void make_hole(void); Xstatic void rebuild_free_list(void); X Xextern void l3tol(long *, char *, int length); Xextern void ltol3(char *, long *, int length); X#else X#define move_indirect Move_Indirect /* make uniq */ Xextern char *calloc(); Xextern char *malloc(); Xextern char *memcpy(); Xextern char *memset(); Xextern long lseek(); Xextern void exit(); Xextern void perror(); X Xstatic void read_superblk(); Xstatic void write_superblk(); Xstatic void map_inode(); Xstatic void update_map(); Xstatic void read_block(); Xstatic void write_block(); Xstatic void read_inode(); Xstatic void write_inode(); Xstatic void move_block(); Xstatic void move_inode(); Xstatic void move_indirect(); Xstatic void make_hole(); Xstatic void rebuild_free_list(); X Xextern void l3tol(); Xextern void ltol3(); X#endif X Xint main(argc, argv) Xint argc; Xchar *argv[]; X{ X ino_t inode, total_inodes; X daddr_t block; X long isize; X int ilimit = -1; X int i; X#ifndef OLDC X char *ctime(long *); X#ifndef DEBUG X struct stat statb; X extern int stat(const char *, struct stat *); X#endif X#else X char *ctime(); X#ifndef DEBUG X struct stat statb; X extern int stat(); X#endif X#endif X X cmd_name = argv[0]; X X if (argc < 2) { X (void) fprintf(stderr, "%s: Usage: %s <file system>\n", X cmd_name, cmd_name); X exit(1); X } X X if (argc == 3) ilimit = atoi(argv[2]); X X#ifndef DEBUG X if (stat(argv[1], &statb) < 0) { X (void) fprintf(stderr, "%s: can't stat %s: ", cmd_name, argv[1]); X perror(""); X exit(1); X } X if ((statb.st_mode & S_IFMT) != S_IFCHR) { X (void) fprintf(stderr, "%s: %s is not a character device\n", X cmd_name, argv[1]); X exit(1); X } X#endif X X disk = open(argv[1], 2, 0); X if (disk < 0) { X (void) fprintf(stderr, "%s: can't open %s: ", cmd_name, argv[1]); X perror(""); X exit(1); X } X X read_superblk(); X X total_inodes = (filsys.s_isize - FsITOD(dev, ROOTINO)) * FsINOPB(dev); X (void) fprintf(stderr, "File system: name: \"%.6s\", pack: \"%.6s\"\n", X filsys.s_fname, filsys.s_fpack); X (void) fprintf(stderr, "\tlast modified on %s", ctime(&filsys.s_time)); X (void) fprintf(stderr, X "\ttotal inodes = %d, data blocks = %ld, total = %ld blocks\n", X total_inodes, filsys.s_fsize - filsys.s_isize, filsys.s_fsize); X (void) fprintf(stderr, "\tfree blocks = %ld, free inodes = %d\n", X filsys.s_tfree, filsys.s_tinode); X X for (i = 0; i < NUM_INDIR; ++i) { X w_indir[i] = 0; X indir[i] = (char *) malloc((unsigned) FsBSIZE(dev)); X if (indir[i] == 0) { X (void) fprintf(stderr, "%s: can't malloc indir buffer space: ", X cmd_name); X perror(""); X exit(1); X } X } X w_ino = 0; X X# ifdef SMALL X for (isize = filsys.s_fsize, i = 0; isize > 0; ++i) X { X map[i] = (long *) calloc((unsigned) MAPSEG, sizeof(long)); X ref[i] = (int *) calloc((unsigned) MAPSEG, sizeof(int)); X isize -= MAPSEG; X if (map[i] == 0 || ref[i] == 0) { X (void) fprintf(stderr, "%s: can't calloc map: ", cmd_name); X perror(""); X exit(1); X } X } X# else X map = (long *) calloc((unsigned) filsys.s_fsize, sizeof(*map)); X ref = (int *) calloc((unsigned) filsys.s_fsize, sizeof(*ref)); X if (map == 0 || ref == 0) { X (void) fprintf(stderr, "%s: can't calloc map: ", cmd_name); X perror(""); X exit(1); X } X# endif X X isize = (long) filsys.s_isize * FsBSIZE(dev); X if (isize > MAXINT) X inode_table = NULL; X else X inode_table = (char *) malloc((unsigned) isize); X if (inode_table == 0) { X (void) fprintf(stderr, "%s: can't malloc space for inode table\n", X cmd_name); X (void) fprintf(stderr, "%s: that's OK, I will just run slower\n", X cmd_name); X w_ino_blk = 0; X inode_block = (char *) malloc((unsigned) FsBSIZE(dev)); X if (inode_block == 0) { X (void) fprintf(stderr, "%s: can't malloc inode buffer space: %u", X cmd_name, FsBSIZE(dev)); X perror(""); X exit(1); X } X } X else X for (block = FsITOD(dev, ROOTINO); block < filsys.s_isize; ++block) X read_block(block, &inode_table[block * FsBSIZE(dev)]); X X (void) fprintf(stderr, "mapping..."); X for (inode = ROOTINO; inode <= total_inodes; ++inode) X map_inode(inode); X (void) fprintf(stderr, "done\n"); X X next_fill = filsys.s_isize; X if (ilimit >= 0) X for (inode = ROOTINO; inode <= ilimit; ++inode) X move_inode(inode); X else X for (inode = ROOTINO; inode <= total_inodes; ++inode) X move_inode(inode); X X (void) fprintf(stderr, "\nrebuilding the free list\n"); X rebuild_free_list(); X X (void) fprintf(stderr, "*** Run fsck to check out the disk!!!\n"); X X (void) close(disk); X exit(0); X /* NOTREACHED */ X} X Xstatic void read_superblk() X{ X if (lseek(disk, (long) SUPERBOFF, 0) != (long) SUPERBOFF) { X (void) fprintf(stderr, "%s: can't seek to superblock: ", cmd_name); X perror(""); X exit(1); X } X if (read(disk, (char *) &filsys, sizeof(filsys)) != sizeof(filsys)) { X (void) fprintf(stderr, "%s: can't read superblock: ", cmd_name); X perror(""); X exit(1); X } X if (filsys.s_magic != FsMAGIC) { X (void) fprintf(stderr, "%s: invalid superblock magic number\n", X cmd_name); X exit(1); X } X dev = (filsys.s_type == Fs2b) ? Fs2BLK : 0; X} X Xstatic void write_superblk() X{ X if (lseek(disk, (long) SUPERBOFF, 0) == -1L) { X (void) fprintf(stderr, "%s: can't seek to superblock: ", cmd_name); X perror(""); X exit(1); X } X if (write(disk, (char *) &filsys, sizeof(filsys)) != sizeof(filsys)) { X (void) fprintf(stderr, "%s: can't write superblock: ", cmd_name); X perror(""); X exit(1); X } X} X Xstatic void map_inode(inode) Xino_t inode; X{ X int type, i; X long block[NUM_ADDR]; X X read_inode(inode, &ino); X if (ino.di_mode == 0) X return; X type = ino.di_mode & S_IFMT; X if (type == S_IFCHR || type == S_IFBLK) X return; X X l3tol(block, ino.di_addr, NUM_ADDR); X for (i = 0; i < NUM_ADDR; ++i) X if (block[i] != 0) X update_map((long) inode, block[i], X (i < FIRST_INDIR) ? 0 : (i - FIRST_INDIR + 1)); X} X Xstatic void update_map(map_entry, block, level) Xlong map_entry; Xdaddr_t block; Xint level; X{ X int i; X X if (map[MB(block)] != 0) { X (void) fprintf(stderr, "%s: duplicate block %d in %d and %d\n", X cmd_name, block, map[block], map_entry); X exit(1); X } X map[MB(block)] = map_entry; X X if (map_entry < 0) X ++ref[MB(-map_entry)]; /* RERSPEEDUP: maintain reference count */ X /* for indirect blocks */ X X if (level == 0) X return; X X --level; X read_block(block, indir[level]); X for (i = 0; i < FsNINDIR(dev); ++i) X if (((daddr_t *)indir[level])[i] != 0) X update_map(-block, ((daddr_t *)indir[level])[i], level); X} X Xstatic void read_block(block, buf) Xdaddr_t block; Xchar *buf; X{ X if (lseek(disk, (long) block * FsBSIZE(dev), 0) == -1L) { X (void) fprintf(stderr, "%s: can't seek block %ld, addr %ld: ", X cmd_name, block, (long) block * FsBSIZE(dev) ); X perror(""); X exit(1); X } X if (read(disk, buf, (unsigned) FsBSIZE(dev)) != FsBSIZE(dev)) { X (void) fprintf(stderr, "%s: can't read block %ld, addr %ld: ", X cmd_name, block, (long) block * FsBSIZE(dev) ); X perror(""); X exit(1); X } X} X Xstatic void write_block(block, buf) Xdaddr_t block; Xchar *buf; X{ X if (lseek(disk, (long) block * FsBSIZE(dev), 0) == -1L X || write(disk, buf, (unsigned) FsBSIZE(dev)) != FsBSIZE(dev)) { X (void) fprintf(stderr, "%s: can't write block %d: ", cmd_name, block); X perror(""); X exit(1); X } X} X Xstatic void read_inode(inode, the_ino) Xino_t inode; Xstruct dinode *the_ino; X{ X daddr_t block; X X block = FsITOD(dev, inode); X if (inode_table == 0) { X if (w_ino_blk != block) { X w_ino_blk = block; X read_block(block, inode_block); X } X *the_ino = ((struct dinode *)inode_block)[FsITOO(dev, inode)]; X } X else { X *the_ino = ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) X [FsITOO(dev, inode)]; X } X} X Xstatic void write_inode(inode, the_ino) Xino_t inode; Xstruct dinode *the_ino; X{ X daddr_t block; X X block = FsITOD(dev, inode); X if (inode_table == 0) { X if (w_ino_blk != block) { X w_ino_blk = block; X read_block(block, inode_block); X } X ((struct dinode *)inode_block)[FsITOO(dev, inode)] = *the_ino; X write_block(block, inode_block); X } X else { X ((struct dinode *)&inode_table[block * FsBSIZE(dev)]) X [FsITOO(dev, inode)] = *the_ino; X write_block(block, &inode_table[block * FsBSIZE(dev)]); X } X} X Xstatic void move_block(from, to) Xdaddr_t from; Xdaddr_t to; X{ X char buffer[FsBSIZEdev]; X daddr_t block; X daddr_t negfrom = -from; X daddr_t negto = -to; X# ifdef SMALL X register int bn, seg; X long *mapp; X# endif X X if (map[MB(to)] != 0) X make_hole(); X X read_block(from, buffer); X write_block(to, buffer); X X map[MB(to)] = map[MB(from)]; X ref[MB(to)] = ref[MB(from)]; X map[MB(from)] = 0; X ref[MB(from)] = 0; X X if (ref[MB(to)]) X { X /* RERSPEEDUP X * The original algorithm did the "for" loop every time X * a block was moved, searching for indirect blocks which X * contain the "from" disk address. I added a reference X * count so we only do the search if there is at least one X * indirect block that has the address. This was a twenty X * fold improvement in speed, and changed the program from X * being compute bound to being I/O bound most of the time. X * In fact, you could abort the for loop early once you've X * found "ref[]" indirect blocks. I didn't, since the X * number of files with indirect blocks was only 10% of all X * of my files. The two second delay for the search proved X * convenient for hitting INTERRUPT in case I wanted to stop. X * X * I also tuned the loop a little for the braindamage of having X * to segment the map on a 16 bit machine. X */ X X (void) fprintf(stderr, "%c", 007); /* Beep */ X# ifdef SMALL X bn = BN(filsys.s_isize); seg = MN(filsys.s_isize); X mapp = &map[seg][bn]; X for (block = filsys.s_isize; block < filsys.s_fsize; ) X { X if (*mapp == negfrom) X *mapp = negto; X ++block; ++mapp; X if (++bn >= MAPSEG) X { X ++seg; bn = 0; mapp = map[seg]; X } X } X# else X for (block = filsys.s_isize; block < filsys.s_fsize; ++block) X if (map[MB(block)] == negfrom) X map[MB(block)] = negto; X# endif X } X} X Xstatic void move_inode(inode) Xino_t inode; X{ X int type, i; X long block[NUM_ADDR]; X X read_inode(inode, &ino); X w_ino = inode; X if (ino.di_mode == 0) X return; X type = ino.di_mode & S_IFMT; X if (type == S_IFCHR || type == S_IFBLK) X return; X X (void) fprintf(stderr, X "moving inode %d (size %ld) \r", X inode, ino.di_size); X X l3tol(block, ino.di_addr, NUM_ADDR); X for (i = 0; i < NUM_ADDR; ++i) { X if (block[i] == 0) X continue; X if (block[i] != next_fill) { X move_block(block[i], next_fill); X l3tol(block, ino.di_addr, NUM_ADDR); X block[i] = next_fill; X ltol3(ino.di_addr, block, NUM_ADDR); X write_inode(inode, &ino); X } X ++next_fill; X } X X for (i = FIRST_INDIR; i < NUM_ADDR; ++i) X move_indirect(block[i], i-FIRST_INDIR); X} X Xstatic void move_indirect(block, level) Xdaddr_t block; Xint level; X{ X int i; X X if (block == 0) X return; X X read_block(block, indir[level]); X w_indir[level] = block; X X for (i = 0; i < FsNINDIR(dev); ++i) { X if (((daddr_t *)indir[level])[i] == 0) X continue; X if (((daddr_t *)indir[level])[i] != next_fill) { X move_block(((daddr_t *)indir[level])[i], next_fill); X ((daddr_t *)indir[level])[i] = next_fill; X write_block(block, indir[level]); X } X ++next_fill; X } X X if (level == 0) X return; X X for (i = 0; i < FsNINDIR(dev); ++i) X move_indirect(((daddr_t *)indir[level])[i], level-1); X} X Xstatic void make_hole() X{ X char t_indir[FsBSIZEdev]; X daddr_t *p_indir; X struct dinode t_ino, *p_ino; X long block[NUM_ADDR]; X daddr_t back; X int i; X X back = filsys.s_fsize - 1; X while (next_fill < back && map[MB(back)] != 0) X --back; X X if (next_fill >= back) { X (void) fprintf(stderr, "%s: can't find a free block for %d\n", X cmd_name, next_fill); X exit(1); X } X X move_block(next_fill, back); X X if (map[MB(back)] < 0) { X block[0] = -map[MB(back)]; X for (i = 0; i < NUM_INDIR; ++i) X if (block[0] == w_indir[i]) X break; X if (i < NUM_INDIR) { X p_indir = (daddr_t *)indir[i]; X } X else { X p_indir = (daddr_t *)t_indir; X read_block(block[0], t_indir); X } X for (i = 0; i < FsNINDIR(dev); ++i) { X if (p_indir[i] == next_fill) { X p_indir[i] = back; X break; X } X } X if (i == FsNINDIR(dev)) { X (void) fprintf(stderr, X "%s: panic: can't find %d in indirect block %d\n", X cmd_name, next_fill, -map[MB(back)]); X exit(1); X } X write_block(block[0], (char *) p_indir); X } X else { X if (map[MB(back)] == w_ino) { X p_ino = &ino; X } X else { X p_ino = &t_ino; X read_inode((ino_t) map[MB(back)], &t_ino); X } X l3tol(block, p_ino->di_addr, NUM_ADDR); X for (i = 0; i < NUM_ADDR; ++i) { X if (block[i] == next_fill) { X block[i] = back; X ltol3(p_ino->di_addr, block, NUM_ADDR); X break; X } X } X if (i == NUM_ADDR) { X (void) fprintf(stderr, "%s: panic: can't find %d in inode %d\n", X cmd_name, next_fill, map[MB(back)]); X exit(1); X } X write_inode((ino_t) map[MB(back)], p_ino); X } X} X Xstatic void rebuild_free_list() X{ X long free_size, nfree; X daddr_t free[NICFREE], block; X char buf[FsBSIZEdev]; X X free_size = filsys.s_fsize - next_fill; X if (free_size != filsys.s_tfree) { X (void) fprintf(stderr, "%s: free list changed size from %ld to %ld\n", X cmd_name, filsys.s_tfree, free_size); X exit(1); X } X X nfree = 1; X (void) memset((char *) free, 0, sizeof(free)); X (void) memset(buf, 0, sizeof(buf)); X X for (block = filsys.s_fsize - 1; block >= next_fill; --block) { X if (nfree == NICFREE) { X if (sizeof(filsys.s_nfree) == sizeof(short)) X { /* Venix/286 has a short s_nfree member */ X ((short *)buf)[0] = nfree; X (void) memcpy((char *) (&((short *)buf)[1]), X (char *) free, sizeof(free)); X } X else X { /* The usual case for System V */ X ((daddr_t *)buf)[0] = nfree; X (void) memcpy((char *) (&((daddr_t *)buf)[1]), X (char *) free, sizeof(free)); X } X write_block(block, buf); X nfree = 0; X (void) memset((char *) free, 0, sizeof(free)); X } X free[nfree++] = block; X } X X filsys.s_nfree = nfree; X (void) memcpy((char *) filsys.s_free, (char *) free, sizeof(free)); X write_superblk(); X} SHAR_EOF fi exit 0 # End of shell archive -- Rick Richardson | Looking for FAX software for UNIX/386 ?????? mention PC Research,Inc.| WE'RE SHIPPING your uunet!pcrat!rick| Ask about FaxiX - UNIX Facsimile System (tm) FAX # (201) 389-8963 | Or JetRoff - troff postprocessor for the HP {Laser,Desk}Jet
karl@sugar.hackercorp.com (Karl Lehenbauer) (10/16/89)
In article <1989Oct14.130123.1067@pcrat.uucp> rick@pcrat.UUCP (Rick Richardson)
writes warning about trying to use packdisk on 16-bit machines.
Thanks for mentioning that, I forgot. Yes, 286 guys and such, this program
needs a good deal of scrutiny before using it on your filesystems. Considering
all the hassle Microport had with 16-bit integer errors (restricting filesystems
to 32 MB), I'd be very careful indeed.
--
-- uunet!sugar!karl "There is hopeful symbolism in the fact that
-- flags do not wave in a vacuum." -- Arthur C. Clarke
-- Usenet access: (713) 438-5018
chuckb@hounix.UUCP (Chuck Bentley) (10/17/89)
In article <1989Oct15.073237.2472@pcrat.uucp>, rick@pcrat.uucp (Rick Richardson) writes: > I've run this on a 44 MB filesystem which was horribly fragmented > (46% fragmented, average seek 139 cyls). The filesystem is now > less than 2% fragmented with an average seek of 1.02 cyclinders. What do you use to measure this? Is it public domain? I haven't seen anything in the archives that would indicate that it would give this kind on information. Then again I've been told I need glasses. :-) Chuck..
rick@pcrat.uucp (Rick Richardson) (10/17/89)
In article <1989Oct15.073237.2472@pcrat.uucp> rick@pcrat.UUCP (Rick Richardson) writes: > >I fixed the stuff for 16 bit machines, Venix/286 filesystems, and >made a performance enhancement.... It turned out that the free list tweak I made for Venix/286 wasn't portable. So I've made it a compile time option. It wouldn't cause any damage, since fsck is perfectly capable of building a clean free list. It also turned out that I missed defining "MB" when SMALL is not defined. The definition was obvious: "#define MB(BLN) BLN". Here is a context diff for "patch" to fix these minor glitches. Apply it to _my_ version posted to comp.sources.d, not to the original source. Also, a couple of people have complained that I didn't post my version to comp.sources.misc. Hey, that's not my job! Its up to the original author to post the changed ("final") version for posterity. My version is mearly a "suggestion". If the author fails to complete his duties within several months, *then and only then* I'd consider posting my changed version to comp.sources.misc for archiving. -Rick *** old/Makefile Tue Oct 17 03:10:29 1989 --- Makefile Tue Oct 17 03:20:42 1989 *************** *** 1,3 #CC = gcc -Wall CC = cc CFLAGS = -O # System V on 32 bit machine with function prototypes compiler --- 1,13 ----- + # + # Makefile for packdisk + # Options: + # -DOLDC Compiler doesn't have function prototypes + # -DSMALL Machine is 16 bit (80286) + # -DSHORTFREE UNIX (e.g. Venix.286) stores the number + # of free block numbers in free disk blocks + # as a short instead of a long (despite what + # the fs(4) manual says). + # #CC = gcc -Wall CC = cc CFLAGS = -O # System V on 32 bit machine with function prototypes compiler *************** *** 1,6 #CC = gcc -Wall CC = cc CFLAGS = -O # System V on 32 bit machine with function prototypes compiler CFLAGS = -O -DOLDC # System V on 32 bit machine without function prototypes CFLAGS = -Ml -DSMALL -DOLDC -O # Venix/286 LINTFLAGS = -DSMALL -DOLDC # Venix/286 --- 11,17 ----- #CC = gcc -Wall CC = cc CFLAGS = -O # System V on 32 bit machine with function prototypes compiler + CFLAGS = -Ml -DSMALL -DOLDC -DSHORTFREE -O # Venix/286 CFLAGS = -O -DOLDC # System V on 32 bit machine without function prototypes LINTFLAGS = -DSMALL -DOLDC # Venix/286 *************** *** 2,8 CC = cc CFLAGS = -O # System V on 32 bit machine with function prototypes compiler CFLAGS = -O -DOLDC # System V on 32 bit machine without function prototypes ! CFLAGS = -Ml -DSMALL -DOLDC -O # Venix/286 LINTFLAGS = -DSMALL -DOLDC # Venix/286 LDFLAGS = # -shlib --- 13,19 ----- CFLAGS = -O # System V on 32 bit machine with function prototypes compiler CFLAGS = -Ml -DSMALL -DOLDC -DSHORTFREE -O # Venix/286 CFLAGS = -O -DOLDC # System V on 32 bit machine without function prototypes ! LINTFLAGS = -DSMALL -DOLDC # Venix/286 LDFLAGS = # -shlib *** old/packdisk.c Tue Oct 17 03:10:33 1989 --- packdisk.c Tue Oct 17 03:25:30 1989 *************** *** 17,23 * the speedup, I estimated that the program would take 60 hours * to run in my environment. It now takes 3 hours, and could be * improved even more. Look for "RERSPEEDUP" below. The speedup ! * invloves using a reference count to decide whether the block * map needs to be scanned for indirect block references. When * -DSMALL is defined, the filesystem size is limited to 128K * 1024 byte blocks. These changes worked for me, and should --- 17,23 ----- * the speedup, I estimated that the program would take 60 hours * to run in my environment. It now takes 3 hours, and could be * improved even more. Look for "RERSPEEDUP" below. The speedup ! * involves using a reference count to decide whether the block * map needs to be scanned for indirect block references. When * -DSMALL is defined, the filesystem size is limited to 128K * 1024 byte blocks. These changes worked for me, and should *************** *** 27,32 * Rick Richardson * 14 October 1989 * uunet!pcrat!rick */ #ifndef OLDC --- 27,42 ----- * Rick Richardson * 14 October 1989 * uunet!pcrat!rick + * + * It turned out that the change I made to handle Venix's weirdness + * with the s_nfree field (in free disk blocks only) wasn't portable. + * I added a compile time option to handle it, -DSHORTFREE. Most + * UNIXes won't need it. I also added the missing "MB" macro for + * when -DSMALL isn't supplied. + * Rick Richardson + * 17 October 1989 + * uunet!pcrat!rick + * */ #ifndef OLDC *************** *** 80,85 /* reference count for block number (RERSPEEDUP) */ #else #define MAXINT 2147483647 /* Size of an integer */ long *map; /* a map from block numbers to referencing inode/indir block */ int *ref; /* a map from block numbers to referencing inode/indir block */ #endif --- 90,96 ----- /* reference count for block number (RERSPEEDUP) */ #else #define MAXINT 2147483647 /* Size of an integer */ + #define MB(BLN) BLN long *map; /* a map from block numbers to referencing inode/indir block */ int *ref; /* a map from block numbers to referencing inode/indir block */ #endif *************** *** 651,657 for (block = filsys.s_fsize - 1; block >= next_fill; --block) { if (nfree == NICFREE) { ! if (sizeof(filsys.s_nfree) == sizeof(short)) { /* Venix/286 has a short s_nfree member */ ((short *)buf)[0] = nfree; (void) memcpy((char *) (&((short *)buf)[1]), --- 662,668 ----- for (block = filsys.s_fsize - 1; block >= next_fill; --block) { if (nfree == NICFREE) { ! # ifdef SHORTFREE { /* Venix/286 has a short s_nfree member */ ((short *)buf)[0] = nfree; (void) memcpy((char *) (&((short *)buf)[1]), *************** *** 657,663 (void) memcpy((char *) (&((short *)buf)[1]), (char *) free, sizeof(free)); } ! else { /* The usual case for System V */ ((daddr_t *)buf)[0] = nfree; (void) memcpy((char *) (&((daddr_t *)buf)[1]), --- 668,674 ----- (void) memcpy((char *) (&((short *)buf)[1]), (char *) free, sizeof(free)); } ! # else { /* The usual case for System V */ ((daddr_t *)buf)[0] = nfree; (void) memcpy((char *) (&((daddr_t *)buf)[1]), *************** *** 663,668 (void) memcpy((char *) (&((daddr_t *)buf)[1]), (char *) free, sizeof(free)); } write_block(block, buf); nfree = 0; (void) memset((char *) free, 0, sizeof(free)); --- 674,680 ----- (void) memcpy((char *) (&((daddr_t *)buf)[1]), (char *) free, sizeof(free)); } + # endif write_block(block, buf); nfree = 0; (void) memset((char *) free, 0, sizeof(free)); -- Rick Richardson | Looking for FAX software for UNIX/386 ?????? mention PC Research,Inc.| WE'RE SHIPPING your uunet!pcrat!rick| Ask about FaxiX - UNIX Facsimile System (tm) FAX # (201) 389-8963 | Or JetRoff - troff postprocessor for the HP {Laser,Desk}Jet
karl@sugar.hackercorp.com (Karl Lehenbauer) (10/18/89)
Here is a patch to the version of packdisk that was recently posted containing i286 fixes and radical performance improvements. This patch makes packdisk compile under Unix System V/386 release 3.2, and may apply to other 3.2 release. The #ifdef'ed code is activated by doing a -DI386 on the command line. Also there was a problem in that the small memory changes made the normal large memory stuff not compile. The problem was that the MB macro was not defined if large model. This is a great tool, thanks to the author and those producing patches, especially the performance improvements. Again, remember to always backup before using and run fsck before and after. -karl ---------------------------- cut here ---------------------------- *** packdisk.c.orig Tue Oct 17 20:01:28 1989 --- packdisk.c Mon Oct 16 01:25:33 1989 *************** *** 34,39 #endif #include <sys/types.h> #include <sys/param.h> #include <sys/filsys.h> #include <sys/ino.h> #include <sys/stat.h> --- 34,44 ----- #endif #include <sys/types.h> #include <sys/param.h> + #ifdef I386 + #include <sys/fs/s5param.h> + #include <sys/fs/s5filsys.h> + #include <sys/fs/s5macros.h> + #else #include <sys/filsys.h> #endif #include <sys/ino.h> *************** *** 35,40 #include <sys/types.h> #include <sys/param.h> #include <sys/filsys.h> #include <sys/ino.h> #include <sys/stat.h> #include <stdio.h> --- 40,46 ----- #include <sys/fs/s5macros.h> #else #include <sys/filsys.h> + #endif #include <sys/ino.h> #include <sys/stat.h> #include <stdio.h> *************** *** 39,44 #include <sys/stat.h> #include <stdio.h> #ifndef OLDC #define FsBSIZEdev FsBSIZE(dev) #else --- 45,54 ----- #include <sys/stat.h> #include <stdio.h> + #ifdef I386 + #define ROOTINO S5ROOTINO + #endif + #ifndef OLDC #define FsBSIZEdev FsBSIZE(dev) #else *************** *** 82,87 #define MAXINT 2147483647 /* Size of an integer */ long *map; /* a map from block numbers to referencing inode/indir block */ int *ref; /* a map from block numbers to referencing inode/indir block */ #endif #ifndef OLDC --- 92,98 ----- #define MAXINT 2147483647 /* Size of an integer */ long *map; /* a map from block numbers to referencing inode/indir block */ int *ref; /* a map from block numbers to referencing inode/indir block */ + #define MB(BLN) (BLN) #endif #ifndef OLDC -- -- uunet!sugar!karl "There is hopeful symbolism in the fact that -- flags do not wave in a vacuum." -- Arthur C. Clarke -- Usenet access: (713) 438-5018
roe@sobmips.UUCP (r.peterson) (10/21/89)
From article <3648@hounix.UUCP>, by chuckb@hounix.UUCP (Chuck Bentley): [ stuff about frag measurement deleted ] > > What do you use to measure this? Is it public domain? I haven't seen > anything in the archives that would indicate that it would give this > kind on information. Then again I've been told I need glasses. :-) Try comp.sources.misc, volume5, fsanalyze4.1 - I just ported it to the NCR tower/32 (1.03.02/2.01) and the mips(4.0) (with some hassles) - but it works just fine. -- Roe Peterson {attcan,mcgill-vision,telly}!sobeco!roe
jfh@rpp386.cactus.org (John F. Haugh II) (10/21/89)
In article <1989Oct21.013237.29071@sobmips.UUCP> roe@sobmips.UUCP (r.peterson) writes: >From article <3648@hounix.UUCP>, by chuckb@hounix.UUCP (Chuck Bentley): >> What do you use to measure this? Is it public domain? I haven't seen >> anything in the archives that would indicate that it would give this >> kind on information. Then again I've been told I need glasses. :-) > >Try comp.sources.misc, volume5, fsanalyze4.1 - I just ported it to >the NCR tower/32 (1.03.02/2.01) and the mips(4.0) (with some hassles) - >but it works just fine. I have it here. The sizes and filenames are % ls -s /usr/archive/fsanalyze/* 46 /usr/archive/fsanalyze/fsanal.sh.1.Z 44 /usr/archive/fsanalyze/fsanal.sh.2.Z 28 /usr/archive/fsanalyze/fsanal.sh.3.Z and the L.sys line is rpp386 Any ACU 2400 15128328835 in:--in:--in: uucp -- John F. Haugh II +-Things you didn't want to know:------ VoiceNet: (512) 832-8832 Data: -8835 | The real meaning of EMACS is ... InterNet: jfh@rpp386.cactus.org | ... EMACS makes a computer slow. UUCPNet: {texbell|bigtex}!rpp386!jfh +--<><--<><--<><--<><--<><--<><--<><---