2 * util.c --- miscellaneous utilities
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
21 #include <sys/resource.h>
23 void fatal_error(e2fsck_t ctx, const char *msg)
26 fprintf (stderr, "e2fsck: %s\n", msg);
27 ctx->flags |= E2F_FLAG_ABORT;
28 if (ctx->flags & E2F_FLAG_SETJMP_OK)
29 longjmp(ctx->abort_loc, 1);
33 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
34 const char *description)
39 #ifdef DEBUG_ALLOCATE_MEMORY
40 printf("Allocating %d bytes for %s...\n", size, description);
44 sprintf(buf, "Can't allocate %s\n", description);
45 fatal_error(ctx, buf);
51 int ask_yn(const char * string, int def)
54 struct termios termios, tmp;
57 tcgetattr (0, &termios);
59 tmp.c_lflag &= ~(ICANON | ECHO);
62 tcsetattr (0, TCSANOW, &tmp);
70 printf("%s%s? ", string, defstr);
73 if ((c = getchar()) == EOF)
84 else if ((c == ' ' || c == '\n') && (def != -1))
91 tcsetattr (0, TCSANOW, &termios);
95 int ask (e2fsck_t ctx, const char * string, int def)
97 if (ctx->options & E2F_OPT_NO) {
98 printf ("%s? no\n\n", string);
101 if (ctx->options & E2F_OPT_YES) {
102 printf ("%s? yes\n\n", string);
105 if (ctx->options & E2F_OPT_PREEN) {
106 printf ("%s? %s\n\n", string, def ? "yes" : "no");
109 return ask_yn(string, def);
112 void e2fsck_read_bitmaps(e2fsck_t ctx)
114 ext2_filsys fs = ctx->fs;
117 if (ctx->invalid_bitmaps) {
118 com_err(ctx->program_name, 0,
119 "e2fsck_read_bitmaps: illegal bitmap block(s) for %s",
124 ehandler_operation("reading inode and block bitmaps");
125 retval = ext2fs_read_bitmaps(fs);
126 ehandler_operation(0);
128 com_err(ctx->program_name, retval,
129 "while retrying to read bitmaps for %s",
135 void e2fsck_write_bitmaps(e2fsck_t ctx)
137 ext2_filsys fs = ctx->fs;
140 if (ext2fs_test_bb_dirty(fs)) {
141 ehandler_operation("writing block bitmaps");
142 retval = ext2fs_write_block_bitmap(fs);
143 ehandler_operation(0);
145 com_err(ctx->program_name, retval,
146 "while retrying to write block bitmaps for %s",
152 if (ext2fs_test_ib_dirty(fs)) {
153 ehandler_operation("writing inode bitmaps");
154 retval = ext2fs_write_inode_bitmap(fs);
155 ehandler_operation(0);
157 com_err(ctx->program_name, retval,
158 "while retrying to write inode bitmaps for %s",
165 void preenhalt(e2fsck_t ctx)
167 ext2_filsys fs = ctx->fs;
169 if (!(ctx->options & E2F_OPT_PREEN))
171 fprintf(stderr, "\n\n%s: UNEXPECTED INCONSISTENCY; "
172 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n",
175 fs->super->s_state |= EXT2_ERROR_FS;
176 ext2fs_mark_super_dirty(fs);
179 exit(FSCK_UNCORRECTED);
182 #ifdef RESOURCE_TRACK
183 void init_resource_track(struct resource_track *track)
185 #ifdef HAVE_GETRUSAGE
189 track->brk_start = sbrk(0);
190 gettimeofday(&track->time_start, 0);
191 #ifdef HAVE_GETRUSAGE
193 memcpy(&r, 0, sizeof(struct rusage));
195 getrusage(RUSAGE_SELF, &r);
196 track->user_start = r.ru_utime;
197 track->system_start = r.ru_stime;
199 track->user_start.tv_sec = track->user_start.tv_usec = 0;
200 track->system_start.tv_sec = track->system_start.tv_usec = 0;
205 #define _INLINE_ __inline__
210 static _INLINE_ float timeval_subtract(struct timeval *tv1,
213 return ((tv1->tv_sec - tv2->tv_sec) +
214 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
217 void print_resource_track(const char *desc, struct resource_track *track)
219 #ifdef HAVE_GETRUSAGE
222 struct timeval time_end;
224 gettimeofday(&time_end, 0);
227 printf("%s: ", desc);
229 #ifdef HAVE_GETRUSAGE
230 getrusage(RUSAGE_SELF, &r);
232 printf("Memory used: %d, elapsed time: %6.3f/%6.3f/%6.3f\n",
233 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)),
234 timeval_subtract(&time_end, &track->time_start),
235 timeval_subtract(&r.ru_utime, &track->user_start),
236 timeval_subtract(&r.ru_stime, &track->system_start));
238 printf("Memory used: %d, elapsed time: %6.3f\n",
239 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)),
240 timeval_subtract(&time_end, &track->time_start));
243 #endif /* RESOURCE_TRACK */
245 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
246 struct ext2_inode * inode, const char *proc)
250 retval = ext2fs_read_inode(ctx->fs, ino, inode);
252 com_err("ext2fs_read_inode", retval,
253 "while reading inode %ld in %s", ino, proc);
258 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
259 struct ext2_inode * inode, const char *proc)
263 retval = ext2fs_write_inode(ctx->fs, ino, inode);
265 com_err("ext2fs_write_inode", retval,
266 "while writing inode %ld in %s", ino, proc);
272 void mtrace_print(char *mesg)
274 FILE *malloc_get_mallstream();
275 FILE *f = malloc_get_mallstream();
278 fprintf(f, "============= %s\n", mesg);
282 blk_t get_backup_sb(ext2_filsys fs)
284 if (!fs || !fs->super)
286 return fs->super->s_blocks_per_group + 1;