blob: 131a0abb8415c6c1ce8d01d6085c65c6038eacb2 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
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>
Theodore Ts'o3839e651997-04-26 13:21:57 +000014
15#include "e2fsck.h"
16
Theodore Ts'o50e1e101997-04-26 13:58:21 +000017#include <sys/time.h>
18#include <sys/resource.h>
19
Theodore Ts'o3839e651997-04-26 13:21:57 +000020static const char *operation;
21
22static errcode_t e2fsck_handle_read_error(io_channel channel,
23 unsigned long block,
24 int count,
25 void *data,
26 size_t size,
27 int actual,
28 errcode_t error)
29{
30 int i;
31 char *p;
32
33 /*
34 * If more than one block was read, try reading each block
35 * separately. We could use the actual bytes read to figure
36 * out where to start, but we don't bother.
37 */
38 if (count > 1) {
39 p = (char *) data;
40 for (i=0; i < count; i++, p += channel->block_size, block++) {
41 error = io_channel_read_blk(channel, block,
42 1, p);
43 if (error)
44 return error;
45 }
46 return 0;
47 }
48 if (operation)
Theodore Ts'of3db3561997-04-26 13:34:30 +000049 printf("Error reading block %lu (%s) while %s. ", block,
Theodore Ts'o3839e651997-04-26 13:21:57 +000050 error_message(error), operation);
51 else
Theodore Ts'of3db3561997-04-26 13:34:30 +000052 printf("Error reading block %lu (%s). ", block,
Theodore Ts'o3839e651997-04-26 13:21:57 +000053 error_message(error));
Theodore Ts'o50e1e101997-04-26 13:58:21 +000054 preenhalt(NULL);
Theodore Ts'o3839e651997-04-26 13:21:57 +000055 if (ask("Ignore error", 1))
56 return 0;
57
58 return error;
59}
60
61static errcode_t e2fsck_handle_write_error(io_channel channel,
62 unsigned long block,
63 int count,
64 const void *data,
65 size_t size,
66 int actual,
67 errcode_t error)
68{
69 int i;
70 const char *p;
71
72 /*
73 * If more than one block was written, try writing each block
74 * separately. We could use the actual bytes read to figure
75 * out where to start, but we don't bother.
76 */
77 if (count > 1) {
78 p = (const char *) data;
79 for (i=0; i < count; i++, p += channel->block_size, block++) {
80 error = io_channel_write_blk(channel, block,
81 1, p);
82 if (error)
83 return error;
84 }
85 return 0;
86 }
87
88 if (operation)
Theodore Ts'of3db3561997-04-26 13:34:30 +000089 printf("Error writing block %lu (%s) while %s. ", block,
Theodore Ts'o3839e651997-04-26 13:21:57 +000090 error_message(error), operation);
91 else
Theodore Ts'of3db3561997-04-26 13:34:30 +000092 printf("Error writing block %lu (%s). ", block,
Theodore Ts'o3839e651997-04-26 13:21:57 +000093 error_message(error));
Theodore Ts'o50e1e101997-04-26 13:58:21 +000094 preenhalt(NULL);
Theodore Ts'o3839e651997-04-26 13:21:57 +000095 if (ask("Ignore error", 1))
96 return 0;
97
98 return error;
99}
100
101const char *ehandler_operation(const char *op)
102{
103 const char *ret = operation;
104
105 operation = op;
106 return ret;
107}
108
109void ehandler_init(io_channel channel)
110{
111 channel->read_error = e2fsck_handle_read_error;
112 channel->write_error = e2fsck_handle_write_error;
113}