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
20 #define read_a_char() getch()
26 #define read_a_char() getchar()
36 #include <sys/resource.h>
38 void fatal_error(e2fsck_t ctx, const char *msg)
41 fprintf (stderr, "e2fsck: %s\n", msg);
42 if (ctx->fs && ctx->fs->io)
43 io_channel_flush(ctx->fs->io);
44 ctx->flags |= E2F_FLAG_ABORT;
45 if (ctx->flags & E2F_FLAG_SETJMP_OK)
46 longjmp(ctx->abort_loc, 1);
50 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
51 const char *description)
56 #ifdef DEBUG_ALLOCATE_MEMORY
57 printf("Allocating %d bytes for %s...\n", size, description);
61 sprintf(buf, "Can't allocate %s\n", description);
62 fatal_error(ctx, buf);
68 int ask_yn(const char * string, int def)
72 char *short_yes = _("yY");
73 char *short_no = _("nN");
76 struct termios termios, tmp;
78 tcgetattr (0, &termios);
80 tmp.c_lflag &= ~(ICANON | ECHO);
83 tcsetattr (0, TCSANOW, &tmp);
92 printf("%s%s? ", string, defstr);
95 if ((c = read_a_char()) == EOF)
97 if (strchr(short_yes, (char) c)) {
101 else if (strchr(short_no, (char) c)) {
105 else if ((c == ' ' || c == '\n') && (def != -1))
112 #ifdef HAVE_TERMIOS_H
113 tcsetattr (0, TCSANOW, &termios);
118 int ask (e2fsck_t ctx, const char * string, int def)
120 if (ctx->options & E2F_OPT_NO) {
121 printf (_("%s? no\n\n"), string);
124 if (ctx->options & E2F_OPT_YES) {
125 printf (_("%s? yes\n\n"), string);
128 if (ctx->options & E2F_OPT_PREEN) {
129 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
132 return ask_yn(string, def);
135 void e2fsck_read_bitmaps(e2fsck_t ctx)
137 ext2_filsys fs = ctx->fs;
140 if (ctx->invalid_bitmaps) {
141 com_err(ctx->program_name, 0,
142 _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
147 ehandler_operation(_("reading inode and block bitmaps"));
148 retval = ext2fs_read_bitmaps(fs);
149 ehandler_operation(0);
151 com_err(ctx->program_name, retval,
152 _("while retrying to read bitmaps for %s"),
158 void e2fsck_write_bitmaps(e2fsck_t ctx)
160 ext2_filsys fs = ctx->fs;
163 if (ext2fs_test_bb_dirty(fs)) {
164 ehandler_operation(_("writing block bitmaps"));
165 retval = ext2fs_write_block_bitmap(fs);
166 ehandler_operation(0);
168 com_err(ctx->program_name, retval,
169 _("while retrying to write block bitmaps for %s"),
175 if (ext2fs_test_ib_dirty(fs)) {
176 ehandler_operation(_("writing inode bitmaps"));
177 retval = ext2fs_write_inode_bitmap(fs);
178 ehandler_operation(0);
180 com_err(ctx->program_name, retval,
181 _("while retrying to write inode bitmaps for %s"),
188 void preenhalt(e2fsck_t ctx)
190 ext2_filsys fs = ctx->fs;
192 if (!(ctx->options & E2F_OPT_PREEN))
194 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
195 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
198 fs->super->s_state |= EXT2_ERROR_FS;
199 ext2fs_mark_super_dirty(fs);
202 exit(FSCK_UNCORRECTED);
205 #ifdef RESOURCE_TRACK
206 void init_resource_track(struct resource_track *track)
208 #ifdef HAVE_GETRUSAGE
212 track->brk_start = sbrk(0);
213 gettimeofday(&track->time_start, 0);
214 #ifdef HAVE_GETRUSAGE
216 memcpy(&r, 0, sizeof(struct rusage));
218 getrusage(RUSAGE_SELF, &r);
219 track->user_start = r.ru_utime;
220 track->system_start = r.ru_stime;
222 track->user_start.tv_sec = track->user_start.tv_usec = 0;
223 track->system_start.tv_sec = track->system_start.tv_usec = 0;
228 #define _INLINE_ __inline__
233 static _INLINE_ float timeval_subtract(struct timeval *tv1,
236 return ((tv1->tv_sec - tv2->tv_sec) +
237 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
240 void print_resource_track(const char *desc, struct resource_track *track)
242 #ifdef HAVE_GETRUSAGE
246 struct mallinfo malloc_info;
248 struct timeval time_end;
250 gettimeofday(&time_end, 0);
253 printf("%s: ", desc);
256 #define kbytes(x) (((x) + 1023) / 1024)
258 malloc_info = mallinfo();
259 printf(_("Memory used: %dk/%dk (%dk/%dk), "),
260 kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
261 kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
263 printf(_("Memory used: %d, "),
264 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)));
266 #ifdef HAVE_GETRUSAGE
267 getrusage(RUSAGE_SELF, &r);
269 printf(_("time: %5.2f/%5.2f/%5.2f\n"),
270 timeval_subtract(&time_end, &track->time_start),
271 timeval_subtract(&r.ru_utime, &track->user_start),
272 timeval_subtract(&r.ru_stime, &track->system_start));
274 printf(_("elapsed time: %6.3f\n"),
275 timeval_subtract(&time_end, &track->time_start));
278 #endif /* RESOURCE_TRACK */
280 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
281 struct ext2_inode * inode, const char *proc)
285 retval = ext2fs_read_inode(ctx->fs, ino, inode);
287 com_err("ext2fs_read_inode", retval,
288 _("while reading inode %ld in %s"), ino, proc);
293 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
294 struct ext2_inode * inode, const char *proc)
298 retval = ext2fs_write_inode(ctx->fs, ino, inode);
300 com_err("ext2fs_write_inode", retval,
301 _("while writing inode %ld in %s"), ino, proc);
307 void mtrace_print(char *mesg)
309 FILE *malloc_get_mallstream();
310 FILE *f = malloc_get_mallstream();
313 fprintf(f, "============= %s\n", mesg);
317 blk_t get_backup_sb(ext2_filsys fs)
319 if (!fs || !fs->super)
321 return fs->super->s_blocks_per_group + 1;
325 * Given a mode, return the ext2 file type
327 int ext2_file_type(unsigned int mode)
329 if (LINUX_S_ISREG(mode))
330 return EXT2_FT_REG_FILE;
332 if (LINUX_S_ISDIR(mode))
335 if (LINUX_S_ISCHR(mode))
336 return EXT2_FT_CHRDEV;
338 if (LINUX_S_ISBLK(mode))
339 return EXT2_FT_BLKDEV;
341 if (LINUX_S_ISLNK(mode))
342 return EXT2_FT_SYMLINK;
344 if (LINUX_S_ISFIFO(mode))
347 if (LINUX_S_ISSOCK(mode))