13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * util.c --- miscellaneous utilities 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header% 721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * This file may be redistributed under the terms of the GNU Public 821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * License. 921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header% 103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h> 1380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o#include <stdio.h> 143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h> 163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <ctype.h> 1780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o#ifdef __linux__ 1880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o#include <sys/utsname.h> 1980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o#endif 209ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o 219ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_CONIO_H 229ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#undef HAVE_TERMIOS_H 239ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#include <conio.h> 24e6597048d9d1637c9f997363a7f45c74b98fd0e2Theodore Ts'o#define read_a_char() getch() 259ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#else 269ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_TERMIOS_H 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <termios.h> 289ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif 299ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif 309ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o 314a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#ifdef HAVE_MALLOC_H 324a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#include <malloc.h> 334a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#endif 343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3549a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos#ifdef HAVE_ERRNO_H 3649a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos#include <errno.h> 3749a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos#endif 3849a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos 393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2fsck.h" 403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 41aa75ecccab67ea7428fc19c66e80a28fb1ca941fTheodore Ts'oextern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */ 42542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o 43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <stdarg.h> 44e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#include <time.h> 4550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/time.h> 4650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/resource.h> 4750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 48f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid fatal_error(e2fsck_t ctx, const char *msg) 493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 50e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2_filsys fs = ctx->fs; 51e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int exit_value = FSCK_ERROR; 52e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 53efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (msg) 541b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o fprintf (stderr, "e2fsck: %s\n", msg); 55e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!fs) 56e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto out; 57e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (fs->io && fs->super) { 58e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_mmp_stop(ctx->fs); 59e39ac92269d645bd279c2660d127b47159b8b1f9Theodore Ts'o if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL) 6058a75177cabbea82361d037978485b2d656c8c89Theodore Ts'o io_channel_flush(ctx->fs->io); 6158a75177cabbea82361d037978485b2d656c8c89Theodore Ts'o else 62e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_err(ctx, "e2fsck: io manager magic bad!\n"); 63e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 64e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ext2fs_test_changed(fs)) { 65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall exit_value |= FSCK_NONDESTRUCT; 66e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"), 67e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ctx->device_name); 68e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ctx->mount_flags & EXT2_MF_ISROOT) 69e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall exit_value |= FSCK_REBOOT; 70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 71e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!ext2fs_test_valid(fs)) { 72e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("\n%s: ********** WARNING: Filesystem still has " 73e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "errors **********\n\n"), ctx->device_name); 74e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall exit_value |= FSCK_UNCORRECTED; 75e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall exit_value &= ~FSCK_NONDESTRUCT; 7613dcce8bb46961fcab14e87343e25aaebef7f44cEric Sandeen } 77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallout: 78f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o ctx->flags |= E2F_FLAG_ABORT; 79f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o if (ctx->flags & E2F_FLAG_SETJMP_OK) 80f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o longjmp(ctx->abort_loc, 1); 81e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall exit(exit_value); 82e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 83e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 84e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid log_out(e2fsck_t ctx, const char *fmt, ...) 85e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 86e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_list pvar; 87e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 88e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_start(pvar, fmt); 89e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall vprintf(fmt, pvar); 90e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_end(pvar); 91e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ctx->logf) { 92e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_start(pvar, fmt); 93e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall vfprintf(ctx->logf, fmt, pvar); 94e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_end(pvar); 95e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 96e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 97e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 98e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid log_err(e2fsck_t ctx, const char *fmt, ...) 99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 100e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_list pvar; 101e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_start(pvar, fmt); 103e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall vfprintf(stderr, fmt, pvar); 104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_end(pvar); 105e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ctx->logf) { 106e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_start(pvar, fmt); 107e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall vfprintf(ctx->logf, fmt, pvar); 108e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall va_end(pvar); 109e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 110b0e91c89257d906324d6081c952157f768dfc699Theodore Ts'o} 111b0e91c89257d906324d6081c952157f768dfc699Theodore Ts'o 112f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, 113f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o const char *description) 1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o void *ret; 1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char buf[256]; 1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifdef DEBUG_ALLOCATE_MEMORY 119611378fe20777da83fcc8fe77ff2c515b7dc1e42Andreas Dilger printf("Allocating %u bytes for %s...\n", size, description); 1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif 1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o ret = malloc(size); 1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!ret) { 123e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall sprintf(buf, "Can't allocate %u bytes for %s\n", 124e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall size, description); 125f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o fatal_error(ctx, buf); 1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o memset(ret, 0, size); 1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return ret; 1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 131efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ochar *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)), 132544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o const char *str, int len) 133f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o{ 134f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o char *ret; 135efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 136f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o if (!str) 137f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o return NULL; 138f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o if (!len) 139f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o len = strlen(str); 140f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o ret = malloc(len+1); 141f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o if (ret) { 142f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o strncpy(ret, str, len); 143f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o ret[len] = 0; 144f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o } 145f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o return ret; 146f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o} 147f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o 148f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o#ifndef HAVE_STRNLEN 149f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o/* 150f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o * Incredibly, libc5 doesn't appear to have strnlen. So we have to 151f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o * provide our own. 152f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o */ 153f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'oint e2fsck_strnlen(const char * s, int count) 154f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o{ 155f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o const char *cp = s; 156f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o 157f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o while (count-- && *cp) 158f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o cp++; 159f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o return cp - s; 160f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o} 161f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o#endif 162f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o 163542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o#ifndef HAVE_CONIO_H 1643e69906495d5898849a6154b0311b5d4a84a27aeTheodore Ts'ostatic int read_a_char(void) 165542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o{ 166542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o char c; 167542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o int r; 168542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o int fail = 0; 169542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o 170542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o while(1) { 171542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o if (e2fsck_global_ctx && 172542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) { 173542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o return 3; 174542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o } 175542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o r = read(0, &c, 1); 176542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o if (r == 1) 177542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o return c; 178542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o if (fail++ > 100) 179542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o break; 180542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o } 181542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o return EOF; 182542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o} 183542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o#endif 184542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o 185e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ask_yn(e2fsck_t ctx, const char * string, int def) 1863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 1873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int c; 1883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o const char *defstr; 18953ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o const char *short_yes = _("yY"); 19053ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o const char *short_no = _("nN"); 1913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1929ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_TERMIOS_H 1939ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o struct termios termios, tmp; 1949ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o 1953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o tcgetattr (0, &termios); 1963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o tmp = termios; 1973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o tmp.c_lflag &= ~(ICANON | ECHO); 19850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o tmp.c_cc[VMIN] = 1; 19950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o tmp.c_cc[VTIME] = 0; 2003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o tcsetattr (0, TCSANOW, &tmp); 2019ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif 2023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (def == 1) 204542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o defstr = _(_("<y>")); 2053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else if (def == 0) 206542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o defstr = _(_("<n>")); 2073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 2080c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o defstr = _(" (y/n)"); 209e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s%s? ", string, defstr); 2103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o while (1) { 2113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fflush (stdout); 212e6597048d9d1637c9f997363a7f45c74b98fd0e2Theodore Ts'o if ((c = read_a_char()) == EOF) 2133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 214542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o if (c == 3) { 215542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o#ifdef HAVE_TERMIOS_H 216542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o tcsetattr (0, TCSANOW, &termios); 217542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o#endif 218e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ctx->flags & E2F_FLAG_SETJMP_OK) { 219e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "\n"); 220542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o longjmp(e2fsck_global_ctx->abort_loc, 1); 221542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o } 222e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s", _("cancelled!\n")); 223542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o return 0; 224542867fb705f0c5705365e470f3e3dd097b5bdedTheodore Ts'o } 2250c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o if (strchr(short_yes, (char) c)) { 2263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o def = 1; 2273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2290c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o else if (strchr(short_no, (char) c)) { 2303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o def = 0; 2313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 233e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall else if ((c == 27 || c == ' ' || c == '\n') && (def != -1)) 2343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 2353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (def) 237e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s", _("yes\n")); 2383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 239e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s", _("no\n")); 2409ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_TERMIOS_H 2413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o tcsetattr (0, TCSANOW, &termios); 2429ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif 2433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return def; 2443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2461b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'oint ask (e2fsck_t ctx, const char * string, int def) 2473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 2481b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o if (ctx->options & E2F_OPT_NO) { 249e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("%s? no\n\n"), string); 2503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 2513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2521b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o if (ctx->options & E2F_OPT_YES) { 253e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("%s? yes\n\n"), string); 2543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 1; 2553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2561b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o if (ctx->options & E2F_OPT_PREEN) { 257e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s? %s\n\n", string, def ? _("yes") : _("no")); 2583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return def; 2593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 260e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ask_yn(ctx, string, def); 2613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 263f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid e2fsck_read_bitmaps(e2fsck_t ctx) 2643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 2651b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o ext2_filsys fs = ctx->fs; 2663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 267e94bc631648299dca43a6015520b18f6232d50dfTheodore Ts'o const char *old_op; 268e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned int save_type; 2693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2701b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o if (ctx->invalid_bitmaps) { 2711b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o com_err(ctx->program_name, 0, 2720c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"), 2731b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o ctx->device_name); 274f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o fatal_error(ctx, 0); 2753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 276f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 277e94bc631648299dca43a6015520b18f6232d50dfTheodore Ts'o old_op = ehandler_operation(_("reading inode and block bitmaps")); 278e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall e2fsck_set_bitmap_type(fs, EXT2FS_BMAP64_RBTREE, "fs_bitmaps", 279e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall &save_type); 280f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o retval = ext2fs_read_bitmaps(fs); 281e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->default_bitmap_type = save_type; 282e94bc631648299dca43a6015520b18f6232d50dfTheodore Ts'o ehandler_operation(old_op); 283f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 2841b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o com_err(ctx->program_name, retval, 2850c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o _("while retrying to read bitmaps for %s"), 2861b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o ctx->device_name); 287f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o fatal_error(ctx, 0); 2883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 2893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 2903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 291f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid e2fsck_write_bitmaps(e2fsck_t ctx) 2923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 2931b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o ext2_filsys fs = ctx->fs; 2943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 295e94bc631648299dca43a6015520b18f6232d50dfTheodore Ts'o const char *old_op; 2963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 2971bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger old_op = ehandler_operation(_("writing block and inode bitmaps")); 2981bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger retval = ext2fs_write_bitmaps(fs); 2991bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger ehandler_operation(old_op); 3001bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger if (retval) { 3011bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger com_err(ctx->program_name, retval, 3021bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger _("while rewriting block and inode bitmaps for %s"), 3031bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger ctx->device_name); 3041bb6f6c87e860f8c021f966fc36aa8768590a227Andreas Dilger fatal_error(ctx, 0); 3053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3081b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'ovoid preenhalt(e2fsck_t ctx) 3093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 3101b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o ext2_filsys fs = ctx->fs; 3111b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o 3121b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o if (!(ctx->options & E2F_OPT_PREEN)) 3133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 314e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_err(ctx, _("\n\n%s: UNEXPECTED INCONSISTENCY; " 3150c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"), 3161b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o ctx->device_name); 31779cc33628256e817610e921ddf600f72e4f879e1Eric Sandeen ctx->flags |= E2F_FLAG_EXITING; 31850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (fs != NULL) { 31950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o fs->super->s_state |= EXT2_ERROR_FS; 32050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ext2fs_mark_super_dirty(fs); 32150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ext2fs_close(fs); 32250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 3233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o exit(FSCK_UNCORRECTED); 3243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 3253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3268bf191e8660939687ef35c013066d2082cb16722Theodore Ts'o#ifdef RESOURCE_TRACK 3276d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'ovoid init_resource_track(struct resource_track *track, io_channel channel) 3283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 32950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE 3303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o struct rusage r; 33150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 3326d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o io_stats io_start = 0; 333efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 3343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o track->brk_start = sbrk(0); 3353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gettimeofday(&track->time_start, 0); 33650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE 33753ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o#ifdef sun 33853ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o memset(&r, 0, sizeof(struct rusage)); 3391b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o#endif 3403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o getrusage(RUSAGE_SELF, &r); 3413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o track->user_start = r.ru_utime; 3423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o track->system_start = r.ru_stime; 34350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#else 34450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o track->user_start.tv_sec = track->user_start.tv_usec = 0; 34550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o track->system_start.tv_sec = track->system_start.tv_usec = 0; 34650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 3476d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o track->bytes_read = 0; 3486d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o track->bytes_written = 0; 3496d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o if (channel && channel->manager && channel->manager->get_stats) 3506d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o channel->manager->get_stats(channel, &io_start); 3516d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o if (io_start) { 3526d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o track->bytes_read = io_start->bytes_read; 3536d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o track->bytes_written = io_start->bytes_written; 3546d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o } 3553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 3563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 35721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#ifdef __GNUC__ 35821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#define _INLINE_ __inline__ 35921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#else 36021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#define _INLINE_ 36121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#endif 36221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 36321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ostatic _INLINE_ float timeval_subtract(struct timeval *tv1, 36421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o struct timeval *tv2) 3653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 3663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return ((tv1->tv_sec - tv2->tv_sec) + 3673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000); 3683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 3693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3709facd076ae8af6e908e228392cea866ce0faf1bcKen Chenvoid print_resource_track(e2fsck_t ctx, const char *desc, 3719facd076ae8af6e908e228392cea866ce0faf1bcKen Chen struct resource_track *track, io_channel channel) 3723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 37350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE 3743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o struct rusage r; 37550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 3764a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#ifdef HAVE_MALLINFO 3774a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o struct mallinfo malloc_info; 3784a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#endif 3793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o struct timeval time_end; 3803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 3819facd076ae8af6e908e228392cea866ce0faf1bcKen Chen if ((desc && !(ctx->options & E2F_OPT_TIME2)) || 3829facd076ae8af6e908e228392cea866ce0faf1bcKen Chen (!desc && !(ctx->options & E2F_OPT_TIME))) 3839facd076ae8af6e908e228392cea866ce0faf1bcKen Chen return; 3849facd076ae8af6e908e228392cea866ce0faf1bcKen Chen 3859facd076ae8af6e908e228392cea866ce0faf1bcKen Chen e2fsck_clear_progbar(ctx); 3863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gettimeofday(&time_end, 0); 3871b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o 3881b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o if (desc) 389e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s: ", desc); 3904a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o 3914a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#ifdef HAVE_MALLINFO 39270eabde9a581d340837c98b11d3ced324155d1aeAndreas Dilger#define kbytes(x) (((unsigned long)(x) + 1023) / 1024) 393efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 3944a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o malloc_info = mallinfo(); 395e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("Memory used: %luk/%luk (%luk/%luk), "), 396e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd), 397e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks)); 3984a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#else 399e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("Memory used: %lu, "), 400e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (unsigned long) (((char *) sbrk(0)) - 401e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ((char *) track->brk_start))); 402efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#endif 40350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE 4043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o getrusage(RUSAGE_SELF, &r); 4053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 406e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("time: %5.2f/%5.2f/%5.2f\n"), 407e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall timeval_subtract(&time_end, &track->time_start), 408e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall timeval_subtract(&r.ru_utime, &track->user_start), 409e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall timeval_subtract(&r.ru_stime, &track->system_start)); 41050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#else 411e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, _("elapsed time: %6.3f\n"), 412e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall timeval_subtract(&time_end, &track->time_start)); 41350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 4146d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o#define mbytes(x) (((x) + 1048575) / 1048576) 4156d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o if (channel && channel->manager && channel->manager->get_stats) { 4166d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o io_stats delta = 0; 4176d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o unsigned long long bytes_read = 0; 4186d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o unsigned long long bytes_written = 0; 4196d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o 4206d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o if (desc) 421e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "%s: ", desc); 4226d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o 4236d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o channel->manager->get_stats(channel, &delta); 4246d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o if (delta) { 4256d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o bytes_read = delta->bytes_read - track->bytes_read; 426efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o bytes_written = delta->bytes_written - 4276d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o track->bytes_written; 4286d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o } 429e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall log_out(ctx, "I/O read: %lluMB, write: %lluMB, " 430e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "rate: %.2fMB/s\n", 431e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall mbytes(bytes_read), mbytes(bytes_written), 432e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (double)mbytes(bytes_read + bytes_written) / 433e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall timeval_subtract(&time_end, &track->time_start)); 4346d96b00d57d236e2746f8245df6c8ea64abc64c1Theodore Ts'o } 4353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 4368bf191e8660939687ef35c013066d2082cb16722Theodore Ts'o#endif /* RESOURCE_TRACK */ 4373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 43808b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'ovoid e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, 439f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o struct ext2_inode * inode, const char *proc) 440f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 441e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 442f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 44308b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'o retval = ext2fs_read_inode(ctx->fs, ino, inode); 444f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 445f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err("ext2fs_read_inode", retval, 446611378fe20777da83fcc8fe77ff2c515b7dc1e42Andreas Dilger _("while reading inode %lu in %s"), ino, proc); 447f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o fatal_error(ctx, 0); 448f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 449f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 450f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 451fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilgervoid e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino, 452fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger struct ext2_inode *inode, int bufsize, 453fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger const char *proc) 454fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger{ 455e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 456fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger 457fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger retval = ext2fs_read_inode_full(ctx->fs, ino, inode, bufsize); 458fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger if (retval) { 459fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger com_err("ext2fs_read_inode_full", retval, 460611378fe20777da83fcc8fe77ff2c515b7dc1e42Andreas Dilger _("while reading inode %lu in %s"), ino, proc); 461fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger fatal_error(ctx, 0); 462fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger } 463fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger} 464fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger 465e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino, 466e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_inode * inode, int bufsize, 467e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *proc) 468cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o{ 469e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 470cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o 471cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize); 472cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o if (retval) { 473cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o com_err("ext2fs_write_inode", retval, 474611378fe20777da83fcc8fe77ff2c515b7dc1e42Andreas Dilger _("while writing inode %lu in %s"), ino, proc); 475cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o fatal_error(ctx, 0); 476cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o } 477cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o} 478cebe48a1ece8b9f61271c73ead83b59c8b36233eTheodore Ts'o 479e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, 480e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_inode * inode, const char *proc) 481f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 482e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 483f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 48408b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'o retval = ext2fs_write_inode(ctx->fs, ino, inode); 485f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 486f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err("ext2fs_write_inode", retval, 487611378fe20777da83fcc8fe77ff2c515b7dc1e42Andreas Dilger _("while writing inode %lu in %s"), ino, proc); 488f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o fatal_error(ctx, 0); 489f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 490f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 491f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 4923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifdef MTRACE 4933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid mtrace_print(char *mesg) 4943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 4953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE *malloc_get_mallstream(); 4963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE *f = malloc_get_mallstream(); 4973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 4983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (f) 4993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fprintf(f, "============= %s\n", mesg); 5003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 5013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif 5023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 503e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallblk64_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, 504e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall io_manager manager) 5051b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o{ 506f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o struct ext2_super_block *sb; 507f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o io_channel io = NULL; 508fae9bfaa5c1dc8b1bd6190d1a51024031e5ac9cfTheodore Ts'o void *buf = NULL; 509f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o int blocksize; 510e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t superblock, ret_sb = 8193; 511efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 512f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (fs && fs->super) { 513f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ret_sb = (fs->super->s_blocks_per_group + 514f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o fs->super->s_first_data_block); 515f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (ctx) { 516f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ctx->superblock = ret_sb; 517f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ctx->blocksize = fs->blocksize; 518f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o } 519f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o return ret_sb; 520f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o } 521efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 522f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (ctx) { 523f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (ctx->blocksize) { 524f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ret_sb = ctx->blocksize * 8; 525f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (ctx->blocksize == 1024) 526f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ret_sb++; 527f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ctx->superblock = ret_sb; 528f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o return ret_sb; 529f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o } 530f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ctx->superblock = ret_sb; 531f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ctx->blocksize = 1024; 532f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o } 533f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o 534f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (!name || !manager) 535f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o goto cleanup; 536f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o 537f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (manager->open(name, 0, &io) != 0) 538f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o goto cleanup; 539f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o 540f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf)) 541f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o goto cleanup; 542f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o sb = (struct ext2_super_block *) buf; 543f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o 544932a489cdf6bc83d69e59d3f8e0a57b733799ce1Andreas Dilger for (blocksize = EXT2_MIN_BLOCK_SIZE; 545932a489cdf6bc83d69e59d3f8e0a57b733799ce1Andreas Dilger blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) { 546f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o superblock = blocksize*8; 547f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (blocksize == 1024) 548f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o superblock++; 549f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o io_channel_set_blksize(io, blocksize); 550e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (io_channel_read_blk64(io, superblock, 551f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o -SUPERBLOCK_SIZE, buf)) 552f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o continue; 5532eae093081a097a0a611fe2817e1533825dfdd86Theodore Ts'o#ifdef WORDS_BIGENDIAN 554f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) 555f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ext2fs_swap_super(sb); 556f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o#endif 557e7b5d3c0b2bb1bafc5be57796ac1b68b1ac8e983Daniel Drake if ((sb->s_magic == EXT2_SUPER_MAGIC) && 558e7b5d3c0b2bb1bafc5be57796ac1b68b1ac8e983Daniel Drake (EXT2_BLOCK_SIZE(sb) == blocksize)) { 559557ddb2fdf46c055d80c66267c8c83299527c8d1Theodore Ts'o ret_sb = superblock; 560557ddb2fdf46c055d80c66267c8c83299527c8d1Theodore Ts'o if (ctx) { 561557ddb2fdf46c055d80c66267c8c83299527c8d1Theodore Ts'o ctx->superblock = superblock; 562557ddb2fdf46c055d80c66267c8c83299527c8d1Theodore Ts'o ctx->blocksize = blocksize; 563557ddb2fdf46c055d80c66267c8c83299527c8d1Theodore Ts'o } 564f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o break; 565f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o } 566f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o } 567f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o 568f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'ocleanup: 569f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (io) 570f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o io_channel_close(io); 571f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o if (buf) 572f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o ext2fs_free_mem(&buf); 573f1a1761d678a5ac539419f62676ce4c1bbd0767eTheodore Ts'o return (ret_sb); 5741b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o} 5753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 5766fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o/* 5776fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o * Given a mode, return the ext2 file type 5786fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o */ 5796fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'oint ext2_file_type(unsigned int mode) 5806fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o{ 5816fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISREG(mode)) 5826fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_REG_FILE; 5836fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o 5846fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISDIR(mode)) 5856fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_DIR; 586efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 5876fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISCHR(mode)) 5886fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_CHRDEV; 589efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 5906fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISBLK(mode)) 5916fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_BLKDEV; 592efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 5936fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISLNK(mode)) 5946fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_SYMLINK; 5956fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o 5966fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISFIFO(mode)) 5976fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_FIFO; 598efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 5996fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o if (LINUX_S_ISSOCK(mode)) 6006fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return EXT2_FT_SOCK; 601efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 6026fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o return 0; 6036fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o} 60449a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos 60549a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos#define STRIDE_LENGTH 8 60649a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos/* 60749a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * Helper function which zeros out _num_ blocks starting at _blk_. In 60849a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * case of an error, the details of the error is returned via _ret_blk_ 60949a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * and _ret_count_ if they are non-NULL pointers. Returns 0 on 61049a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * success, and an error code on an error. 61149a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * 61249a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * As a special case, if the first argument is NULL, then it will 61349a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * attempt to free the static zeroizing buffer. (This is to keep 61449a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos * programs that check for memory leaks happy.) 61549a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos */ 61649a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santoserrcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num, 61749a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos blk_t *ret_blk, int *ret_count) 61849a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos{ 619e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int j, count; 62049a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos static char *buf; 62149a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos errcode_t retval; 62249a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos 62349a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos /* If fs is null, clean up the static buffer and return */ 62449a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (!fs) { 62549a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (buf) { 62649a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos free(buf); 62749a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos buf = 0; 62849a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos } 62949a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos return 0; 63049a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos } 63149a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos /* Allocate the zeroizing buffer if necessary */ 63249a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (!buf) { 63349a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos buf = malloc(fs->blocksize * STRIDE_LENGTH); 63449a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (!buf) { 635e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall com_err("malloc", ENOMEM, "%s", 63649a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos _("while allocating zeroizing buffer")); 63749a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos exit(1); 63849a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos } 63949a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos memset(buf, 0, fs->blocksize * STRIDE_LENGTH); 64049a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos } 64149a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos /* OK, do the write loop */ 64249a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { 64349a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos count = num - j; 64449a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (count > STRIDE_LENGTH) 64549a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos count = STRIDE_LENGTH; 646e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = io_channel_write_blk64(fs->io, blk, count, buf); 64749a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (retval) { 64849a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (ret_count) 64949a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos *ret_count = count; 65049a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos if (ret_blk) 65149a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos *ret_blk = blk; 65249a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos return retval; 65349a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos } 65449a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos } 65549a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos return 0; 65649a7360ba6b986242d9f0f33e102291d2e0dfb47Jose R. Santos} 65780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o 65880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o/* 65980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o * Check to see if a filesystem is in /proc/filesystems. 66080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o * Returns 1 if found, 0 if not 66180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o */ 66280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'oint fs_proc_check(const char *fs_name) 66380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o{ 66480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o FILE *f; 66580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o char buf[80], *cp, *t; 66680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o 66780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o f = fopen("/proc/filesystems", "r"); 66880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!f) 66980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (0); 67080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o while (!feof(f)) { 67180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!fgets(buf, sizeof(buf), f)) 67280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o break; 67380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o cp = buf; 67480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!isspace(*cp)) { 67580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o while (*cp && !isspace(*cp)) 67680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o cp++; 67780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o } 67880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o while (*cp && isspace(*cp)) 67980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o cp++; 68080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if ((t = strchr(cp, '\n')) != NULL) 68180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o *t = 0; 68280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if ((t = strchr(cp, '\t')) != NULL) 68380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o *t = 0; 68480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if ((t = strchr(cp, ' ')) != NULL) 68580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o *t = 0; 68680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!strcmp(fs_name, cp)) { 68780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o fclose(f); 68880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (1); 68980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o } 69080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o } 69180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o fclose(f); 69280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (0); 69380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o} 69480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o 69580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o/* 69680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o * Check to see if a filesystem is available as a module 69780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o * Returns 1 if found, 0 if not 69880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o */ 69980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'oint check_for_modules(const char *fs_name) 70080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o{ 70180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o#ifdef __linux__ 70280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o struct utsname uts; 70380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o FILE *f; 70480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o char buf[1024], *cp, *t; 70580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o int i; 70680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o 70780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (uname(&uts)) 70880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (0); 70980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release); 71080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o 71180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o f = fopen(buf, "r"); 71280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!f) 71380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (0); 71480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o while (!feof(f)) { 71580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!fgets(buf, sizeof(buf), f)) 71680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o break; 71780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if ((cp = strchr(buf, ':')) != NULL) 71880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o *cp = 0; 71980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o else 72080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o continue; 72180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if ((cp = strrchr(buf, '/')) != NULL) 72280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o cp++; 723f2fe5da31deebc689bb64e71c8e873efc925d312Eric Sandeen else 724f2fe5da31deebc689bb64e71c8e873efc925d312Eric Sandeen cp = buf; 72580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o i = strlen(cp); 72680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (i > 3) { 72780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o t = cp + i - 3; 72880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!strcmp(t, ".ko")) 72980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o *t = 0; 73080875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o } 73180875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o if (!strcmp(cp, fs_name)) { 73280875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o fclose(f); 73380875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (1); 73480875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o } 73580875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o } 73680875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o fclose(f); 73780875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o#endif /* __linux__ */ 73880875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o return (0); 73980875db58a6db58e3e2f01caf1adabca068d3ffbTheodore Ts'o} 740b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o 741b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o/* 742b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o * Helper function that does the right thing if write returns a 743b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o * partial write, or an EGAIN/EINTR error. 744b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o */ 745b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'oint write_all(int fd, char *buf, size_t count) 746b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o{ 747b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o ssize_t ret; 748b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o int c = 0; 749b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o 750b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o while (count > 0) { 751b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o ret = write(fd, buf, count); 752b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o if (ret < 0) { 753b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o if ((errno == EAGAIN) || (errno == EINTR)) 754b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o continue; 755b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o return -1; 756b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o } 757b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o count -= ret; 758b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o buf += ret; 759b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o c += ret; 760b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o } 761b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o return c; 762b0258cbcd89862b927707258c67f2eeac769adc2Theodore Ts'o} 763e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 764e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid dump_mmp_msg(struct mmp_struct *mmp, const char *msg) 765e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 766e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 767e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (msg) 768e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall printf("MMP check failed: %s\n", msg); 769e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (mmp) { 770e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall time_t t = mmp->mmp_time; 771e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 772e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall printf("MMP error info: last update: %s node: %s device: %s\n", 773e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ctime(&t), mmp->mmp_nodename, mmp->mmp_bdevname); 774e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 775e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 776e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 777e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t e2fsck_mmp_update(ext2_filsys fs) 778e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 779e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 780e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 781e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_mmp_update(fs); 782e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval == EXT2_ET_MMP_CHANGE_ABORT) 783e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall dump_mmp_msg(fs->mmp_cmp, 784e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall _("UNEXPECTED INCONSISTENCY: the filesystem is " 785e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "being modified while fsck is running.\n")); 786e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 787e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return retval; 788e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 789e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 790e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallvoid e2fsck_set_bitmap_type(ext2_filsys fs, unsigned int default_type, 791e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *profile_name, unsigned int *old_type) 792e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 793e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned type; 794e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 795e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (old_type) 796e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *old_type = fs->default_bitmap_type; 797e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#ifdef HAVE_SIGNAL_H 798e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall profile_get_uint(e2fsck_global_ctx->profile, "bitmaps", 799e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall profile_name, 0, default_type, &type); 800e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall profile_get_uint(e2fsck_global_ctx->profile, "bitmaps", 801e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall "all", 0, type, &type); 802e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->default_bitmap_type = type ? type : default_type; 803e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#else 804e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->default_bitmap_type = default_type; 805e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 806e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 807e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 808e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t e2fsck_allocate_inode_bitmap(ext2_filsys fs, const char *descr, 809e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int deftype, 810e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *name, 811e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_inode_bitmap *ret) 812e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 813e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 814e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned int save_type; 815e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 816e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall e2fsck_set_bitmap_type(fs, deftype, name, &save_type); 817e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_allocate_inode_bitmap(fs, descr, ret); 818e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->default_bitmap_type = save_type; 819e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return retval; 820e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 821e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 822e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t e2fsck_allocate_block_bitmap(ext2_filsys fs, const char *descr, 823e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int deftype, 824e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *name, 825e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_block_bitmap *ret) 826e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 827e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 828e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned int save_type; 829e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 830e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall e2fsck_set_bitmap_type(fs, deftype, name, &save_type); 831e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_allocate_block_bitmap(fs, descr, ret); 832e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->default_bitmap_type = save_type; 833e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return retval; 834e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 835e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 836e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t e2fsck_allocate_subcluster_bitmap(ext2_filsys fs, const char *descr, 837e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int deftype, 838e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *name, 839e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_block_bitmap *ret) 840e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 841e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 842e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned int save_type; 843e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 844e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall e2fsck_set_bitmap_type(fs, deftype, name, &save_type); 845e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_allocate_subcluster_bitmap(fs, descr, ret); 846e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->default_bitmap_type = save_type; 847e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return retval; 848e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 849