badblocks.c revision a418d3ad819323f871005d253f7f9ac378e78ba5
13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * badblocks.c - Bad blocks checker 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 455f4cbd96e0029f0ff67c4913192d87bf52fd149Theodore Ts'o * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> 555f4cbd96e0029f0ff67c4913192d87bf52fd149Theodore Ts'o * Laboratoire MASI, Institut Blaise Pascal 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * Universite Pierre et Marie Curie (Paris VI) 719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * This file is based on the minix file system programs fsck and mkfs 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * written and copyrighted by Linus Torvalds <Linus.Torvalds@cs.helsinki.fi> 1019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * This file can be redistributed under the terms of the GNU General 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Public License 133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 14efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 16efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * History: 173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 93/05/26 - Creation from e2fsck 183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 94/02/27 - Made a separate bad blocks checker 19ebabf2ad6d19af5c674b624bafe619dedbc94403Theodore Ts'o */ 20ebabf2ad6d19af5c674b624bafe619dedbc94403Theodore Ts'o 21d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include <errno.h> 22a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <fcntl.h> 233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifdef HAVE_GETOPT_H 24d0c537748d5a9799dd0658b0a5cceaafc28084bbTheodore Ts'o#include <getopt.h> 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif 263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <signal.h> 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 28756df353e8ffd010fcca8cef8972cf27006edb6aTheodore Ts'o#include <stdlib.h> 292740156bd12747389eaf745529653b26a3a9d73dTheodore Ts'o#include <string.h> 302740156bd12747389eaf745529653b26a3a9d73dTheodore Ts'o#include <unistd.h> 31a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o 323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/ioctl.h> 33373b8337c7b6c6243810be250083fa4773891e92Theodore Ts'o#include <sys/types.h> 34373b8337c7b6c6243810be250083fa4773891e92Theodore Ts'o 35373b8337c7b6c6243810be250083fa4773891e92Theodore Ts'o#if HAVE_LINUX_FS_H 36a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <linux/fd.h> 37a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include <linux/fs.h> 383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif 39a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o 40a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o#include "et/com_err.h" 413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs/io.h" 42a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o 43a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'oconst char * program_name = "badblocks"; 44a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'o 45a418d3ad819323f871005d253f7f9ac378e78ba5Theodore Ts'oint v_flag = 0; /* verbose */ 463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint w_flag = 0; /* do r/w test */ 47f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'oint s_flag = 0; /* show progress of test */ 4813b0b1231ed28aac75ba336de7a8cb3b4611ce68Eric Sandeen 49b626b39a8c87dfb6d973b4ad7eca1eefa659d3d6Aneesh Kumar K.Vstatic volatile void usage (void) 50365857912e27914afa8857af5adf74ee19ca9e03Theodore Ts'o{ 519ed8e5fec226aa53634ed95cbeac736d90a518e5Eric Sandeen fprintf (stderr, "Usage: %s [-b block_size] [-o output_file] [-svw] device blocks_count\n [start_count]\n", 52f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o program_name); 5354c637d4d29af3e6365779f8b12976abe95a4753Theodore Ts'o exit (1); 5495fd65bb7fcf84e8d1e207f84b9d5a9f99626a38Valerie Aurora Henson} 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 561e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o/* 57896938d57e7091e7a032674dfeeb91f2a17fd78bTheodore Ts'o * Perform a test of a block; return the number of blocks readable/writeable. 583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 5963985320384bf143eaac9857af424800d9867a1aTheodore Ts'ostatic long do_test (int dev, char * buffer, int try, unsigned long block_size, 609dc6ad1ecb0ba3caf14e05279f1cc3cea52095a2Theodore Ts'o unsigned long current_block) 61a6d8302b4873527798a77c1ba3106a04b71dfeacTheodore Ts'o{ 623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o long got; 63d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o 641f5d7a890e8b2ad03ee91fd891b0b5b4327da030Aditya Kali /* Seek to the correct loc. */ 653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (ext2_llseek (dev, (ext2_loff_t) current_block * block_size, 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o SEEK_SET) != (ext2_loff_t) current_block * block_size) 673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, "during seek"); 68493024ea1d74e4cb48aac3a24111f5c8da343e9fTheodore Ts'o 69493024ea1d74e4cb48aac3a24111f5c8da343e9fTheodore Ts'o /* Try the read */ 706733c2fd0046c525203034f58fc0a8c69fdf480bTheodore Ts'o got = read (dev, buffer, try * block_size); 711e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o if (got < 0) 721e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o got = 0; 731e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o if (got & (block_size - 1)) 747d9e31655fca48e9d6c2647ad443124113508b73Lukas Czerner fprintf (stderr, 757d9e31655fca48e9d6c2647ad443124113508b73Lukas Czerner "Weird value (%ld) in do_test: probably bugs\n", 763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o got); 77f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o got /= block_size; 783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return got; 793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 80d48755e97f7d4cb06092921bff0d3681d30a8acaTheodore Ts'o 813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic unsigned long currently_testing = 0; 823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic unsigned long num_blocks = 0; 8316ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o 8416ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'ostatic void alarm_intr (int alnum) 8516ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o{ 8616ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o signal (SIGALRM, alarm_intr); 877fe5ff3c1e06c4705a7a709a7ed34f02c5a02fd8Lukas Czerner alarm(1); 8837c8db7b2078d0310e5676404e21cc143d8e4d56Theodore Ts'o if (!num_blocks) 8916ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o return; 9016ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o fprintf(stderr, "%9ld/%9ld", currently_testing, num_blocks); 9116ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 9216ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o fflush (stderr); 937fe5ff3c1e06c4705a7a709a7ed34f02c5a02fd8Lukas Czerner} 9416ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o 9516ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'ostatic void flush_bufs (int dev, int sync) 96d678fef0d78fb3c5546cd9398698ddc0106618f6Aditya Kali{ 973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (v_flag 989b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o#if !defined (BLKFLSBUF) && !defined (FDFLUSH) 99b0afdda1bc044026336009576fbe6b72884140cbTheodore Ts'o && sync 10016ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o#endif 10116ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o ) 10216ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o fprintf (stderr, "Flushing buffers\n"); 10316ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o 10416ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o if (sync && fsync (dev) == -1) 105b626b39a8c87dfb6d973b4ad7eca1eefa659d3d6Aneesh Kumar K.V com_err (program_name, errno, "during fsync"); 1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1079dc6ad1ecb0ba3caf14e05279f1cc3cea52095a2Theodore Ts'o#ifdef BLKLSBUF 1089dc6ad1ecb0ba3caf14e05279f1cc3cea52095a2Theodore Ts'o ioctl (dev, BLKFLSBUF, 0); /* In case this is a HD */ 10931e29a12d1e22745c74afe47bf172a3c73280dd9Theodore Ts'o#endif 110d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o#ifdef FDFLUSH 11131e29a12d1e22745c74afe47bf172a3c73280dd9Theodore Ts'o ioctl (dev, FDFLUSH, 0); /* In case this is floppy */ 11263985320384bf143eaac9857af424800d9867a1aTheodore Ts'o#endif 1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 114bdd80f28d759cda94bab13af689d4aee0328dd7fTheodore Ts'o 11528e2cb9e72cce9e97a4a6f738d28b0f3f31efe69Eric Sandeenstatic void test_ro (int dev, unsigned long blocks_count, 116bdd80f28d759cda94bab13af689d4aee0328dd7fTheodore Ts'o unsigned long block_size, FILE * out, 1178dbcbe1c4a4bdd30c6e9aa1a3df9b06f4f3cbee1Yongqiang Yang unsigned long from_count) 1189ba400027fb00ce43d14673346bbfb6f5719985aTheodore Ts'o{ 1199ba400027fb00ce43d14673346bbfb6f5719985aTheodore Ts'o#define TEST_BUFFER_BLOCKS 16 120067911ae734bb5fef7c5780a639533847b5b578cAndreas Dilger char * blkbuf; 121bdd80f28d759cda94bab13af689d4aee0328dd7fTheodore Ts'o int try; 12265794cf159aa051ea3fe79db1950f562600b252eMike Frysinger long got; 12337c8db7b2078d0310e5676404e21cc143d8e4d56Theodore Ts'o 1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o blkbuf = malloc (TEST_BUFFER_BLOCKS * block_size); 1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!blkbuf) 1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, ENOMEM, "while allocating buffers"); 12802d6f47e9647d3155a38c8676c2da6ea773d9b68Jose R. Santos exit (1); 1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o flush_bufs (dev, 0); 1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (v_flag) { 1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, 1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "Checking for bad blocks in read-only mode\n"); 1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, "From block %lu to %lu\n", from_count, blocks_count); 1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o try = TEST_BUFFER_BLOCKS; 1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o currently_testing = from_count; 1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o num_blocks = blocks_count; 1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (s_flag) { 14002d6f47e9647d3155a38c8676c2da6ea773d9b68Jose R. Santos fprintf(stderr, "Checking for bad blocks (read-only test): "); 1411dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o alarm_intr(SIGALRM); 1421dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o } 1431dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o while (currently_testing < blocks_count) 1441dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o { 1451dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o if (currently_testing + try > blocks_count) 1461dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o try = blocks_count - currently_testing; 1471dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o got = do_test (dev, blkbuf, try, block_size, currently_testing); 1481dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o currently_testing += got; 1491d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger if (got == try) { 150d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o try = TEST_BUFFER_BLOCKS; 151d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o continue; 152d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o } 153d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o else 154d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o try = 1; 155d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o if (got == 0) 156d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o fprintf (out, "%lu\n", currently_testing++); 157d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o } 158d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o num_blocks = 0; 159d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o alarm(0); 160d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o if (s_flag) 161d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o fprintf(stderr, "done \n"); 162d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o fflush (stderr); 163d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o free (blkbuf); 164d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o} 165d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o 166d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'ostatic void test_rw (int dev, unsigned long blocks_count, 167d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o unsigned long block_size, FILE * out, 168d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o unsigned long from_count) 169d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o{ 170d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o int i; 1711d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger char * buffer; 172d99225ecceb580d497c649daa4894fa2e10019adTheodore Ts'o unsigned char pattern[] = {0xaa, 0x55, 0xff, 0x00}; 17350787ea22edd8b4662203daf3569411d9dcf4287Theodore Ts'o 1743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o buffer = malloc (2 * block_size); 1753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!buffer) 176544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o { 1773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, ENOMEM, "while allocating buffers"); 1786693837e59cc7b5397a0d46d2753c309382c76f9Theodore Ts'o exit (1); 1793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o flush_bufs (dev, 0); 1823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (v_flag) 1843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, "Checking for bad blocks in read-write mode\n"); 1853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (i = 0; i < sizeof (pattern); i++) 1863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o memset (buffer, pattern[i], block_size); 1883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (s_flag | v_flag) 1893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, "Writing pattern 0x%08x: ", 1903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *((int *) buffer)); 1913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o num_blocks = blocks_count; 1923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o currently_testing = from_count; 1933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (s_flag) 194d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o alarm_intr(SIGALRM); 1953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (; 1963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o currently_testing < blocks_count; 1973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o currently_testing++) 1983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 1993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (ext2_llseek (dev, (ext2_loff_t) currently_testing * 2003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o block_size, SEEK_SET) != 201d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o (ext2_loff_t) currently_testing * block_size) 2023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, 2033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "during seek on block %d", 2043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o currently_testing); 2053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o write (dev, buffer, block_size); 2063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o num_blocks = 0; 2083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o alarm (0); 2093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (s_flag | v_flag) 2103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf(stderr, "done \n"); 2113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o flush_bufs (dev, 1); 2123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (s_flag | v_flag) 2133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (stderr, "Reading and comparing: "); 2143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o num_blocks = blocks_count; 2154efbac6fed75c29d3d5f1b676b932754653a2ac5Valerie Aurora Henson currently_testing = from_count; 2163ed57c27df0ba0942a19c71bc065c8eec3036567Theodore Ts'o if (s_flag) 2174efbac6fed75c29d3d5f1b676b932754653a2ac5Valerie Aurora Henson alarm_intr(SIGALRM); 2183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (; 219d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o currently_testing < blocks_count; 2203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o currently_testing++) 2213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 2223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (ext2_llseek (dev, (ext2_loff_t) currently_testing * 223f37ab68a26bacf4f5cc7643b8373e40292b7682aTheodore Ts'o block_size, SEEK_SET) != 2243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o (ext2_loff_t) currently_testing * block_size) 2253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, errno, 2263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "during seek on block %d", 227f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o currently_testing); 2283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (read (dev, buffer + block_size, block_size) < block_size) 2293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (out, "%ld\n", currently_testing); 230d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o else if (memcmp (buffer, buffer + block_size, block_size)) 2313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf (out, "%ld\n", currently_testing); 2323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o num_blocks = 0; 2343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o alarm (0); 2353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (s_flag | v_flag) 2363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf(stderr, "done \n"); 237544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o flush_bufs (dev, 0); 238544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o } 239544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o} 2403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid main (int argc, char ** argv) 2423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 243f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o char c; 244f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o char * tmp; 245f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o char * device_name; 2463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char * output_file = NULL; 2473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE * out; 2483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o unsigned long block_size = 1024; 249efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o unsigned long blocks_count, from_count; 2503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int dev; 2513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o setbuf(stdout, NULL); 2533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o setbuf(stderr, NULL); 2543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (argc && *argv) 2553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o program_name = *argv; 256cbbf031b6edf9bdf5511af2193e44cff7fdaa66aTheodore Ts'o while ((c = getopt (argc, argv, "b:o:svw")) != EOF) { 257d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o switch (c) { 258d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o case 'b': 259d0ff90d5202428583c78a60c3042e7b60d88bc45Eric Sandeen block_size = strtoul (optarg, &tmp, 0); 260d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o if (*tmp || block_size > 4096) { 2613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, 0, 262544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o "bad block size - %s", optarg); 2633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (1); 2643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 266f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'o': 267f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o output_file = optarg; 268f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 269f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 's': 270f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o s_flag = 1; 271f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 272f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'v': 273f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o v_flag = 1; 274efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o break; 275f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o case 'w': 27692bcc595dcb31ad15e12d8c72e6edfc70545c204Theodore Ts'o w_flag = 1; 277f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o break; 278cbbf031b6edf9bdf5511af2193e44cff7fdaa66aTheodore Ts'o default: 279cbbf031b6edf9bdf5511af2193e44cff7fdaa66aTheodore Ts'o usage (); 280efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o } 281f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 2828deb80a5d1078cbe43eaffcdeebf0a1a549d6a54Takashi Sato if (optind > argc - 1) 283d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o usage (); 284f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o device_name = argv[optind++]; 285f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (optind > argc - 1) 2866493f8e85defc568a4ca8cdb4a53361f36fb94baTheodore Ts'o usage (); 287d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson blocks_count = strtoul (argv[optind], &tmp, 0); 2885711ed297b1a3d94086256b5b3b891d4f77b21caTheodore Ts'o if (*tmp) 2894efbac6fed75c29d3d5f1b676b932754653a2ac5Valerie Aurora Henson { 290f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err (program_name, 0, "bad blocks count - %s", argv[optind]); 291f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o exit (1); 292f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 293f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (++optind <= argc-1) { 294efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o from_count = strtoul (argv[optind], &tmp, 0); 2953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } else from_count = 0; 2963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (from_count >= blocks_count) { 2973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err (program_name, 0, "bad blocks range: %lu-%lu", 298cbbf031b6edf9bdf5511af2193e44cff7fdaa66aTheodore Ts'o from_count, blocks_count); 2993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit (1); 300cbbf031b6edf9bdf5511af2193e44cff7fdaa66aTheodore Ts'o } 301d9c56d3ca0bee11e3446ff7e12e3124d28e298a7Theodore Ts'o dev = open (device_name, w_flag ? O_RDWR : O_RDONLY); 3023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (dev == -1) 3033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o { 304efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o com_err (program_name, errno,"while trying to open %s", 305c6ed60cdeb1355a884f635ac8118c8f330e2ba68Theodore Ts'o device_name); 306cbbf031b6edf9bdf5511af2193e44cff7fdaa66aTheodore Ts'o exit (1); 3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (output_file && strcmp (output_file, "-") != 0) 3096fcd6f84c235f4bf2bd9770f172837da9982eb6eEric Sandeen { 31016ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o out = fopen (output_file, "w"); 31116ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o if (out == NULL) 31202d6f47e9647d3155a38c8676c2da6ea773d9b68Jose R. Santos { 313544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o com_err (program_name, errno,"while trying to open %s", 314e16324210286dc72a013e66d91bd3a59c3ab7538Theodore Ts'o device_name); 31595fd65bb7fcf84e8d1e207f84b9d5a9f99626a38Valerie Aurora Henson exit (1); 31616ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o } 31795fd65bb7fcf84e8d1e207f84b9d5a9f99626a38Valerie Aurora Henson } 31895fd65bb7fcf84e8d1e207f84b9d5a9f99626a38Valerie Aurora Henson else 31995fd65bb7fcf84e8d1e207f84b9d5a9f99626a38Valerie Aurora Henson out = stdout; 3201dde43f0c1176f61dd0bf91aff265ce8cd1c5fd6Theodore Ts'o if (w_flag) 3213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o test_rw (dev, blocks_count, block_size, out, from_count); 322c498cb11d3e72e41af760bd882675f44db8b77e7Theodore Ts'o else 323efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o test_ro (dev, blocks_count, block_size, out, from_count); 324d7cca6b06f366f998ed43346f9b6fca9e163692fValerie Aurora Henson close (dev); 32519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o if (out != stdout) 32616ed5b3af43c72f60991222b9d7ab65cf53f203dTheodore Ts'o fclose (out); 327e16324210286dc72a013e66d91bd3a59c3ab7538Theodore Ts'o} 328e16324210286dc72a013e66d91bd3a59c3ab7538Theodore Ts'o