ehandler.c revision d45b67c5f2a66597d8e2915052e180203a9193b8
1/* 2 * ehandler.c --- handle bad block errors which come up during the 3 * course of an e2fsck session. 4 * 5 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed 6 * under the terms of the GNU Public License. 7 */ 8 9#include "config.h" 10#include <stdlib.h> 11#include <unistd.h> 12#include <string.h> 13#include <ctype.h> 14#include <termios.h> 15 16#include "e2fsck.h" 17 18#include <sys/time.h> 19#include <sys/resource.h> 20 21static const char *operation; 22 23static errcode_t e2fsck_handle_read_error(io_channel channel, 24 unsigned long block, 25 int count, 26 void *data, 27 size_t size EXT2FS_ATTR((unused)), 28 int actual EXT2FS_ATTR((unused)), 29 errcode_t error) 30{ 31 int i; 32 char *p; 33 ext2_filsys fs = (ext2_filsys) channel->app_data; 34 e2fsck_t ctx; 35 36 ctx = (e2fsck_t) fs->priv_data; 37 if (ctx->flags & E2F_FLAG_EXITING) 38 return 0; 39 /* 40 * If more than one block was read, try reading each block 41 * separately. We could use the actual bytes read to figure 42 * out where to start, but we don't bother. 43 */ 44 if (count > 1) { 45 p = (char *) data; 46 for (i=0; i < count; i++, p += channel->block_size, block++) { 47 error = io_channel_read_blk64(channel, block, 48 1, p); 49 if (error) 50 return error; 51 } 52 return 0; 53 } 54 if (operation) 55 printf(_("Error reading block %lu (%s) while %s. "), block, 56 error_message(error), operation); 57 else 58 printf(_("Error reading block %lu (%s). "), block, 59 error_message(error)); 60 preenhalt(ctx); 61 if (ask(ctx, _("Ignore error"), 1)) { 62 if (ask(ctx, _("Force rewrite"), 1)) 63 io_channel_write_blk64(channel, block, count, data); 64 return 0; 65 } 66 67 return error; 68} 69 70static errcode_t e2fsck_handle_write_error(io_channel channel, 71 unsigned long block, 72 int count, 73 const void *data, 74 size_t size EXT2FS_ATTR((unused)), 75 int actual EXT2FS_ATTR((unused)), 76 errcode_t error) 77{ 78 int i; 79 const char *p; 80 ext2_filsys fs = (ext2_filsys) channel->app_data; 81 e2fsck_t ctx; 82 83 ctx = (e2fsck_t) fs->priv_data; 84 if (ctx->flags & E2F_FLAG_EXITING) 85 return 0; 86 87 /* 88 * If more than one block was written, try writing each block 89 * separately. We could use the actual bytes read to figure 90 * out where to start, but we don't bother. 91 */ 92 if (count > 1) { 93 p = (const char *) data; 94 for (i=0; i < count; i++, p += channel->block_size, block++) { 95 error = io_channel_write_blk64(channel, block, 96 1, p); 97 if (error) 98 return error; 99 } 100 return 0; 101 } 102 103 if (operation) 104 printf(_("Error writing block %lu (%s) while %s. "), block, 105 error_message(error), operation); 106 else 107 printf(_("Error writing block %lu (%s). "), block, 108 error_message(error)); 109 preenhalt(ctx); 110 if (ask(ctx, _("Ignore error"), 1)) 111 return 0; 112 113 return error; 114} 115 116const char *ehandler_operation(const char *op) 117{ 118 const char *ret = operation; 119 120 operation = op; 121 return ret; 122} 123 124void ehandler_init(io_channel channel) 125{ 126 channel->read_error = e2fsck_handle_read_error; 127 channel->write_error = e2fsck_handle_write_error; 128} 129