119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ehandler.c --- handle bad block errors which come up during the 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * course of an e2fsck session. 43984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * under the terms of the GNU Public License. 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h> 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h> 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <termios.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2fsck.h" 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/time.h> 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/resource.h> 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char *operation; 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t e2fsck_handle_read_error(io_channel channel, 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long block, 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *data, 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t size EXT2FS_ATTR((unused)), 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int actual EXT2FS_ATTR((unused)), 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t error) 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i; 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *p; 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = (ext2_filsys) channel->app_data; 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx; 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx = (e2fsck_t) fs->priv_data; 363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ctx->flags & E2F_FLAG_EXITING) 373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If more than one block was read, try reading each block 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * separately. We could use the actual bytes read to figure 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * out where to start, but we don't bother. 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (count > 1) { 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project p = (char *) data; 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < count; i++, p += channel->block_size, block++) { 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project error = io_channel_read_blk(channel, block, 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1, p); 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (error) 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return error; 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (operation) 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf(_("Error reading block %lu (%s) while %s. "), block, 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project error_message(error), operation); 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf(_("Error reading block %lu (%s). "), block, 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project error_message(error)); 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project preenhalt(ctx); 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ask(ctx, _("Ignore error"), 1)) { 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ask(ctx, _("Force rewrite"), 1)) 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project io_channel_write_blk(channel, block, 1, data); 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return error; 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t e2fsck_handle_write_error(io_channel channel, 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long block, 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const void *data, 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t size EXT2FS_ATTR((unused)), 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int actual EXT2FS_ATTR((unused)), 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t error) 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i; 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const char *p; 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = (ext2_filsys) channel->app_data; 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx; 813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx = (e2fsck_t) fs->priv_data; 833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ctx->flags & E2F_FLAG_EXITING) 843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If more than one block was written, try writing each block 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * separately. We could use the actual bytes read to figure 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * out where to start, but we don't bother. 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (count > 1) { 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project p = (const char *) data; 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < count; i++, p += channel->block_size, block++) { 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project error = io_channel_write_blk(channel, block, 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1, p); 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (error) 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return error; 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 1013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (operation) 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf(_("Error writing block %lu (%s) while %s. "), block, 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project error_message(error), operation); 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf(_("Error writing block %lu (%s). "), block, 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project error_message(error)); 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project preenhalt(ctx); 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ask(ctx, _("Ignore error"), 1)) 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return error; 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectconst char *ehandler_operation(const char *op) 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const char *ret = operation; 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project operation = op; 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret; 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid ehandler_init(io_channel channel) 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project channel->read_error = e2fsck_handle_read_error; 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project channel->write_error = e2fsck_handle_write_error; 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 128