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