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