Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 1 | /* |
| 2 | * util.c --- miscellaneous utilities |
| 3 | * |
Theodore Ts'o | 21c84b7 | 1997-04-29 16:15:03 +0000 | [diff] [blame] | 4 | * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. |
| 5 | * |
| 6 | * %Begin-Header% |
| 7 | * This file may be redistributed under the terms of the GNU Public |
| 8 | * License. |
| 9 | * %End-Header% |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <stdlib.h> |
| 13 | #include <unistd.h> |
| 14 | #include <string.h> |
| 15 | #include <ctype.h> |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 16 | |
| 17 | #ifdef HAVE_CONIO_H |
| 18 | #undef HAVE_TERMIOS_H |
| 19 | #include <conio.h> |
Theodore Ts'o | e659704 | 1999-10-26 02:30:16 +0000 | [diff] [blame] | 20 | #define read_a_char() getch() |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 21 | #else |
| 22 | #ifdef HAVE_TERMIOS_H |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 23 | #include <termios.h> |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 24 | #endif |
Theodore Ts'o | e659704 | 1999-10-26 02:30:16 +0000 | [diff] [blame] | 25 | #include <stdio.h> |
Theodore Ts'o | c81c6ce | 1999-10-26 04:28:53 +0000 | [diff] [blame] | 26 | #define read_a_char() getchar() |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 27 | #endif |
| 28 | |
Theodore Ts'o | 4a9f593 | 1999-03-16 19:32:52 +0000 | [diff] [blame] | 29 | #ifdef HAVE_MALLOC_H |
| 30 | #include <malloc.h> |
| 31 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 32 | |
| 33 | #include "e2fsck.h" |
| 34 | |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 35 | #include <sys/time.h> |
| 36 | #include <sys/resource.h> |
| 37 | |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 38 | void fatal_error(e2fsck_t ctx, const char *msg) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 39 | { |
| 40 | if (msg) |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 41 | fprintf (stderr, "e2fsck: %s\n", msg); |
Theodore Ts'o | 58a7517 | 2001-01-12 20:59:19 +0000 | [diff] [blame] | 42 | if (ctx->fs && ctx->fs->io) { |
Theodore Ts'o | e39ac92 | 2001-05-05 06:47:24 +0000 | [diff] [blame] | 43 | if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL) |
Theodore Ts'o | 58a7517 | 2001-01-12 20:59:19 +0000 | [diff] [blame] | 44 | io_channel_flush(ctx->fs->io); |
| 45 | else |
| 46 | fprintf(stderr, "e2fsck: io manager magic bad!\n"); |
| 47 | } |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 48 | ctx->flags |= E2F_FLAG_ABORT; |
| 49 | if (ctx->flags & E2F_FLAG_SETJMP_OK) |
| 50 | longjmp(ctx->abort_loc, 1); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 51 | exit(FSCK_ERROR); |
| 52 | } |
| 53 | |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 54 | void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, |
| 55 | const char *description) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 56 | { |
| 57 | void *ret; |
| 58 | char buf[256]; |
| 59 | |
| 60 | #ifdef DEBUG_ALLOCATE_MEMORY |
| 61 | printf("Allocating %d bytes for %s...\n", size, description); |
| 62 | #endif |
| 63 | ret = malloc(size); |
| 64 | if (!ret) { |
Theodore Ts'o | 7f88b04 | 1997-04-26 14:48:50 +0000 | [diff] [blame] | 65 | sprintf(buf, "Can't allocate %s\n", description); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 66 | fatal_error(ctx, buf); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 67 | } |
| 68 | memset(ret, 0, size); |
| 69 | return ret; |
| 70 | } |
| 71 | |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 72 | int ask_yn(const char * string, int def) |
| 73 | { |
| 74 | int c; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 75 | const char *defstr; |
Theodore Ts'o | 53ef44c | 2001-01-06 05:55:58 +0000 | [diff] [blame] | 76 | const char *short_yes = _("yY"); |
| 77 | const char *short_no = _("nN"); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 78 | |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 79 | #ifdef HAVE_TERMIOS_H |
| 80 | struct termios termios, tmp; |
| 81 | |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 82 | tcgetattr (0, &termios); |
| 83 | tmp = termios; |
| 84 | tmp.c_lflag &= ~(ICANON | ECHO); |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 85 | tmp.c_cc[VMIN] = 1; |
| 86 | tmp.c_cc[VTIME] = 0; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 87 | tcsetattr (0, TCSANOW, &tmp); |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 88 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 89 | |
| 90 | if (def == 1) |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 91 | defstr = _("<y>"); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 92 | else if (def == 0) |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 93 | defstr = _("<n>"); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 94 | else |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 95 | defstr = _(" (y/n)"); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 96 | printf("%s%s? ", string, defstr); |
| 97 | while (1) { |
| 98 | fflush (stdout); |
Theodore Ts'o | e659704 | 1999-10-26 02:30:16 +0000 | [diff] [blame] | 99 | if ((c = read_a_char()) == EOF) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 100 | break; |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 101 | if (strchr(short_yes, (char) c)) { |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 102 | def = 1; |
| 103 | break; |
| 104 | } |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 105 | else if (strchr(short_no, (char) c)) { |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 106 | def = 0; |
| 107 | break; |
| 108 | } |
| 109 | else if ((c == ' ' || c == '\n') && (def != -1)) |
| 110 | break; |
| 111 | } |
| 112 | if (def) |
| 113 | printf ("yes\n\n"); |
| 114 | else |
| 115 | printf ("no\n\n"); |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 116 | #ifdef HAVE_TERMIOS_H |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 117 | tcsetattr (0, TCSANOW, &termios); |
Theodore Ts'o | 9ecd8be | 1999-10-20 18:24:31 +0000 | [diff] [blame] | 118 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 119 | return def; |
| 120 | } |
| 121 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 122 | int ask (e2fsck_t ctx, const char * string, int def) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 123 | { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 124 | if (ctx->options & E2F_OPT_NO) { |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 125 | printf (_("%s? no\n\n"), string); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 126 | return 0; |
| 127 | } |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 128 | if (ctx->options & E2F_OPT_YES) { |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 129 | printf (_("%s? yes\n\n"), string); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 130 | return 1; |
| 131 | } |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 132 | if (ctx->options & E2F_OPT_PREEN) { |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 133 | printf ("%s? %s\n\n", string, def ? _("yes") : _("no")); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 134 | return def; |
| 135 | } |
| 136 | return ask_yn(string, def); |
| 137 | } |
| 138 | |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 139 | void e2fsck_read_bitmaps(e2fsck_t ctx) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 140 | { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 141 | ext2_filsys fs = ctx->fs; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 142 | errcode_t retval; |
| 143 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 144 | if (ctx->invalid_bitmaps) { |
| 145 | com_err(ctx->program_name, 0, |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 146 | _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"), |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 147 | ctx->device_name); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 148 | fatal_error(ctx, 0); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 149 | } |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 150 | |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 151 | ehandler_operation(_("reading inode and block bitmaps")); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 152 | retval = ext2fs_read_bitmaps(fs); |
| 153 | ehandler_operation(0); |
| 154 | if (retval) { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 155 | com_err(ctx->program_name, retval, |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 156 | _("while retrying to read bitmaps for %s"), |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 157 | ctx->device_name); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 158 | fatal_error(ctx, 0); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 159 | } |
| 160 | } |
| 161 | |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 162 | void e2fsck_write_bitmaps(e2fsck_t ctx) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 163 | { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 164 | ext2_filsys fs = ctx->fs; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 165 | errcode_t retval; |
| 166 | |
| 167 | if (ext2fs_test_bb_dirty(fs)) { |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 168 | ehandler_operation(_("writing block bitmaps")); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 169 | retval = ext2fs_write_block_bitmap(fs); |
| 170 | ehandler_operation(0); |
| 171 | if (retval) { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 172 | com_err(ctx->program_name, retval, |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 173 | _("while retrying to write block bitmaps for %s"), |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 174 | ctx->device_name); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 175 | fatal_error(ctx, 0); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 176 | } |
| 177 | } |
| 178 | |
| 179 | if (ext2fs_test_ib_dirty(fs)) { |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 180 | ehandler_operation(_("writing inode bitmaps")); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 181 | retval = ext2fs_write_inode_bitmap(fs); |
| 182 | ehandler_operation(0); |
| 183 | if (retval) { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 184 | com_err(ctx->program_name, retval, |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 185 | _("while retrying to write inode bitmaps for %s"), |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 186 | ctx->device_name); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 187 | fatal_error(ctx, 0); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 188 | } |
| 189 | } |
| 190 | } |
| 191 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 192 | void preenhalt(e2fsck_t ctx) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 193 | { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 194 | ext2_filsys fs = ctx->fs; |
| 195 | |
| 196 | if (!(ctx->options & E2F_OPT_PREEN)) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 197 | return; |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 198 | fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; " |
| 199 | "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"), |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 200 | ctx->device_name); |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 201 | if (fs != NULL) { |
| 202 | fs->super->s_state |= EXT2_ERROR_FS; |
| 203 | ext2fs_mark_super_dirty(fs); |
| 204 | ext2fs_close(fs); |
| 205 | } |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 206 | exit(FSCK_UNCORRECTED); |
| 207 | } |
| 208 | |
Theodore Ts'o | 8bf191e | 1997-10-20 01:38:32 +0000 | [diff] [blame] | 209 | #ifdef RESOURCE_TRACK |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 210 | void init_resource_track(struct resource_track *track) |
| 211 | { |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 212 | #ifdef HAVE_GETRUSAGE |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 213 | struct rusage r; |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 214 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 215 | |
| 216 | track->brk_start = sbrk(0); |
| 217 | gettimeofday(&track->time_start, 0); |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 218 | #ifdef HAVE_GETRUSAGE |
Theodore Ts'o | 53ef44c | 2001-01-06 05:55:58 +0000 | [diff] [blame] | 219 | #ifdef sun |
| 220 | memset(&r, 0, sizeof(struct rusage)); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 221 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 222 | getrusage(RUSAGE_SELF, &r); |
| 223 | track->user_start = r.ru_utime; |
| 224 | track->system_start = r.ru_stime; |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 225 | #else |
| 226 | track->user_start.tv_sec = track->user_start.tv_usec = 0; |
| 227 | track->system_start.tv_sec = track->system_start.tv_usec = 0; |
| 228 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 229 | } |
| 230 | |
Theodore Ts'o | 21c84b7 | 1997-04-29 16:15:03 +0000 | [diff] [blame] | 231 | #ifdef __GNUC__ |
| 232 | #define _INLINE_ __inline__ |
| 233 | #else |
| 234 | #define _INLINE_ |
| 235 | #endif |
| 236 | |
| 237 | static _INLINE_ float timeval_subtract(struct timeval *tv1, |
| 238 | struct timeval *tv2) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 239 | { |
| 240 | return ((tv1->tv_sec - tv2->tv_sec) + |
| 241 | ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000); |
| 242 | } |
| 243 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 244 | void print_resource_track(const char *desc, struct resource_track *track) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 245 | { |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 246 | #ifdef HAVE_GETRUSAGE |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 247 | struct rusage r; |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 248 | #endif |
Theodore Ts'o | 4a9f593 | 1999-03-16 19:32:52 +0000 | [diff] [blame] | 249 | #ifdef HAVE_MALLINFO |
| 250 | struct mallinfo malloc_info; |
| 251 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 252 | struct timeval time_end; |
| 253 | |
| 254 | gettimeofday(&time_end, 0); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 255 | |
| 256 | if (desc) |
Theodore Ts'o | 7fdfabd | 1997-11-24 11:51:17 +0000 | [diff] [blame] | 257 | printf("%s: ", desc); |
Theodore Ts'o | 4a9f593 | 1999-03-16 19:32:52 +0000 | [diff] [blame] | 258 | |
| 259 | #ifdef HAVE_MALLINFO |
Theodore Ts'o | 80c5d7e | 2000-02-08 23:19:32 +0000 | [diff] [blame] | 260 | #define kbytes(x) (((x) + 1023) / 1024) |
| 261 | |
Theodore Ts'o | 4a9f593 | 1999-03-16 19:32:52 +0000 | [diff] [blame] | 262 | malloc_info = mallinfo(); |
Theodore Ts'o | 80c5d7e | 2000-02-08 23:19:32 +0000 | [diff] [blame] | 263 | printf(_("Memory used: %dk/%dk (%dk/%dk), "), |
| 264 | kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd), |
| 265 | kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks)); |
Theodore Ts'o | 4a9f593 | 1999-03-16 19:32:52 +0000 | [diff] [blame] | 266 | #else |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 267 | printf(_("Memory used: %d, "), |
Theodore Ts'o | 4a9f593 | 1999-03-16 19:32:52 +0000 | [diff] [blame] | 268 | (int) (((char *) sbrk(0)) - ((char *) track->brk_start))); |
| 269 | #endif |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 270 | #ifdef HAVE_GETRUSAGE |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 271 | getrusage(RUSAGE_SELF, &r); |
| 272 | |
Theodore Ts'o | 80c5d7e | 2000-02-08 23:19:32 +0000 | [diff] [blame] | 273 | printf(_("time: %5.2f/%5.2f/%5.2f\n"), |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 274 | timeval_subtract(&time_end, &track->time_start), |
| 275 | timeval_subtract(&r.ru_utime, &track->user_start), |
| 276 | timeval_subtract(&r.ru_stime, &track->system_start)); |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 277 | #else |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 278 | printf(_("elapsed time: %6.3f\n"), |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 279 | timeval_subtract(&time_end, &track->time_start)); |
| 280 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 281 | } |
Theodore Ts'o | 8bf191e | 1997-10-20 01:38:32 +0000 | [diff] [blame] | 282 | #endif /* RESOURCE_TRACK */ |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 283 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 284 | void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 285 | struct ext2_inode * inode, const char *proc) |
| 286 | { |
| 287 | int retval; |
| 288 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 289 | retval = ext2fs_read_inode(ctx->fs, ino, inode); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 290 | if (retval) { |
| 291 | com_err("ext2fs_read_inode", retval, |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 292 | _("while reading inode %ld in %s"), ino, proc); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 293 | fatal_error(ctx, 0); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 294 | } |
| 295 | } |
| 296 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 297 | extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 298 | struct ext2_inode * inode, const char *proc) |
| 299 | { |
| 300 | int retval; |
| 301 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 302 | retval = ext2fs_write_inode(ctx->fs, ino, inode); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 303 | if (retval) { |
| 304 | com_err("ext2fs_write_inode", retval, |
Theodore Ts'o | 0c4a072 | 2000-02-07 03:11:03 +0000 | [diff] [blame] | 305 | _("while writing inode %ld in %s"), ino, proc); |
Theodore Ts'o | f8188ff | 1997-11-14 05:23:04 +0000 | [diff] [blame] | 306 | fatal_error(ctx, 0); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 307 | } |
| 308 | } |
| 309 | |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 310 | #ifdef MTRACE |
| 311 | void mtrace_print(char *mesg) |
| 312 | { |
| 313 | FILE *malloc_get_mallstream(); |
| 314 | FILE *f = malloc_get_mallstream(); |
| 315 | |
| 316 | if (f) |
| 317 | fprintf(f, "============= %s\n", mesg); |
| 318 | } |
| 319 | #endif |
| 320 | |
Theodore Ts'o | f1a1761 | 2001-12-23 22:27:52 -0500 | [diff] [blame] | 321 | blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, |
| 322 | io_manager manager) |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 323 | { |
Theodore Ts'o | f1a1761 | 2001-12-23 22:27:52 -0500 | [diff] [blame] | 324 | struct ext2_super_block *sb; |
| 325 | io_channel io = NULL; |
Theodore Ts'o | fae9bfa | 2001-12-23 22:56:12 -0500 | [diff] [blame] | 326 | void *buf = NULL; |
Theodore Ts'o | f1a1761 | 2001-12-23 22:27:52 -0500 | [diff] [blame] | 327 | int blocksize; |
| 328 | blk_t superblock, ret_sb = 8193; |
| 329 | |
| 330 | if (fs && fs->super) { |
| 331 | ret_sb = (fs->super->s_blocks_per_group + |
| 332 | fs->super->s_first_data_block); |
| 333 | if (ctx) { |
| 334 | ctx->superblock = ret_sb; |
| 335 | ctx->blocksize = fs->blocksize; |
| 336 | } |
| 337 | return ret_sb; |
| 338 | } |
| 339 | |
| 340 | if (ctx) { |
| 341 | if (ctx->blocksize) { |
| 342 | ret_sb = ctx->blocksize * 8; |
| 343 | if (ctx->blocksize == 1024) |
| 344 | ret_sb++; |
| 345 | ctx->superblock = ret_sb; |
| 346 | return ret_sb; |
| 347 | } |
| 348 | ctx->superblock = ret_sb; |
| 349 | ctx->blocksize = 1024; |
| 350 | } |
| 351 | |
| 352 | if (!name || !manager) |
| 353 | goto cleanup; |
| 354 | |
| 355 | if (manager->open(name, 0, &io) != 0) |
| 356 | goto cleanup; |
| 357 | |
| 358 | if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf)) |
| 359 | goto cleanup; |
| 360 | sb = (struct ext2_super_block *) buf; |
| 361 | |
Andreas Dilger | 932a489 | 2002-05-16 03:20:07 -0600 | [diff] [blame^] | 362 | for (blocksize = EXT2_MIN_BLOCK_SIZE; |
| 363 | blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) { |
Theodore Ts'o | f1a1761 | 2001-12-23 22:27:52 -0500 | [diff] [blame] | 364 | superblock = blocksize*8; |
| 365 | if (blocksize == 1024) |
| 366 | superblock++; |
| 367 | io_channel_set_blksize(io, blocksize); |
| 368 | if (io_channel_read_blk(io, superblock, |
| 369 | -SUPERBLOCK_SIZE, buf)) |
| 370 | continue; |
| 371 | #ifdef EXT2FS_ENABLE_SWAPFS |
| 372 | if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) |
| 373 | ext2fs_swap_super(sb); |
| 374 | #endif |
| 375 | if (sb->s_magic == EXT2_SUPER_MAGIC) { |
| 376 | ret_sb = ctx->superblock = superblock; |
| 377 | ctx->blocksize = blocksize; |
| 378 | break; |
| 379 | } |
| 380 | } |
| 381 | |
| 382 | cleanup: |
| 383 | if (io) |
| 384 | io_channel_close(io); |
| 385 | if (buf) |
| 386 | ext2fs_free_mem(&buf); |
| 387 | return (ret_sb); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 388 | } |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 389 | |
Theodore Ts'o | 6fdc7a3 | 1999-11-10 13:34:40 +0000 | [diff] [blame] | 390 | /* |
| 391 | * Given a mode, return the ext2 file type |
| 392 | */ |
| 393 | int ext2_file_type(unsigned int mode) |
| 394 | { |
| 395 | if (LINUX_S_ISREG(mode)) |
| 396 | return EXT2_FT_REG_FILE; |
| 397 | |
| 398 | if (LINUX_S_ISDIR(mode)) |
| 399 | return EXT2_FT_DIR; |
| 400 | |
| 401 | if (LINUX_S_ISCHR(mode)) |
| 402 | return EXT2_FT_CHRDEV; |
| 403 | |
| 404 | if (LINUX_S_ISBLK(mode)) |
| 405 | return EXT2_FT_BLKDEV; |
| 406 | |
| 407 | if (LINUX_S_ISLNK(mode)) |
| 408 | return EXT2_FT_SYMLINK; |
| 409 | |
| 410 | if (LINUX_S_ISFIFO(mode)) |
| 411 | return EXT2_FT_FIFO; |
| 412 | |
| 413 | if (LINUX_S_ISSOCK(mode)) |
| 414 | return EXT2_FT_SOCK; |
| 415 | |
| 416 | return 0; |
| 417 | } |