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