119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * badblocks.c - Bad blocks checker 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Laboratoire MASI, Institut Blaise Pascal 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Universite Pierre et Marie Curie (Paris VI) 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright 1995, 1996, 1997, 1998, 1999 by Theodore Ts'o 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright 1999 by David Beattie 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file is based on the minix file system programs fsck and mkfs 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * written and copyrighted by Linus Torvalds <Linus.Torvalds@cs.helsinki.fi> 133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License. 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * History: 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 93/05/26 - Creation from e2fsck 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 94/02/27 - Made a separate bad blocks checker 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 99/06/30...99/07/26 - Added non-destructive write-testing, 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * configurable blocks-at-once parameter, 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * loading of badblocks list to avoid testing 273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * blocks known to be bad, multiple passes to 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * make sure that no new blocks are added to the 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * list. (Work done by David Beattie) 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _GNU_SOURCE /* for O_DIRECT */ 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifndef O_LARGEFILE 353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define O_LARGEFILE 0 363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h> 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETOPT_H 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <getopt.h> 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern char *optarg; 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int optind; 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <signal.h> 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h> 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <setjmp.h> 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <time.h> 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <limits.h> 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <sys/time.h> 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/ioctl.h> 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h> 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "et/com_err.h" 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs/ext2_io.h" 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs/ext2_fs.h" 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs/ext2fs.h" 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "nls-enable.h" 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectconst char * program_name = "badblocks"; 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectconst char * done_string = N_("done \n"); 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int v_flag = 0; /* verbose */ 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int w_flag = 0; /* do r/w test: 0=no, 1=yes, 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 2=non-destructive */ 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int s_flag = 0; /* show progress of test */ 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int force = 0; /* force check of mounted device */ 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int t_flag = 0; /* number of test patterns */ 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int t_max = 0; /* allocated test patterns */ 753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int *t_patts = NULL; /* test patterns */ 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int current_O_DIRECT = 0; /* Current status of O_DIRECT flag */ 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int exclusive_ok = 0; 783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int max_bb = 0; /* Abort test if more than this number of bad blocks has been encountered */ 793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int d_flag = 0; /* delay factor between reads */ 803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic struct timeval time_start; 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define T_INC 32 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtunsigned int sys_page_size = 4096; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void usage(void) 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, _( 893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt"Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n" 903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt" [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks]\n" 913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt" [-p num_passes] [-t test_pattern [-t test_pattern [...]]]\n" 923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt" device [last_block [first_block]]\n"), 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project program_name); 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void exclusive_usage(void) 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, 1003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt _("%s: The -n and -w options are mutually exclusive.\n\n"), 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project program_name); 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic blk_t currently_testing = 0; 1063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic blk_t num_blocks = 0; 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic ext2_badblocks_list bb_list = NULL; 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic FILE *out; 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic blk_t next_bad = 0; 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic ext2_badblocks_iterate bb_iter = NULL; 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void *allocate_buffer(size_t size) 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *ret = 0; 1153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_POSIX_MEMALIGN 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (posix_memalign(&ret, sys_page_size, size) < 0) 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = 0; 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MEMALIGN 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = memalign(sys_page_size, size); 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_VALLOC 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = valloc(size); 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_VALLOC */ 1263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif /* HAVE_MEMALIGN */ 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_POSIX_MEMALIGN */ 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ret) 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = malloc(size); 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret; 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This routine reports a new bad block. If the bad block has already 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * been seen before, then it returns 0; otherwise it returns 1. 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int bb_output (blk_t bad) 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t errcode; 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_badblocks_list_test(bb_list, bad)) 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(out, "%lu\n", (unsigned long) bad); 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fflush(out); 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode = ext2fs_badblocks_list_add (bb_list, bad); 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode) { 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errcode, "adding to in-memory bad block list"); 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* kludge: 1563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt increment the iteration through the bb_list if 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project an element was just added before the current iteration 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project position. This should not cause next_bad to change. */ 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bb_iter && bad < next_bad) 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate (bb_iter, &next_bad); 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic char *time_diff_format(struct timeval *tv1, 1653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct timeval *tv2, char *buf) 1663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 1673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt time_t diff = (tv1->tv_sec - tv2->tv_sec); 1683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int hr,min,sec; 1693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sec = diff % 60; 1713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt diff /= 60; 1723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt min = diff % 60; 1733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt hr = diff / 60; 1743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (hr) 1763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sprintf(buf, "%d:%02d:%02d", hr, min, sec); 1773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 1783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sprintf(buf, "%d:%02d", min, sec); 1793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return buf; 1803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic float calc_percent(unsigned long current, unsigned long total) { 1833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt float percent = 0.0; 1843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (total <= 0) 1853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return percent; 1863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (current >= total) { 1873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt percent = 100.0; 1883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 1893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt percent=(100.0*(float)current/(float)total); 1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 1913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return percent; 1923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void print_status(void) 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 1963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct timeval time_end; 1973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char diff_buf[32], line_buf[128]; 1983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int len; 1993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gettimeofday(&time_end, 0); 2013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt len = snprintf(line_buf, sizeof(line_buf), 2023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt _("%6.2f%% done, %s elapsed"), 2033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt calc_percent((unsigned long) currently_testing, 2043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) num_blocks), 2053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt time_diff_format(&time_end, &time_start, diff_buf)); 2063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(line_buf, stderr); 2073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(line_buf, '\b', len); 2083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt line_buf[len] = 0; 2093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(line_buf, stderr); 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fflush (stderr); 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void alarm_intr(int alnum EXT2FS_ATTR((unused))) 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGALRM, alarm_intr); 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm(1); 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!num_blocks) 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project print_status(); 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void *terminate_addr = NULL; 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void terminate_intr(int signo EXT2FS_ATTR((unused))) 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 2263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fflush(out); 2273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, "\n\nInterrupted at block %llu\n", 2283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long long) currently_testing); 2293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fflush(stderr); 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (terminate_addr) 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project longjmp(terminate_addr,1); 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void capture_terminate(jmp_buf term_addr) 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project terminate_addr = term_addr; 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGHUP, terminate_intr); 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGINT, terminate_intr); 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGPIPE, terminate_intr); 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGTERM, terminate_intr); 24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGUSR1, terminate_intr); 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGUSR2, terminate_intr); 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void uncapture_terminate(void) 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project terminate_addr = NULL; 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGHUP, SIG_DFL); 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGINT, SIG_DFL); 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGPIPE, SIG_DFL); 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGTERM, SIG_DFL); 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGUSR1, SIG_DFL); 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGUSR2, SIG_DFL); 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void set_o_direct(int dev, unsigned char *buffer, size_t size, 2583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t current_block) 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef O_DIRECT 26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int new_flag = O_DIRECT; 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flag; 2633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((((unsigned long) buffer & (sys_page_size - 1)) != 0) || 26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((size & (sys_page_size - 1)) != 0) || 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((current_block & ((sys_page_size >> 9)-1)) != 0)) 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project new_flag = 0; 26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (new_flag != current_O_DIRECT) { 27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* printf("%s O_DIRECT\n", new_flag ? "Setting" : "Clearing"); */ 27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flag = fcntl(dev, F_GETFL); 27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (flag > 0) { 27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flag = (flag & ~O_DIRECT) | new_flag; 27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fcntl(dev, F_SETFL, flag); 27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project current_O_DIRECT = new_flag; 27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void pattern_fill(unsigned char *buffer, unsigned int pattern, 28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t n) 28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int i, nb; 28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char bpattern[sizeof(pattern)], *ptr; 2873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (pattern == (unsigned int) ~0) { 28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (ptr = buffer; ptr < buffer + n; ptr++) { 29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (*ptr) = random() % (1 << (8 * sizeof(char))); 29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag | v_flag) 29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Testing with random pattern: "), stderr); 29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bpattern[0] = 0; 29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0; i < sizeof(bpattern); i++) { 29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pattern == 0) 29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bpattern[i] = pattern & 0xFF; 30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern = pattern >> 8; 30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nb = i ? (i-1) : 0; 30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (ptr = buffer, i = nb; ptr < buffer + n; ptr++) { 30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *ptr = bpattern[i]; 30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (i == 0) 30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project i = nb; 30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project i--; 30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag | v_flag) { 31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Testing with pattern 0x"), stderr); 31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0; i <= nb; i++) 31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, "%02x", buffer[i]); 31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(": ", stderr); 31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Perform a read of a sequence of blocks; return the number of blocks 32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * successfully sequentially read. 32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int do_read (int dev, unsigned char * buffer, int try, int block_size, 3243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t current_block) 32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project long got; 3273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct timeval tv1, tv2; 3283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define NANOSEC (1000000000L) 3293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define MILISEC (1000L) 33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project set_o_direct(dev, buffer, try * block_size, current_block); 33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag > 1) 33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project print_status(); 33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Seek to the correct loc. */ 33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_llseek (dev, (ext2_loff_t) current_block * block_size, 33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project SEEK_SET) != (ext2_loff_t) current_block * block_size) 33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, _("during seek")); 34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Try the read */ 3423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (d_flag) 3433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gettimeofday(&tv1, NULL); 34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = read (dev, buffer, try * block_size); 3453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (d_flag) 3463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gettimeofday(&tv2, NULL); 34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got < 0) 3483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt got = 0; 34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got & 511) 35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, _("Weird value (%ld) in do_read\n"), got); 35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got /= block_size; 3523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (d_flag && got == try) { 3533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef HAVE_NANOSLEEP 3543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct timespec ts; 3553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_sec = tv2.tv_sec - tv1.tv_sec; 3563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_nsec = (tv2.tv_usec - tv1.tv_usec) * MILISEC; 3573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ts.tv_nsec < 0) { 3583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_nsec += NANOSEC; 3593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_sec -= 1; 3603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* increase/decrease the sleep time based on d_flag value */ 3623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_sec = ts.tv_sec * d_flag / 100; 3633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_nsec = ts.tv_nsec * d_flag / 100; 3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ts.tv_nsec > NANOSEC) { 3653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_sec += ts.tv_nsec / NANOSEC; 3663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ts.tv_nsec %= NANOSEC; 3673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ts.tv_sec || ts.tv_nsec) 3693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt nanosleep(&ts, NULL); 3703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#else 3713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef HAVE_USLEEP 3723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct timeval tv; 3733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tv.tv_sec = tv2.tv_sec - tv1.tv_sec; 3743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tv.tv_usec = tv2.tv_usec - tv1.tv_usec; 3753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tv.tv_sec = tv.tv_sec * d_flag / 100; 3763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tv.tv_usec = tv.tv_usec * d_flag / 100; 3773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (tv.tv_usec > 1000000) { 3783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tv.tv_sec += tv.tv_usec / 1000000; 3793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tv.tv_usec %= 1000000; 3803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (tv.tv_sec) 3823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sleep(tv.tv_sec); 3833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (tv.tv_usec) 3843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt usleep(tv.tv_usec); 3853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 3863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 3873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return got; 38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Perform a write of a sequence of blocks; return the number of blocks 39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * successfully sequentially written. 39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int do_write(int dev, unsigned char * buffer, int try, int block_size, 3963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned long current_block) 39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project long got; 39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project set_o_direct(dev, buffer, try * block_size, current_block); 40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag > 1) 40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project print_status(); 40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Seek to the correct loc. */ 40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_llseek (dev, (ext2_loff_t) current_block * block_size, 40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project SEEK_SET) != (ext2_loff_t) current_block * block_size) 40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, _("during seek")); 40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Try the write */ 41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = write (dev, buffer, try * block_size); 41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got < 0) 4133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt got = 0; 41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got & 511) 41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, "Weird value (%ld) in do_write\n", got); 41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got /= block_size; 41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return got; 41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int host_dev; 42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void flush_bufs(void) 42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_sync_device(host_dev, 1); 42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, retval, _("during ext2fs_sync_device")); 42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int test_ro (int dev, blk_t last_block, 4323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int block_size, blk_t first_block, 4333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int blocks_at_once) 43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char * blkbuf; 43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int try; 4373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int got; 43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int bb_count = 0; 43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t errcode; 44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* set up abend handler */ 4423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt capture_terminate(NULL); 4433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode = ext2fs_badblocks_list_iterate_begin(bb_list,&bb_iter); 44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode) { 44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errcode, 44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while beginning bad block list iteration")); 44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate (bb_iter, &next_bad); 4523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } while (next_bad && next_bad < first_block); 45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag) { 45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blkbuf = allocate_buffer((blocks_at_once + 1) * block_size); 45619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blkbuf = allocate_buffer(blocks_at_once * block_size); 45819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 45919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!blkbuf) 46019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 46119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, ENOMEM, _("while allocating buffers")); 46219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 46319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 46419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag) { 4653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf (stderr, _("Checking blocks %lu to %lu\n"), 4663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) first_block, 4673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) last_block - 1); 46819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 46919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag) { 47019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Checking for bad blocks in read-only mode\n"), stderr); 47119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern_fill(blkbuf + blocks_at_once * block_size, 47219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t_patts[0], block_size); 47319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 47419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 47519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once; 4763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt currently_testing = first_block; 47719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = last_block - 1; 47819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!t_flag && (s_flag || v_flag)) { 47919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Checking for bad blocks (read-only test): "), stderr); 48019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag <= 1) 48119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm_intr(SIGALRM); 48219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 48319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (currently_testing < last_block) 48419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 4853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (max_bb && bb_count >= max_bb) { 4863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (s_flag || v_flag) { 4873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(_("Too many bad blocks, aborting test\n"), stderr); 4883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 4893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 4903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 49119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (next_bad) { 49219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (currently_testing == next_bad) { 49319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* fprintf (out, "%lu\n", nextbad); */ 49419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate (bb_iter, &next_bad); 49519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing++; 49619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 49719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 49819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (currently_testing + try > next_bad) 49919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = next_bad - currently_testing; 50019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 50119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (currently_testing + try > last_block) 50219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = last_block - currently_testing; 50319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = do_read (dev, blkbuf, try, block_size, currently_testing); 50419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag) { 50519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* test the comparison between all the 50619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blocks successfully read */ 50719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i; 50819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0; i < got; ++i) 50919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (memcmp (blkbuf+i*block_size, 51019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blkbuf+blocks_at_once*block_size, 51119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_size)) 51219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing + i); 51319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 51419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing += got; 51519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got == try) { 51619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once; 51719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* recover page-aligned offset for O_DIRECT */ 5183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ( (blocks_at_once >= sys_page_size >> 9) 51919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project && (currently_testing % (sys_page_size >> 9)!= 0)) 52019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try -= (sys_page_size >> 9) 5213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt - (currently_testing 52219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project % (sys_page_size >> 9)); 52319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 52419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 52519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 52619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = 1; 52719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got == 0) { 52819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing++); 52919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 53019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 53119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = 0; 53219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm(0); 53319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag || v_flag) 53419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_(done_string), stderr); 53519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 53619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fflush (stderr); 53719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free (blkbuf); 53819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 53919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate_end(bb_iter); 54019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt uncapture_terminate(); 5423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 54319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return bb_count; 54419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 54519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int test_rw (int dev, blk_t last_block, 5473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int block_size, blk_t first_block, 5483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int blocks_at_once) 54919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 55019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char *buffer, *read_buffer; 5513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const unsigned int patterns[] = {0xaa, 0x55, 0xff, 0x00}; 5523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const unsigned int *pattern; 55319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i, try, got, nr_pattern, pat_idx; 55419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int bb_count = 0; 55519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* set up abend handler */ 5573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt capture_terminate(NULL); 5583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 55919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buffer = allocate_buffer(2 * blocks_at_once * block_size); 56019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project read_buffer = buffer + blocks_at_once * block_size; 5613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 56219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!buffer) { 56319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, ENOMEM, _("while allocating buffers")); 56419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 56519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 56619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 56719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 56819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 56919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag) { 5703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(_("Checking for bad blocks in read-write mode\n"), 57119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project stderr); 57219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, _("From block %lu to %lu\n"), 5733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) first_block, 5743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) last_block - 1); 57519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 57619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag) { 57719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern = t_patts; 57819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nr_pattern = t_flag; 57919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 58019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern = patterns; 58119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nr_pattern = sizeof(patterns) / sizeof(patterns[0]); 58219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 58319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (pat_idx = 0; pat_idx < nr_pattern; pat_idx++) { 58419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern_fill(buffer, pattern[pat_idx], 58519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blocks_at_once * block_size); 58619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = last_block - 1; 5873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt currently_testing = first_block; 58819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag && v_flag <= 1) 58919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm_intr(SIGALRM); 59019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 59119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once; 59219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (currently_testing < last_block) { 5933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (max_bb && bb_count >= max_bb) { 5943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (s_flag || v_flag) { 5953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(_("Too many bad blocks, aborting test\n"), stderr); 5963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 5973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 5983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 59919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (currently_testing + try > last_block) 60019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = last_block - currently_testing; 60119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = do_write(dev, buffer, try, block_size, 60219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing); 60319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag > 1) 60419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project print_status(); 60519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 60619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing += got; 60719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got == try) { 60819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once; 60919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* recover page-aligned offset for O_DIRECT */ 6103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ( (blocks_at_once >= sys_page_size >> 9) 6113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt && (currently_testing % 61219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (sys_page_size >> 9)!= 0)) 61319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try -= (sys_page_size >> 9) 6143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt - (currently_testing 61519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project % (sys_page_size >> 9)); 61619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 61719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 61819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = 1; 61919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got == 0) { 62019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing++); 62119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 62219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 62419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = 0; 62519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm (0); 62619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag | v_flag) 62719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_(done_string), stderr); 62819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 62919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag | v_flag) 63019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Reading and comparing: "), stderr); 63119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = last_block; 6323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt currently_testing = first_block; 63319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag && v_flag <= 1) 63419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm_intr(SIGALRM); 63519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 63619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once; 63719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (currently_testing < last_block) { 6383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (max_bb && bb_count >= max_bb) { 6393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (s_flag || v_flag) { 6403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(_("Too many bad blocks, aborting test\n"), stderr); 6413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 6433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 64419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (currently_testing + try > last_block) 64519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = last_block - currently_testing; 64619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = do_read (dev, read_buffer, try, block_size, 64719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing); 64819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got == 0) { 64919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing++); 65019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 65119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 65219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < got; i++) { 65319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (memcmp(read_buffer + i * block_size, 65419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buffer + i * block_size, 65519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_size)) 65619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing+i); 65719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 65819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing += got; 65919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* recover page-aligned offset for O_DIRECT */ 6603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ( (blocks_at_once >= sys_page_size >> 9) 66119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project && (currently_testing % (sys_page_size >> 9)!= 0)) 66219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once - (sys_page_size >> 9) 6633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt - (currently_testing 66419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project % (sys_page_size >> 9)); 66519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 66619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = blocks_at_once; 66719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag > 1) 66819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project print_status(); 66919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 67119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = 0; 67219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm (0); 67319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag | v_flag) 67419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_(done_string), stderr); 67519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 67619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 67719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project uncapture_terminate(); 67819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(buffer); 67919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return bb_count; 68019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 68119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 68219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct saved_blk_record { 68319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t block; 68419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int num; 68519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 68619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int test_nd (int dev, blk_t last_block, 6883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int block_size, blk_t first_block, 6893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int blocks_at_once) 69019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 69119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char *blkbuf, *save_ptr, *test_ptr, *read_ptr; 69219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char *test_base, *save_base, *read_base; 69319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int try, i; 6943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const unsigned int patterns[] = { ~0 }; 6953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const unsigned int *pattern; 69619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int nr_pattern, pat_idx; 6973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int got, used2, written; 6983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t save_currently_testing; 69919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct saved_blk_record *test_record; 70019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* This is static to prevent being clobbered by the longjmp */ 70119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project static int num_saved; 70219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project jmp_buf terminate_env; 70319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t errcode; 70419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long buf_used; 70519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project static unsigned int bb_count; 70619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 70719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count = 0; 70819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode = ext2fs_badblocks_list_iterate_begin(bb_list,&bb_iter); 70919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode) { 71019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errcode, 71119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while beginning bad block list iteration")); 71219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 71319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 71419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 71519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate (bb_iter, &next_bad); 7163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } while (next_bad && next_bad < first_block); 71719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 71819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blkbuf = allocate_buffer(3 * blocks_at_once * block_size); 71919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_record = malloc (blocks_at_once*sizeof(struct saved_blk_record)); 72019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!blkbuf || !test_record) { 72119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, ENOMEM, _("while allocating buffers")); 72219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 72319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 72419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 72519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_base = blkbuf; 72619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_base = blkbuf + (blocks_at_once * block_size); 72719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project read_base = blkbuf + (2 * blocks_at_once * block_size); 7283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 72919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_saved = 0; 73019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 73119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 73219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag) { 73319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Checking for bad blocks in non-destructive read-write mode\n"), stderr); 7343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf (stderr, _("From block %lu to %lu\n"), 7353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) first_block, 7363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) last_block - 1); 73719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 73819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag || v_flag > 1) { 73919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("Checking for bad blocks (non-destructive read-write test)\n"), stderr); 74019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 74119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (setjmp(terminate_env)) { 74219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 74319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Abnormal termination by a signal is handled here. 74419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 74519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project signal (SIGALRM, SIG_IGN); 74619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("\nInterrupt caught, cleaning up\n"), stderr); 74719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 74819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr = save_base; 74919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < num_saved; i++) { 75019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_write(dev, save_ptr, test_record[i].num, 75119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_size, test_record[i].block); 75219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr += test_record[i].num * block_size; 75319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 75419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fflush (out); 75519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 75619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 75819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* set up abend handler */ 75919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project capture_terminate(terminate_env); 76019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 76119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag) { 76219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern = t_patts; 76319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nr_pattern = t_flag; 76419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 76519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern = patterns; 76619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nr_pattern = sizeof(patterns) / sizeof(patterns[0]); 76719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 76819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (pat_idx = 0; pat_idx < nr_pattern; pat_idx++) { 76919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern_fill(test_base, pattern[pat_idx], 77019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blocks_at_once * block_size); 77119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 77219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf_used = 0; 77319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count = 0; 77419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr = save_base; 77519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_ptr = test_base; 7763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt currently_testing = first_block; 77719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = last_block - 1; 77819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag && v_flag <= 1) 77919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm_intr(SIGALRM); 78019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 78119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (currently_testing < last_block) { 7823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (max_bb && bb_count >= max_bb) { 7833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (s_flag || v_flag) { 7843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs(_("Too many bad blocks, aborting test\n"), stderr); 7853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 7863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 7873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 78819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = try = blocks_at_once - buf_used; 78919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (next_bad) { 79019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (currently_testing == next_bad) { 79119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* fprintf (out, "%lu\n", nextbad); */ 79219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate (bb_iter, &next_bad); 79319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing++; 79419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto check_for_more; 79519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 79619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (currently_testing + try > next_bad) 79719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = next_bad - currently_testing; 79819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 79919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (currently_testing + try > last_block) 80019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = last_block - currently_testing; 80119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = do_read (dev, save_ptr, try, block_size, 80219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing); 80319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got == 0) { 80419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* First block must have been bad. */ 80519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing++); 80619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto check_for_more; 80719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 80819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 80919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 81019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Note the fact that we've saved this much data 81119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * *before* we overwrite it with test data 81219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 81319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_record[num_saved].block = currently_testing; 81419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_record[num_saved].num = got; 81519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_saved++; 81619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 81719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Write the test data */ 81819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project written = do_write (dev, test_ptr, got, block_size, 81919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing); 82019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (written != got) 82119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, 82219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("during test data write, block %lu"), 8233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) currently_testing + 8243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt written); 82519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 82619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf_used += got; 82719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr += got * block_size; 82819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_ptr += got * block_size; 82919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing += got; 83019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got != try) 83119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing++); 83219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 83319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_for_more: 83419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 83519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If there's room for more blocks to be tested this 83619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * around, and we're not done yet testing the disk, go 83719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * back and get some more blocks. 83819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 83919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((buf_used != blocks_at_once) && 84019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (currently_testing < last_block)) 84119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 84219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 84319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 84419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_currently_testing = currently_testing; 84519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 84619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 84719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * for each contiguous block that we read into the 84819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * buffer (and wrote test data into afterwards), read 84919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * it back (looping if necessary, to get past newly 85019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * discovered unreadable blocks, of which there should 85119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * be none, but with a hard drive which is unreliable, 85219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * it has happened), and compare with the test data 85319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * that was written; output to the bad block list if 85419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * it doesn't match. 85519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 85619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project used2 = 0; 85719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr = save_base; 85819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_ptr = test_base; 85919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project read_ptr = read_base; 86019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = 0; 86119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 86219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (1) { 86319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (try == 0) { 86419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (used2 >= num_saved) 86519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 86619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing = test_record[used2].block; 86719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try = test_record[used2].num; 86819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project used2++; 86919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 87119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got = do_read (dev, read_ptr, try, 87219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_size, currently_testing); 87319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 87419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* test the comparison between all the 87519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blocks successfully read */ 87619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0; i < got; ++i) 87719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (memcmp (test_ptr+i*block_size, 87819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project read_ptr+i*block_size, block_size)) 87919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing + i); 88019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (got < try) { 88119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count += bb_output(currently_testing + got); 88219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project got++; 88319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 88519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* write back original data */ 88619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do_write (dev, save_ptr, got, 88719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_size, currently_testing); 88819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr += got * block_size; 88919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 89019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing += got; 89119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_ptr += got * block_size; 89219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project read_ptr += got * block_size; 89319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project try -= got; 89419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 89519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 89619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* empty the buffer so it can be reused */ 89719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_saved = 0; 89819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf_used = 0; 89919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project save_ptr = save_base; 90019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_ptr = test_base; 90119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project currently_testing = save_currently_testing; 90219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 90319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project num_blocks = 0; 90419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project alarm(0); 90519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (s_flag || v_flag > 1) 90619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_(done_string), stderr); 90719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 90819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flush_bufs(); 90919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 91019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project uncapture_terminate(); 91119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fflush(stderr); 91219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(blkbuf); 91319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(test_record); 91419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 91519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_badblocks_list_iterate_end(bb_iter); 91619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 91719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return bb_count; 91819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 91919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 92019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void check_mount(char *device_name) 92119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 92219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 92319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int mount_flags; 92419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 92519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_check_if_mounted(device_name, &mount_flags); 92619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 92719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("ext2fs_check_if_mount", retval, 92819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while determining whether %s is mounted."), 92919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project device_name); 93019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 93119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 93219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (mount_flags & EXT2_MF_MOUNTED) { 93319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, _("%s is mounted; "), device_name); 93419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (force) { 93519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("badblocks forced anyway. " 93619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "Hope /etc/mtab is incorrect.\n"), stderr); 93719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 93819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 93919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project abort_badblocks: 94019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("it's not safe to run badblocks!\n"), stderr); 94119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 94219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 94319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 94419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((mount_flags & EXT2_MF_BUSY) && !exclusive_ok) { 94519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, _("%s is apparently in use by the system; "), 94619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project device_name); 94719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (force) 94819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fputs(_("badblocks forced anyway.\n"), stderr); 94919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 95019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto abort_badblocks; 95119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 95219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 95319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 95419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 9563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * This function will convert a string to an unsigned long, printing 9573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * an error message if it fails, and returning success or failure in err. 9583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 9593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned int parse_uint(const char *str, const char *descr) 9603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 9613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *tmp; 9623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned long ret; 9633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errno = 0; 9653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ret = strtoul(str, &tmp, 0); 9663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (*tmp || errno || (ret > UINT_MAX) || 9673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (ret == ULONG_MAX && errno == ERANGE)) { 9683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err (program_name, 0, _("invalid %s - %s"), descr, str); 9693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt exit (1); 9703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return ret; 9723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 97319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 97419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main (int argc, char ** argv) 97519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 97619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int c; 97719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char * device_name; 97819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char * host_device_name = NULL; 97919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char * input_file = NULL; 98019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char * output_file = NULL; 98119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project FILE * in = NULL; 98219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int block_size = 1024; 9833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int blocks_at_once = 64; 9843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t last_block, first_block; 98519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int num_passes = 0; 98619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int passes_clean = 0; 98719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int dev; 98819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t errcode; 9893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int pattern; 9903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int (*test_func)(int, blk_t, 9913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int, blk_t, 9923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int); 9933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int open_flag; 99419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project long sysval; 99519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 99619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project setbuf(stdout, NULL); 99719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project setbuf(stderr, NULL); 99819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_NLS 99919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project setlocale(LC_MESSAGES, ""); 100019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project setlocale(LC_CTYPE, ""); 100119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 100219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project textdomain(NLS_CAT_NAME); 100319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 100419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project srandom((unsigned int)time(NULL)); /* simple randomness is enough */ 100519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_func = test_ro; 100619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 100719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Determine the system page size if possible */ 100819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SYSCONF 100919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE)) 101019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _SC_PAGESIZE _SC_PAGE_SIZE 101119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 101219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef _SC_PAGESIZE 101319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sysval = sysconf(_SC_PAGESIZE); 101419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sysval > 0) 101519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sys_page_size = sysval; 101619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* _SC_PAGESIZE */ 101719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* HAVE_SYSCONF */ 10183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 101919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (argc && *argv) 102019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project program_name = *argv; 10213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while ((c = getopt (argc, argv, "b:d:e:fi:o:svwnc:p:h:t:X")) != EOF) { 102219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project switch (c) { 102319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'b': 10243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt block_size = parse_uint(optarg, "block size"); 102519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 102619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'f': 102719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project force++; 102819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 102919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'i': 103019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project input_file = optarg; 103119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 103219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'o': 103319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project output_file = optarg; 103419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 103519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 's': 103619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project s_flag = 1; 103719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 103819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'v': 103919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project v_flag++; 104019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 104119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'w': 104219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (w_flag) 104319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exclusive_usage(); 104419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_func = test_rw; 104519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project w_flag = 1; 104619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 104719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'n': 104819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (w_flag) 104919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exclusive_usage(); 105019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project test_func = test_nd; 105119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project w_flag = 2; 105219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 105319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'c': 10543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blocks_at_once = parse_uint(optarg, "blocks at once"); 10553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 10563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case 'e': 10573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt max_bb = parse_uint(optarg, "max bad block count"); 10583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 10593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case 'd': 10603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt d_flag = parse_uint(optarg, "read delay factor"); 106119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 106219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'p': 10633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt num_passes = parse_uint(optarg, 10643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "number of clean passes"); 106519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 106619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'h': 106719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project host_device_name = optarg; 106819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 106919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 't': 107019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag + 1 > t_max) { 10713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int *t_patts_new; 107219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt t_patts_new = realloc(t_patts, sizeof(int) * 10743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (t_max + T_INC)); 107519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!t_patts_new) { 107619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, ENOMEM, 107719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("can't allocate memory for " 107819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "test_pattern - %s"), 107919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project optarg); 108019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 108119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 108219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t_patts = t_patts_new; 108319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t_max += T_INC; 108419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 108519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!strcmp(optarg, "r") || !strcmp(optarg,"random")) { 108619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t_patts[t_flag++] = ~0; 108719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 10883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pattern = parse_uint(optarg, "test pattern"); 10893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (pattern == (unsigned int) ~0) 109019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pattern = 0xffff; 109119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project t_patts[t_flag++] = pattern; 109219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 109319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 109419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 'X': 109519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exclusive_ok++; 109619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 109719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project default: 109819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project usage(); 109919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 110019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 110119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!w_flag) { 110219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (t_flag > 1) { 110319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, 0, 110419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("Maximum of one test_pattern may be specified " 110519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "in read-only mode")); 110619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 110719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (t_patts && (t_patts[0] == (unsigned int) ~0)) { 110919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, 0, 111019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("Random test_pattern is not allowed " 111119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "in read-only mode")); 111219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 111319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 111419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 111519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (optind > argc - 1) 111619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project usage(); 111719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project device_name = argv[optind++]; 111819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (optind > argc - 1) { 111919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode = ext2fs_get_device_size(device_name, 112019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_size, 112119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &last_block); 112219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode == EXT2_ET_UNIMPLEMENTED) { 112319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, 0, 112419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("Couldn't determine device size; you " 112519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "must specify\nthe size manually\n")); 112619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 112719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 112819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode) { 112919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(program_name, errcode, 113019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while trying to determine device size")); 113119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit(1); 113219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 113319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 113419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errno = 0; 11353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt last_block = parse_uint(argv[optind], _("last block")); 113619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project last_block++; 113719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project optind++; 113819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 113919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (optind <= argc-1) { 114019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errno = 0; 11413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_block = parse_uint(argv[optind], _("first block")); 11423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else first_block = 0; 11433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (first_block >= last_block) { 11443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err (program_name, 0, _("invalid starting block (%lu): must be less than %lu"), 11453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) first_block, (unsigned long) last_block); 114619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 114719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 114819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (w_flag) 114919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_mount(device_name); 11503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gettimeofday(&time_start, 0); 11523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt open_flag = O_LARGEFILE | (w_flag ? O_RDWR : O_RDONLY); 115319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dev = open (device_name, open_flag); 115419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dev == -1) { 115519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, _("while trying to open %s"), 115619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project device_name); 115719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 115819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 115919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (host_device_name) { 116019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project host_dev = open (host_device_name, open_flag); 116119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (host_dev == -1) { 116219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, 116319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while trying to open %s"), 116419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project host_device_name); 116519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 116619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 116719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 116819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project host_dev = dev; 116919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (input_file) { 117019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strcmp (input_file, "-") == 0) 117119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project in = stdin; 117219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 117319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project in = fopen (input_file, "r"); 117419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (in == NULL) 117519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 117619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, 117719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while trying to open %s"), 117819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project input_file); 117919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 118019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 118119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 118219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 118319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (output_file && strcmp (output_file, "-") != 0) 118419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 118519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project out = fopen (output_file, "w"); 118619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (out == NULL) 118719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 118819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errno, 118919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while trying to open %s"), 119019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project output_file); 119119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 119219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 119319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 119419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 119519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project out = stdout; 119619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 119719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode = ext2fs_badblocks_list_create(&bb_list,0); 119819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode) { 119919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errcode, 120019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while creating in-memory bad blocks list")); 120119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 120219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 120319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 120419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (in) { 120519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for(;;) { 120619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project switch(fscanf (in, "%u\n", &next_bad)) { 120719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case 0: 120819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, 0, "input file - bad format"); 120919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 121019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case EOF: 121119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 121219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project default: 121319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode = ext2fs_badblocks_list_add(bb_list,next_bad); 121419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (errcode) { 121519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err (program_name, errcode, _("while adding to in-memory bad block list")); 121619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project exit (1); 121719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 121819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 121919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 122019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 122119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 122219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 122319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (in != stdin) 122419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fclose (in); 122519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 122619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 122719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 122819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int bb_count; 122919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 123019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count = test_func(dev, last_block, block_size, 12313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_block, blocks_at_once); 123219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bb_count) 123319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project passes_clean = 0; 123419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 123519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ++passes_clean; 12363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 123719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (v_flag) 123819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fprintf(stderr, 12393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt _("Pass completed, %u bad blocks found.\n"), 124019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bb_count); 124119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 124219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } while (passes_clean < num_passes); 124319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 124419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project close (dev); 124519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (out != stdout) 124619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fclose (out); 12473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(t_patts); 124819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 124919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 125019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1251