add directory study
This commit is contained in:
135
study/linux-travel/MINIX-1.5/1.5/Source/commands/readall.c
Normal file
135
study/linux-travel/MINIX-1.5/1.5/Source/commands/readall.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* readall - read a whole device fast Author: Andy Tanenbaum */
|
||||
|
||||
/* Readall reads all the blocks on a device as fast as it can. If it hits
|
||||
* an error, it stops reading in large units and reads one block at a time.
|
||||
* It reports on all errors it finds.
|
||||
*
|
||||
* If the -b flag is given, the output is a shell script that can be run
|
||||
* to mark all the bad blocks.
|
||||
*
|
||||
* If the -t flag is given, only the total numbers of blocks is reported.
|
||||
*
|
||||
* Examples of usage:
|
||||
* readall /dev/hd1 # read /dev/hd1
|
||||
* readall -b /dev/hd2 # prepare bad block list on stdout
|
||||
* readall -t /dev/ram # report size of ram disk
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <blocksize.h>
|
||||
|
||||
#define CHUNK 25 /* max number of blocks read at once */
|
||||
#define RESUME 200 /* # good reads before going back to CHUNK */
|
||||
#define DIVISOR 50 /* how often to print statistics */
|
||||
#define STORE 4096 /* save this many bad blocks for summary */
|
||||
|
||||
int chunk = CHUNK; /* current number of blocks being read */
|
||||
long goodies; /* incremented on good reads */
|
||||
long errors; /* number of errors so far */
|
||||
int normal = 1; /* set unless -b flag is given */
|
||||
int total = 0; /* unset unless -t flag is given */
|
||||
char *name; /* name of special file being read */
|
||||
|
||||
char a[CHUNK * BLOCK_SIZE]; /* read buffer */
|
||||
long rotten[STORE]; /* list of bad blocks */
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int fd, s, i, badprinted;
|
||||
long b = 0;
|
||||
char *p;
|
||||
|
||||
if (argc != 2 && argc != 3) {
|
||||
printf("Usage: readall [-b | -t] file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
i = 1;
|
||||
|
||||
p = argv[1];
|
||||
if (*p == '-' && *(p+1) == 'b' && *(p+2) == '\0') {
|
||||
normal = 0;
|
||||
i++;
|
||||
name = argv[i];
|
||||
}
|
||||
if (*p == '-' && *(p+1) == 't' && *(p+2) == '\0') {
|
||||
normal = 0;
|
||||
total = 1;
|
||||
i++;
|
||||
name = argv[i];
|
||||
}
|
||||
|
||||
fd = open(argv[i], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("%s is not readable\n", argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Read the entire file. Try it in large chunks, but if an error occurs,
|
||||
* go to single reads for a while.
|
||||
*/
|
||||
while (1) {
|
||||
lseek(fd, BLOCK_SIZE * b, SEEK_SET);
|
||||
s = read(fd, a, BLOCK_SIZE * chunk);
|
||||
if (s == BLOCK_SIZE * chunk) {
|
||||
/* Normal read, no errors. */
|
||||
b += chunk;
|
||||
goodies++;
|
||||
if (chunk == 1) {
|
||||
if(goodies >= RESUME && b % DIVISOR == 0)chunk = CHUNK;
|
||||
}
|
||||
} else if (s < 0) {
|
||||
/* I/O error. */
|
||||
if (chunk != 1) {
|
||||
chunk = 1; /* regress to single block mode */
|
||||
continue;
|
||||
}
|
||||
if (errors == STORE) {
|
||||
printf("\n%ld Bad blocks is too many. Exiting\n",errors);
|
||||
exit(1);
|
||||
}
|
||||
rotten[(int)errors] = b; /* log the error */
|
||||
b += chunk;
|
||||
errors++;
|
||||
} else {
|
||||
/* End of file. */
|
||||
b += s/BLOCK_SIZE;
|
||||
if (normal) {
|
||||
output(b);
|
||||
printf("\n");
|
||||
}
|
||||
if (total) printf("%8ld\n", b);
|
||||
if ((errors == 0) || total) exit(0);
|
||||
if (normal)
|
||||
printf("Summary of bad blocks\n");
|
||||
else
|
||||
badprinted = 0;
|
||||
|
||||
/* Print summary of bad blocks, possibly as shell script. */
|
||||
for (i = 0; i < errors; i++) {
|
||||
if (normal == 0 && badprinted == 0) {
|
||||
printf("badblocks %s ", name);
|
||||
badprinted = 1;
|
||||
}
|
||||
printf("%6ld ", rotten[i]);
|
||||
if ( (i+1) % 7 == 0) {
|
||||
printf("\n");
|
||||
badprinted = 0;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
if (normal && b % DIVISOR == 0) output(b);
|
||||
}
|
||||
}
|
||||
|
||||
output(b)
|
||||
long b;
|
||||
{
|
||||
printf("%8ld blocks read, %5ld errors\r", b, errors);
|
||||
}
|
||||
Reference in New Issue
Block a user