diff --git a/CREDITS b/CREDITS index a24c3d0..66c5d36 100644 --- a/CREDITS +++ b/CREDITS @@ -1,5 +1,5 @@ /* - Copyright 1996-2003 by Hans Reiser, licensing governed by + Copyright 1996-2004 by Hans Reiser, licensing governed by reiserfsprogs/README. */ @@ -50,7 +50,7 @@ developing libreiser4 and userspace plugins with Umka. Yury Umanets (aka Umka) developed libreiser4, userspace plugins, and all userspace tools (reiser4progs) except of fsck. - + Joshua Macdonald wrote the first draft of the transaction manager. Yuri Rupasov did testing and benchmarking, plus he invented the r5 hash (also used by the dcache code). Yura Rupasov, Anatoly Pinchuk, Igor Krasheninnikov, Grigory diff --git a/ChangeLog b/ChangeLog index 20e4d8b..9b5845b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,59 @@ +2004-02-17 + 3.6.13 release. +2004-02-13 + reiserfsprogs + a few bugs were fixed in the mount entry detection code. + 3.6.13-pre1 release. +2004-02-06 + 3.6.12 release. +2004-01-26 + 3.6.12-pre3 release. +2004-01-21 + A few bugs were fixed: + *reiserfsck + - break from the pass2 loop correctly; + *resizer + - calculate the new fs size correctly; + - parse new size parameters correctly; + - checks for the new fs size are fixed; +2004-01-15 + *reiserfsprogs + UUID support is rewritten -- link to libuuid instead of + our own UUID support. +2004-01-12 + *reiserfsprogs + A fix for mount entry detection. +2003-12-17 + *reiserfsck + A bug in rebuild-sb was fixed. +2003-11-24 + *reiserfsck + Reboot is needed (0x2) return code was added. +2003-10-03 + *reiserfs_resizer + Some checks before shrinking are added avoiding segfault in + some cases. +2003-09-29 + *reiserfsprogs + bad block support is enabled and fixed. +2003-09-23 + *reiserfsprogs + fix for counting block number on block devices with block + size greater then 4k. +2003-09-18 + *reiserfsck + ro mounted filesystems are allowed to be checked. +2003-08-22i + *reiserfsck + fix for the journal of the minimal size +2003-08-01 + *reiserfsprogs + 3.6.11 release. +2003-07-30 + *reiserfsck + 2 bugs were fixed: + - 64bit architecture related; + - object attributes related. 2003-07-16 *reiserfsprogs Credits were changed. diff --git a/Makefile.am b/Makefile.am index f6b0759..bcb518d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = include lib reiserfscore fsck debugreiserfs resize_reiserfs mkreiserfs tune tests +SUBDIRS = include lib reiserfscore fsck debugreiserfs resize_reiserfs mkreiserfs tune noinst_DATA = reiserfsprogs.spec diff --git a/Makefile.in b/Makefile.in index ede2b8a..214770e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ @@ -104,7 +105,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -SUBDIRS = include lib reiserfscore fsck debugreiserfs resize_reiserfs mkreiserfs tune tests +SUBDIRS = include lib reiserfscore fsck debugreiserfs resize_reiserfs mkreiserfs tune noinst_DATA = reiserfsprogs.spec diff --git a/configure b/configure index abd1644..aca5f06 100755 --- a/configure +++ b/configure @@ -308,7 +308,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB CPP EGREP LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB UUID_LIBS CPP EGREP LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1261,6 +1261,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + @@ -1528,7 +1531,7 @@ fi # Define the identity of the package. PACKAGE=reiserfsprogs - VERSION=3.6.9 + VERSION=3.6.13 cat >>confdefs.h <<_ACEOF @@ -2770,6 +2773,77 @@ fi +# Check for LIBUUID + + +echo "$as_me:$LINENO: checking for uuid_generate in -luuid" >&5 +echo $ECHO_N "checking for uuid_generate in -luuid... $ECHO_C" >&6 +if test "${ac_cv_lib_uuid_uuid_generate+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char uuid_generate (); +int +main () +{ +uuid_generate (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_uuid_uuid_generate=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_uuid_uuid_generate=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_uuid_uuid_generate" >&5 +echo "${ECHO_T}$ac_cv_lib_uuid_uuid_generate" >&6 +if test $ac_cv_lib_uuid_uuid_generate = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUUID 1 +_ACEOF + + LIBS="-luuid $LIBS" + +else + { echo "$as_me:$LINENO: WARNING: libuuid could not be found" >&5 +echo "$as_me: WARNING: libuuid could not be found" >&2;} +fi + +UUID_LIBS="$LIBS" + ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -3249,7 +3323,8 @@ done -for ac_header in fcntl.h limits.h malloc.h sys/ioctl.h unistd.h + +for ac_header in fcntl.h limits.h malloc.h sys/ioctl.h unistd.h uuid/uuid.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then @@ -4252,11 +4327,8 @@ echo "$as_me:$LINENO: checking for CREDITS" >&5 echo $ECHO_N "checking for CREDITS... $ECHO_C" >&6 if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + echo $ac_n "cross compiling; assumed OK... $ac_c" + else cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" @@ -4266,7 +4338,6 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#define _GNU_SOURSE #include #include #include @@ -4309,7 +4380,7 @@ int main (void) { count++; } else { if (!start) - fprintf(fout, "\t\\\" "\n"); + fprintf(fout, "\\t\\\\\\n"); else if (start == 1) fprintf(fout, ",\n\n"); @@ -4355,8 +4426,7 @@ fi rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi - - ac_config_files="$ac_config_files include/Makefile mkreiserfs/Makefile resize_reiserfs/Makefile fsck/Makefile lib/Makefile Makefile reiserfscore/Makefile debugreiserfs/Makefile tune/Makefile tests/Makefile tests/PROGS/Makefile" + ac_config_files="$ac_config_files include/Makefile mkreiserfs/Makefile resize_reiserfs/Makefile fsck/Makefile lib/Makefile Makefile reiserfscore/Makefile debugreiserfs/Makefile tune/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -4914,8 +4984,6 @@ do "reiserfscore/Makefile" ) CONFIG_FILES="$CONFIG_FILES reiserfscore/Makefile" ;; "debugreiserfs/Makefile" ) CONFIG_FILES="$CONFIG_FILES debugreiserfs/Makefile" ;; "tune/Makefile" ) CONFIG_FILES="$CONFIG_FILES tune/Makefile" ;; - "tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; - "tests/PROGS/Makefile" ) CONFIG_FILES="$CONFIG_FILES tests/PROGS/Makefile" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 @@ -5039,6 +5107,7 @@ s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t s,@RANLIB@,$RANLIB,;t t s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@UUID_LIBS@,$UUID_LIBS,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@LIBOBJS@,$LIBOBJS,;t t @@ -5663,3 +5732,6 @@ if test "$no_create" != yes; then $ac_cs_success || { (exit 1); exit 1; } fi + +echo +echo Type \'make\' to compile reiserfsprogs diff --git a/configure.in b/configure.in index c91ad6c..3d60c03 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,9 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(version.h) -AM_INIT_AUTOMAKE(reiserfsprogs, 3.6.9) +AH_TEMPLATE([HAVE_LIBUUID], [Define for enable libuuid using.]) + +AM_INIT_AUTOMAKE(reiserfsprogs, 3.6.13) dnl We install in /sbin, the utils are to be available on boot dnl AC_PREFIX(/) @@ -24,9 +26,14 @@ dnl AC_PROG_LN_S dnl Checks for libraries. +# Check for LIBUUID +AC_CHECK_LIB(uuid, uuid_generate, , AC_MSG_WARN(libuuid could not be found)) +UUID_LIBS="$LIBS" +AC_SUBST(UUID_LIBS) + dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h unistd.h) +AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h unistd.h uuid/uuid.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -56,7 +63,6 @@ AC_DEFUN(AC_PREPARE_CREDITS, AC_MSG_CHECKING(for CREDITS) AC_TRY_RUN([ -#define _GNU_SOURSE #include #include #include @@ -99,7 +105,7 @@ int main (void) { count++; } else { if (!start) - fprintf(fout, "\t\\\" "\n"); + fprintf(fout, "\\t\\\\\\n"); else if (start == 1) fprintf(fout, ",\n\n"); @@ -118,8 +124,9 @@ int main (void) { return 0; } -], AC_MSG_RESULT(yes), AC_MSG_RESULT(no) ; exit) -]) +], AC_MSG_RESULT(yes), AC_MSG_RESULT(no) ; exit, + [echo $ac_n "cross compiling; assumed OK... $ac_c"] +)]) AC_PREPARE_CREDITS() @@ -132,6 +139,7 @@ AC_OUTPUT( Makefile reiserfscore/Makefile debugreiserfs/Makefile - tune/Makefile - tests/Makefile - tests/PROGS/Makefile) + tune/Makefile) + +echo +echo Type \'make\' to compile reiserfsprogs diff --git a/debugreiserfs/Makefile.in b/debugreiserfs/Makefile.in index 823dd31..50037fa 100644 --- a/debugreiserfs/Makefile.in +++ b/debugreiserfs/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/debugreiserfs/corruption.c b/debugreiserfs/corruption.c index d6da7f5..981cde6 100644 --- a/debugreiserfs/corruption.c +++ b/debugreiserfs/corruption.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -621,8 +621,8 @@ void do_one_corruption_in_one_block (reiserfs_filsys_t * fs, int do_one_ih_corrupt (struct item_head * ih, unsigned int nr_bytes) { if (nr_bytes > IH_SIZE) { - printf ("Bad byte number %u expected not more then %d\n", nr_bytes, - IH_SIZE); + printf ("Bad byte number %u expected not more then %lu\n", nr_bytes, + (unsigned long)IH_SIZE); exit (1); } @@ -662,10 +662,13 @@ int do_one_ih_random_corrupt (struct item_head * ih) } /* Corrupt n bytes in block header */ -int corrupt_block_header (struct block_head * blkh, unsigned int offset, unsigned int bytes ) +int corrupt_block_header (struct block_head * blkh, unsigned int offset, + unsigned int bytes) { if ((offset + bytes) > BLKH_SIZE) { - printf ("Bad offset number: %u or bad bytes number: %u, the suumary value expected not more then %d\n", offset, bytes, BLKH_SIZE ); + printf ("Bad offset number: %u or bad bytes number: %u, the suumary " + "value expected not more then %lu\n", offset, bytes, + (unsigned long)BLKH_SIZE); exit (1); } @@ -685,7 +688,7 @@ void do_one_blkh_random_corrupt (struct buffer_head * bh) struct block_head * blkh; unsigned int from; unsigned int count; - int i; + unsigned int i; from = get_rand (0, BLKH_SIZE - 1); count = get_rand (1, BLKH_SIZE); @@ -777,7 +780,7 @@ void do_one_block_random_corrupt (struct buffer_head * bh) { unsigned int from = get_rand (0, bh->b_size - 1); unsigned int count = get_rand (1, bh->b_size); - int i; + unsigned int i; if (from + count > bh->b_size) count = bh->b_size - from; @@ -798,11 +801,11 @@ void do_one_block_random_corrupt (struct buffer_head * bh) void do_bitmap_corruption (reiserfs_filsys_t * fs) { - unsigned long first = fs->fs_super_bh->b_blocknr + 1; + unsigned long first = fs->fs_super_bh->b_blocknr + 1; unsigned long nr_bitmap_to_corrupt; unsigned long block; - struct buffer_head * bh; - int i; + struct buffer_head * bh; + unsigned int i; nr_bitmap_to_corrupt = (unsigned long)get_rand (1, get_sb_bmap_nr (fs->fs_ondisk_sb) - 1); @@ -834,7 +837,7 @@ void do_ih_random_corrupt (reiserfs_filsys_t * fs, unsigned long nr_leaves_cr) { unsigned int nr_ih_cr; - int i, j; + unsigned int i, j; struct buffer_head * bh; struct item_head * ih; unsigned long nr_leaves = 0; @@ -941,7 +944,7 @@ void do_dir_random_corrupt (reiserfs_filsys_t * fs, unsigned long nr_leaves_cr) { unsigned int nr_ih_cr; - int i, j; + unsigned int i, j; struct buffer_head * bh; struct item_head * ih; unsigned long nr_leaves = 0; @@ -1022,7 +1025,7 @@ void do_sd_random_corrupt (reiserfs_filsys_t * fs, unsigned long nr_leaves_cr) { unsigned int nr_ih_cr; - int i, j; + unsigned int i, j; struct buffer_head * bh; struct item_head * ih; unsigned long nr_leaves = 0; @@ -1103,7 +1106,7 @@ void do_ind_random_corrupt (reiserfs_filsys_t * fs, unsigned long nr_leaves_cr) { unsigned int nr_ih_cr; - int i, j; + unsigned int i, j; struct buffer_head * bh; struct item_head * ih; unsigned long nr_leaves = 0; diff --git a/debugreiserfs/debugreiserfs.8 b/debugreiserfs/debugreiserfs.8 index b3c981a..fe8da4f 100644 --- a/debugreiserfs/debugreiserfs.8 +++ b/debugreiserfs/debugreiserfs.8 @@ -1,9 +1,9 @@ .\" -*- nroff -*- -.\" Copyright 1996-2003 Hans Reiser. +.\" Copyright 1996-2004 Hans Reiser. .\" -.TH DEBUGREISERFS 8 "April 2003" "Reiserfsprogs 3.6.9" +.TH DEBUGREISERFS 8 "February 2004" "Reiserfsprogs 3.6.13" .SH NAME -debugreiserfs +debugreiserfs \- debugging tool for the ReiserFS filesystem .SH SYNOPSIS .B debugreiserfs [ @@ -11,7 +11,9 @@ debugreiserfs ] [ .B -j \fIdevice ] [ -.B -B \fIblocknumber +.B -B \fIfile +] [ +.B -1 \fIN ] .\" ] [ @@ -47,6 +49,9 @@ print contents of bitmap (not very useful) .B -o print objectid map (not very useful) .TP +\fB-B\fR \fIfile\fR +extract the filesystem list of bad blocks to the specified file. +.TP \fB-1\fR \fIblocknumber\fR print specified block of the filesystem .TP diff --git a/debugreiserfs/debugreiserfs.c b/debugreiserfs/debugreiserfs.c index 2034747..a1da13a 100644 --- a/debugreiserfs/debugreiserfs.c +++ b/debugreiserfs/debugreiserfs.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -12,6 +12,7 @@ fprintf (stderr, "Usage: %s [options] device\n\n\ Options:\n\ -d\t\tprint blocks details of the internal tree\n\ -D\t\tprint blocks details of all used blocks\n\ + -B file\textract list of badblocks\n\ -m\t\tprint bitmap blocks\n\ -o\t\tprint objectid map\n\n\ -J\t\tprint journal header\n\ @@ -19,12 +20,12 @@ Options:\n\ -p\t\tsend filesystem metadata to stdout\n\ -S\t\thandle all blocks, not only used\n\ -1 block\tblock to print\n\ - -q\t\tno speed info (for -p, -s and -n)\n\n", argv[0]);\ + -q\t\tno speed info (for -p, -s and -n)\n\ + -V\t\tprint version and exit\n\n", argv[0]);\ exit (16);\ } /* - -B file\textract list of badblocks\n\ Undocumented options: -a map_file\n\tstore to the file the map of file. Is used with -n, -N, -r, -f\n @@ -55,7 +56,7 @@ struct reiserfs_fsstat { static void print_disk_tree (reiserfs_filsys_t * fs, unsigned long block_nr) { struct buffer_head * bh; - int i, count; + int i, j, count; static int level = -1; if (level == -1) @@ -94,9 +95,18 @@ static void print_disk_tree (reiserfs_filsys_t * fs, unsigned long block_nr) ih = B_N_PITEM_HEAD (bh, 0); count = leaf_item_number_estimate(bh); - for (i = 0; i <= count; i++, ih++) { - if (is_indirect_ih(ih)) - g_stat_info.nr_unformatted += I_UNFM_NUM(ih); + for (i = 0; i < count; i++, ih++) { + if (is_indirect_ih(ih)) { + __u32 * ind_item = (__u32 *)B_I_PITEM (bh, ih); + __u32 unfm_ptr; + + for (j = 0; j < (int)I_UNFM_NUM (ih); j ++) { + unfm_ptr = le32_to_cpu (ind_item [j]); + if (unfm_ptr) { + g_stat_info.nr_unformatted += 1; + } + } + } } } else { print_block (stdout, fs, bh, data (fs)->options & PRINT_TREE_DETAILS, -1, -1); @@ -202,6 +212,7 @@ static void print_one_block (reiserfs_filsys_t * fs, unsigned long block) char * where_to_save; char * badblocks_file; char * corruption_list_file; +char *program_name; static char * parse_options (struct debugreiserfs_data * data, int argc, char * argv []) { @@ -210,8 +221,15 @@ static char * parse_options (struct debugreiserfs_data * data, int argc, char * data->scan_area = USED_BLOCKS; data->mode = DO_DUMP; + + program_name = strrchr( argv[ 0 ], '/' ); + + if (program_name) + program_name++; + else + program_name = argv[ 0 ]; - while ((c = getopt (argc, argv, "a:b:C:F:SU1:psn:Nfr:dDomj:J:qtZl:L")) != EOF) { + while ((c = getopt (argc, argv, "a:b:C:F:SU1:psn:Nfr:dDomj:JqtZl:LVB:")) != EOF) { switch (c) { case 'a': /* -r will read this, -n and -N will write to it */ asprintf (&data->map_file, "%s", optarg); @@ -314,7 +332,6 @@ static char * parse_options (struct debugreiserfs_data * data, int argc, char * case 'J': data->options |= PRINT_JOURNAL_HEADER; - data->journal_device_name = optarg; break; case 'R': /* read block numbers from stdin and look for them in the @@ -346,13 +363,23 @@ static char * parse_options (struct debugreiserfs_data * data, int argc, char * /* random fs corruption */ data->mode = DO_RANDOM_CORRUPTION; break; + case 'V': + data->mode = DO_NOTHING; + break; } } + if (data->mode == DO_NOTHING) { + print_banner(program_name); + exit(0); + } + if (optind != argc - 1) /* only one non-option argument is permitted */ print_usage_and_exit(); - + + print_banner(program_name); + data->device_name = argv[optind]; return argv[optind]; } @@ -473,74 +500,49 @@ static void do_dump_tree (reiserfs_filsys_t * fs) init_bitmap (fs); if (data (fs)->options & PRINT_DETAILS || data (fs)->options & PRINT_TREE_DETAILS) { - if (data (fs)->options & PRINT_DETAILS) + if (data (fs)->options & PRINT_DETAILS) { print_disk_blocks (fs); - else + printf("The '%s' device with reiserfs has:\n", fs->fs_file_name); + } else { print_disk_tree (fs, get_sb_root_block (fs->fs_ondisk_sb)); + printf("The internal reiserfs tree has:\n"); + } /* print the statistic */ - printf ("File system uses %d internal + %d leaves + %d unformatted nodes = %d blocks\n", - g_stat_info.nr_internals, g_stat_info.nr_leaves, g_stat_info.nr_unformatted, - g_stat_info.nr_internals + g_stat_info.nr_leaves + g_stat_info.nr_unformatted); + printf ("\t%d internal + %d leaves + %d unformatted nodes = %d blocks\n", + g_stat_info.nr_internals, g_stat_info.nr_leaves, g_stat_info.nr_unformatted, + g_stat_info.nr_internals + g_stat_info.nr_leaves + g_stat_info.nr_unformatted); } } -void extract_badblock_list () +static void callback_badblock_print(reiserfs_filsys_t *fs, + struct path *badblock_path, + void *data) { - FILE * fd; - struct key badblock_key = {-1, -1, {{0, 0}}}; - struct key * rdkey; - struct path badblock_path; - struct item_head * tmp_ih; - __u32 i; - __u32 * ind_item; + struct item_head *tmp_ih; + FILE *fd = (FILE *)data; + __u32 *ind_item; + __u32 i; + tmp_ih = get_ih(badblock_path); + ind_item = (__u32 *)get_item(badblock_path); - fd = fopen (badblocks_file, "w"); - - if (fd == NULL) { + for (i = 0; i < I_UNFM_NUM(tmp_ih); i++, ind_item++) + fprintf (fd, "%u\n", le32_to_cpu (*ind_item)); + + pathrelse (badblock_path); +} + +void extract_badblock_list () { + FILE *fd; + + if (!(fd = fopen (badblocks_file, "w"))) { reiserfs_warning (stderr, "debugreiserfs: could not open badblock file %s\n", - badblocks_file); + badblocks_file); exit (1); } - - badblock_path.path_length = ILLEGAL_PATH_ELEMENT_OFFSET; - - set_type_and_offset (KEY_FORMAT_2, &badblock_key, 1, TYPE_INDIRECT); - - while (1) { - reiserfs_search_by_key_4 (fs, &badblock_key, &badblock_path); - - if (get_blkh_nr_items ( B_BLK_HEAD (get_bh(&badblock_path))) <= PATH_LAST_POSITION (&badblock_path)) { - break; - } - - tmp_ih = get_ih(&badblock_path); - - if (get_key_dirid(&tmp_ih->ih_key) != (__u32)-1 || - get_key_objectid(&tmp_ih->ih_key) != (__u32)-1) { - break; - } - - /* even if offset or type are corrupted it could be a badblock list */ - if (!is_indirect_ih (tmp_ih)) { - reiserfs_warning (stderr, "$s: a badblock item which was found has a wrong type.\n" - " It probable contains not correct bad block list, check it.\n", __FUNCTION__); - } - - ind_item = (__u32 *)B_I_PITEM (get_bh (&badblock_path), tmp_ih); - for (i = 0; i < get_ih_item_len (tmp_ih) / UNFM_P_SIZE; i++, ind_item++) - fprintf (fd, "%u\n", le32_to_cpu (*ind_item)); - - if ((rdkey = get_next_key_2 (&badblock_path)) == NULL) - break; - else - badblock_key = *rdkey; - - pathrelse (&badblock_path); - } - - pathrelse (&badblock_path); + + badblock_list(fs, callback_badblock_print, fd); fclose (fd); } @@ -634,8 +636,6 @@ int main (int argc, char * argv[]) int error; struct debugreiserfs_data * data; - print_banner ("debugreiserfs"); - data = getmem (sizeof (struct debugreiserfs_data)); file_name = parse_options (data, argc, argv); @@ -649,7 +649,6 @@ int main (int argc, char * argv[]) if (reiserfs_open_journal (fs, data (fs)->journal_device_name, O_RDONLY)) { fprintf(stderr, "\ndebugreiserfs: Failed to open the fs journal.\n"); - exit(1); } switch (debug_mode (fs)) { @@ -706,8 +705,10 @@ int main (int argc, char * argv[]) /*do_test (fs);*/ break; case DO_EXTRACT_BADBLOCKS: - reiserfs_warning (stderr, "Will try to extract list of bad blocks and save it to '%s' file\n", badblocks_file); - extract_badblock_list (); + reiserfs_warning (stderr, "Will try to extract list of bad blocks and " + "save it to '%s' file\n", badblocks_file); + + extract_badblock_list (); reiserfs_warning (stderr, "Done\n\n"); break; } diff --git a/debugreiserfs/debugreiserfs.h b/debugreiserfs/debugreiserfs.h index e7a9f2e..0b74e22 100644 --- a/debugreiserfs/debugreiserfs.h +++ b/debugreiserfs/debugreiserfs.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -33,7 +33,7 @@ extern reiserfs_filsys_t * fs; tree nodes */ #define DO_CORRUPT_ONE 2 /* used to make filesystem corruption and then test fsck */ #define DO_CORRUPT_FILE 3 /* used to make filesystem corruption and then test fsck, the list of corruption is set on the file */ -#define DO_RANDOM_CORRUPTION 4 +#define DO_RANDOM_CORRUPTION 4 #define DO_SCAN 5 #define DO_RECOVER 6 #define DO_TEST 7 @@ -45,7 +45,7 @@ extern reiserfs_filsys_t * fs; #define DO_EXTRACT_BADBLOCKS 13 #define DO_FILE_MAP 14 #define DO_ZERO_BITMAP 15 - +#define DO_NOTHING 16 /*first bits are in reiserfs_fs.b*/ diff --git a/debugreiserfs/pack.c b/debugreiserfs/pack.c index 48f2709..6e278b4 100644 --- a/debugreiserfs/pack.c +++ b/debugreiserfs/pack.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -407,7 +407,6 @@ static void pack_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh) return; } - /* start magic in low 8 bits, hash code in high 8 bits */ v16 = (LEAF_START_MAGIC | (func2code (fs->fs_hash_function) << 8)); fwrite_le16 (&v16); diff --git a/debugreiserfs/recover.c b/debugreiserfs/recover.c index 4ea48b4..2d35673 100644 --- a/debugreiserfs/recover.c +++ b/debugreiserfs/recover.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/debugreiserfs/scan.c b/debugreiserfs/scan.c index 18a253d..1a5f747 100644 --- a/debugreiserfs/scan.c +++ b/debugreiserfs/scan.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -819,9 +819,9 @@ static void scan_for_key (struct buffer_head * bh, struct key * key) i_num = leaf_item_number_estimate(bh); for (i = 0; i < i_num; i ++, ih ++) { if ((get_key_dirid(&ih->ih_key) == get_key_dirid(key) || - get_key_dirid(key) == ~0ul) && + get_key_dirid(key) == ~(__u32)0) && (get_key_objectid(&ih->ih_key) == get_key_objectid(key) || - get_key_objectid(key) == ~0ul)) + get_key_objectid(key) == ~(__u32)0)) { reiserfs_warning(log_to, "%d-th item of block %lu is item of file %K: %H\n", i, bh->b_blocknr, key, ih); diff --git a/debugreiserfs/stat.c b/debugreiserfs/stat.c index 1da15f1..5cbab4e 100644 --- a/debugreiserfs/stat.c +++ b/debugreiserfs/stat.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003 by Hans Reiser, licensing governed by + * Copyright 2002-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -205,8 +205,9 @@ void do_stat (reiserfs_filsys_t * fs) brelse (bh); } - reiserfs_warning (stderr, "\nThere were %lu leaves\n" - "\ttotal number of items %lu there\n" + reiserfs_warning (stderr, "\nThere were found on the '%s' device:\n" + "\tleaves %lu\n" + "\ttotal number of items %lu\n" "\tblocks containing at least one unique item %lu\n" "\tblocks which can be skipped %lu\n" "\t\tstat data %lu\n" @@ -220,6 +221,7 @@ void do_stat (reiserfs_filsys_t * fs) "other items %lu\n" "blocks containing only 1 dir item %lu\n", */ + fs->fs_file_name, fs_stat.leaves, fs_stat.all, fs_stat.leaves - fs_stat.blocks_to_skip, diff --git a/debugreiserfs/unpack.c b/debugreiserfs/unpack.c index b8f85fa..d8d906c 100644 --- a/debugreiserfs/unpack.c +++ b/debugreiserfs/unpack.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -489,7 +489,8 @@ static void unpack_unformatted_bitmap (int dev, int blocksize) // read packed reiserfs partition metadata from stdin void unpack_partition (int fd, int jfd) { - __u32 magic32, position; + __u32 magic32; + long position; __u16 magic16; __u16 blocksize; int dev = fd; @@ -567,7 +568,7 @@ void unpack_partition (int fd, int jfd) default: position = ftell(stdin); - if (position == ~0ul) + if (position == ~(long)0) die ("unpack_partition: bad magic found - %x", magic16 & 0xff); else die ("unpack_partition: bad magic found - %x, position %lu", @@ -615,7 +616,7 @@ int main (int argc, char ** argv) /* only one non-option argument is permitted */ print_usage_and_exit(); - if (is_mounted (argv[optind])) + if (misc_device_mounted(argv[optind]) > 0) reiserfs_panic ("%s seems mounted, umount it first\n", argv[optind]); fd = open (argv[optind], O_RDWR | O_LARGEFILE); diff --git a/fsck/Makefile.am b/fsck/Makefile.am index b93c8ae..fcf73fe 100644 --- a/fsck/Makefile.am +++ b/fsck/Makefile.am @@ -7,5 +7,5 @@ ufile.c check_tree.c info.c super.c fsck.h man_MANS = reiserfsck.8 EXTRA_DIST = $(man_MANS) -LDADD = $(LDFLAGS) $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a +reiserfsck_LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a diff --git a/fsck/Makefile.in b/fsck/Makefile.in index 5476496..e97c663 100644 --- a/fsck/Makefile.in +++ b/fsck/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ @@ -114,7 +115,7 @@ ufile.c check_tree.c info.c super.c fsck.h man_MANS = reiserfsck.8 EXTRA_DIST = $(man_MANS) -LDADD = $(LDFLAGS) $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a +reiserfsck_LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a subdir = fsck mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/include/config.h @@ -129,7 +130,6 @@ am_reiserfsck_OBJECTS = main.$(OBJEXT) pass0.$(OBJEXT) pass1.$(OBJEXT) \ ufile.$(OBJEXT) check_tree.$(OBJEXT) info.$(OBJEXT) \ super.$(OBJEXT) reiserfsck_OBJECTS = $(am_reiserfsck_OBJECTS) -reiserfsck_LDADD = $(LDADD) reiserfsck_DEPENDENCIES = $(top_srcdir)/lib/libmisc.a \ $(top_srcdir)/reiserfscore/libcore.a reiserfsck_LDFLAGS = diff --git a/fsck/check_tree.c b/fsck/check_tree.c index 44d5709..9688968 100644 --- a/fsck/check_tree.c +++ b/fsck/check_tree.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2003 by Hans Reiser, licensing governed by + * Copyright 1999-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -141,17 +141,19 @@ static void init_control_bitmap (reiserfs_filsys_t * fs) unsigned long reserved; - control_bitmap = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); + control_bitmap = reiserfs_create_bitmap(get_sb_block_count(fs->fs_ondisk_sb)); if (!control_bitmap) die ("init_control_bitmap: Failed to allocate a control bitmap."); - /*printf ("Initially number of zeros in control bitmap %d\n", reiserfs_bitmap_zeros (control_bitmap));*/ + /*printf ("Initially number of zeros in control bitmap %d\n", + reiserfs_bitmap_zeros (control_bitmap));*/ /* skipped and super block */ for (i = 0; i <= fs->fs_super_bh->b_blocknr; i ++) we_met_it (i); - /*printf ("SKIPPED: %d blocks marked used (%d)\n", hits, reiserfs_bitmap_zeros (control_bitmap)); + /*printf ("SKIPPED: %d blocks marked used (%d)\n", hits, + reiserfs_bitmap_zeros (control_bitmap)); hits = 0;*/ /* bitmaps */ @@ -160,11 +162,15 @@ static void init_control_bitmap (reiserfs_filsys_t * fs) we_met_it (block); if (spread_bitmaps (fs)) - block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); + block = (block / (fs->fs_blocksize * 8) + 1) * + (fs->fs_blocksize * 8); else block ++; } - /*printf ("BITMAPS: %d blocks marked used (%d)\n", hits, reiserfs_bitmap_zeros (control_bitmap)); + + /*printf ("BITMAPS: %d blocks marked used (%d)\n", hits, + reiserfs_bitmap_zeros (control_bitmap)); + hits = 0;*/ /* mark as used area of the main device either containing a journal or @@ -176,7 +182,8 @@ static void init_control_bitmap (reiserfs_filsys_t * fs) if (!is_new_sb_location (fs->fs_super_bh->b_blocknr, fs->fs_blocksize) && !is_old_sb_location (fs->fs_super_bh->b_blocknr, fs->fs_blocksize)) - die ("init_control_bitmap: Wrong super block location. You must run --rebuild-sb."); + die ("init_control_bitmap: Wrong super block location. You must run " + "--rebuild-sb."); block = get_journal_start_must (fs); @@ -199,16 +206,20 @@ static void handle_bitmaps (reiserfs_filsys_t * fs) int problem = 0; if (tree_scanning_failed) { - fsck_progress ("Could not scan the internal tree. --rebuild-tree is required\n"); + fsck_progress ("Could not scan the internal tree. --rebuild-tree " + "is required\n"); return; } fsck_progress ("Comparing bitmaps.."); /* check free block counter */ - if (get_sb_free_blocks (fs->fs_ondisk_sb) != reiserfs_bitmap_zeros (control_bitmap)) { -/* fsck_log ("vpf-10630: The count of free blocks in the on-disk bitmap (%lu) mismatches " - "with the correct one (%lu).\n", get_sb_free_blocks (fs->fs_ondisk_sb), + if (get_sb_free_blocks (fs->fs_ondisk_sb) != + reiserfs_bitmap_zeros (control_bitmap)) + { +/* fsck_log ("vpf-10630: The count of free blocks in the on-disk bitmap " + "(%lu) mismatches with the correct one (%lu).\n", + get_sb_free_blocks (fs->fs_ondisk_sb), reiserfs_bitmap_zeros (control_bitmap)); */ problem++; @@ -222,28 +233,34 @@ static void handle_bitmaps (reiserfs_filsys_t * fs) fsck_log ("vpf-10630: The on-disk and the correct bitmaps differs. " "Will be fixed later.\n"); // fsck_progress ("Trying to fix bitmap ..\n"); - /* mark blocks as used in source bitmap if they are used in control bitmap */ + /* mark blocks as used in source bitmap if they are used in + control bitmap */ reiserfs_bitmap_disjunction (source_bitmap, control_bitmap); - /* change used blocks count accordinly source bitmap, - copy bitmap changes to on_disk bitmap */ - set_sb_free_blocks (fs->fs_ondisk_sb, reiserfs_bitmap_zeros (source_bitmap)); + /* change used blocks count accordinly source bitmap, copy bitmap + changes to on_disk bitmap */ + set_sb_free_blocks (fs->fs_ondisk_sb, + reiserfs_bitmap_zeros(source_bitmap)); reiserfs_bitmap_copy (fs->fs_bitmap2, source_bitmap); mark_buffer_dirty (fs->fs_super_bh); /* // check again - if ((diff = reiserfs_bitmap_compare (source_bitmap, control_bitmap)) != 0) { - // do not mark them as fatal or fixable because one can live with leaked space. - // So this is not a fatal corruption, and fix-fixable cannot fix it - fsck_progress (" bitmaps were not recovered. \n" - "\tYou can either run rebuild-tree or live with %d leaked blocks\n", diff); + if ((diff = reiserfs_bitmap_compare(source_bitmap, + control_bitmap)) != 0) + { + // do not mark them as fatal or fixable because one can live + // with leaked space. So this is not a fatal corruption, and + // fix-fixable cannot fix it + fsck_progress (" bitmaps were not recovered.\n\tYou can either " + "run rebuild-tree or live with %d leaked blocks\n", diff); } else { fsck_progress ("finished\n"); } */ } else if (problem) { - fsck_log ("vpf-10640: The on-disk and the correct bitmaps differs.\n"); + fsck_log ("vpf-10640: The on-disk and the correct bitmaps differs.\n"); while (problem) { - /* fixable corruptions because we can try to recover them without rebuilding the tree */ + /* fixable corruptions because we can try to recover them + without rebuilding the tree */ one_more_corruption (fs, FIXABLE); problem --; } @@ -312,7 +329,9 @@ static int got_already (reiserfs_filsys_t * fs, unsigned long block) } /* 1 if it does not look like reasonable stat data */ -static int bad_stat_data (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih) +static int bad_stat_data (reiserfs_filsys_t * fs, + struct buffer_head * bh, + struct item_head * ih) { unsigned long objectid; // __u32 links; @@ -320,9 +339,9 @@ static int bad_stat_data (reiserfs_filsys_t * fs, struct buffer_head * bh, struc objectid = get_key_objectid (&ih->ih_key); if (!is_objectid_used (fs, objectid)) { /* FIXME: this could be cured right here */ - fsck_log ("bad_stat_data: The objectid (%lu) is marked free, but used by an object %k\n", - objectid, &ih->ih_key); - + fsck_log ("bad_stat_data: The objectid (%lu) is marked free, but used " + "by an object %k\n", objectid, &ih->ih_key); + /* if it is FIX_FIXABLE we flush objectid map at the end no way to call one_less_corruption later */ @@ -331,7 +350,9 @@ static int bad_stat_data (reiserfs_filsys_t * fs, struct buffer_head * bh, struc } if (id_map_mark(proper_id_map (fs), objectid)) { - fsck_log ("bad_stat_data: The objectid (%lu) is shared by at least two files\n", objectid); + fsck_log ("bad_stat_data: The objectid (%lu) is shared by at least two " + "files\n", objectid); + if (fsck_mode (fs) == FSCK_FIX_FIXABLE) to_be_relocated (&ih->ih_key); @@ -361,13 +382,18 @@ static int bad_stat_data (reiserfs_filsys_t * fs, struct buffer_head * bh, struc /* it looks like we can check item length only */ -static int bad_direct_item (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih) +static int bad_direct_item (reiserfs_filsys_t * fs, + struct buffer_head * bh, + struct item_head * ih) { return 0; } -inline void handle_one_pointer (reiserfs_filsys_t * fs, struct buffer_head * bh, __u32 * ptr) { +inline void handle_one_pointer (reiserfs_filsys_t * fs, + struct buffer_head * bh, + __u32 * ptr) +{ if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { fsck_log (" - zeroed"); *ptr = 0; @@ -377,31 +403,38 @@ inline void handle_one_pointer (reiserfs_filsys_t * fs, struct buffer_head * bh, } } -/* + static int bad_badblocks_item (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih) { - int i; + __u32 i; __u32 * ind = (__u32 *)B_I_PITEM (bh, ih); if (get_ih_item_len (ih) % 4) { fsck_log ("%s: block %lu: item (%H) has bad length\n", __FUNCTION__, bh->b_blocknr, ih); - one_more_corruption (fs, fatal); + one_more_corruption (fs, FATAL); return 1; } - + + /* All valid badblocks are given in badblock bitmap. Nothing to check anymore. */ + if (fs->fs_badblocks_bm) + return 0; + for (i = 0; i < I_UNFM_NUM (ih); i ++) { -// __u32 unfm_ptr; - -// unfm_ptr = le32_to_cpu (ind [i]); if (!le32_to_cpu (ind [i])) { - fsck_log ("%s: block %lu: badblocks item (%H) has zero pointer."); - fsck_log ("Not an error, but could be deleted with --fix-fixable\n", - __FUNCTION__, bh->b_blocknr, ih); +/* fsck_log ("%s: block %lu: badblocks item (%H) has zero pointer.", + __FUNCTION__, bh->b_blocknr, ih); + + if (fsck_mode(fs) != FSCK_FIX_FIXABLE) { + fsck_log("Not an error, but could be deleted with --fix-fixable\n"); + } else { + fsck_log("Will be deleted later.\n"); + }*/ + continue; } - // check list of badblocks pointers + /* check list of badblocks pointers */ if (le32_to_cpu (ind [i]) >= get_sb_block_count (fs->fs_ondisk_sb)) { fsck_log ("%s: badblock pointer (block %lu) points out of disk spase (%lu)", __FUNCTION__, bh->b_blocknr, le32_to_cpu (ind [i])); @@ -410,32 +443,34 @@ static int bad_badblocks_item (reiserfs_filsys_t * fs, struct buffer_head * bh, } if (did_we_meet_it (le32_to_cpu (ind [i]))) { - // it can be - // 1. not_data_block - // delete pointer - // 2. ind [i] or internal/leaf - // advice to run fix-fixable if there is no fatal errors - // with list of badblocks, say that it could fix it. + /* it can be + 1. not_data_block + delete pointer + 2. ind [i] or internal/leaf + advice to run fix-fixable if there is no fatal errors + with list of badblocks, say that it could fix it. */ if (not_data_block (fs, le32_to_cpu (ind [i]))) { fsck_log ("%s: badblock pointer (block %lu) points on fs metadata (%lu)", - __FUNCTION__, bh->b_blocknr, le32_to_cpu (ind [i])); + __FUNCTION__, bh->b_blocknr, le32_to_cpu (ind [i])); handle_one_pointer (fs, bh, &ind[i]); fsck_log ("\n"); } else { - one_more_corruption (fs, badblocks); - fsck_log ("%s: badblock item points to a block" - " which in the tree already. Use --badblock-file option" - " to fix the problem\n", __FUNCTION__); + one_more_corruption(fs, FIXABLE); + fsck_log ("%s: badblock pointer (block %lu) points to a block (%lu) " + "which is in the tree already. Use badblock option (-B) to" + " fix the problem\n", __FUNCTION__, bh->b_blocknr, + le32_to_cpu(ind[i])); } - } else { - we_met_it (le32_to_cpu (ind [i])); + + continue; } + + we_met_it(le32_to_cpu(ind[i])); } return 0; } -*/ /* for each unformatted node pointer: make sure it points to data area and that it is not in the tree yet */ @@ -465,16 +500,20 @@ static int bad_indirect_item (reiserfs_filsys_t * fs, struct buffer_head * bh, /* check unformatted node pointer and mark it used in the control bitmap */ if (bad_block_number (fs, le32_to_cpu (ind [i]))) { - fsck_log ("%s: block %lu: The item %k has the bad pointer (%d) to the block (%lu)", - __FUNCTION__, bh->b_blocknr, &ih->ih_key, i, le32_to_cpu (ind [i])); + fsck_log ("%s: block %lu: The item %k has the bad pointer (%d) to " + "the block (%lu)", __FUNCTION__, bh->b_blocknr, + &ih->ih_key, i, le32_to_cpu (ind [i])); + handle_one_pointer (fs, bh, &ind[i]); fsck_log ("\n"); continue; } if (got_already (fs, le32_to_cpu (ind [i]))) { - fsck_log ("%s: block %lu: The item (%H) has the bad pointer (%d) to the block (%lu), " - "which is in tree already", __FUNCTION__, bh->b_blocknr, ih, i, le32_to_cpu (ind [i])); + fsck_log ("%s: block %lu: The item (%H) has the bad pointer (%d) " + "to the block (%lu), which is in tree already", + __FUNCTION__, bh->b_blocknr, ih, i, le32_to_cpu(ind[i])); + handle_one_pointer (fs, bh, &ind [i]); fsck_log ("\n"); continue; @@ -498,7 +537,9 @@ static int bad_indirect_item (reiserfs_filsys_t * fs, struct buffer_head * bh, /* FIXME: this was is_bad_directory from pass0.c */ -static int bad_directory_item (reiserfs_filsys_t * fs, struct buffer_head * bh, struct item_head * ih) +static int bad_directory_item (reiserfs_filsys_t * fs, + struct buffer_head * bh, + struct item_head * ih) { char * name; int namelen; @@ -520,16 +561,20 @@ static int bad_directory_item (reiserfs_filsys_t * fs, struct buffer_head * bh, /* make sure item looks like a directory */ if (get_ih_item_len (ih) / (DEH_SIZE + min_entry_size) < count) { /* entry count can not be that big */ - fsck_log ("%s: block %lu: The directory item %k has the exsessively big entry count (%u)\n", - __FUNCTION__, bh->b_blocknr, &ih->ih_key, count); + fsck_log ("%s: block %lu: The directory item %k has the exsessively " + "big entry count (%u)\n", __FUNCTION__, bh->b_blocknr, + &ih->ih_key, count); + one_more_corruption (fs, FATAL); return 1; } if (get_deh_location (&deh[count - 1]) != DEH_SIZE * count) { /* last entry should start right after array of dir entry headers */ - fsck_log ("%s: block %lu: The directory item %k has the corrupted entry structure\n", - __FUNCTION__, bh->b_blocknr, &ih->ih_key); + fsck_log ("%s: block %lu: The directory item %k has the corrupted " + "entry structure\n", __FUNCTION__, bh->b_blocknr, + &ih->ih_key); + one_more_corruption (fs, FATAL); return 1; } @@ -539,8 +584,10 @@ static int bad_directory_item (reiserfs_filsys_t * fs, struct buffer_head * bh, namelen = name_in_entry_length (ih, deh, i); name = name_in_entry (deh, i); if (!is_properly_hashed (fs, name, namelen, get_deh_offset (deh))) { - fsck_log ("%s: block %lu: The directory item %k has a not properly hashed entry (%d)\n", - __FUNCTION__, bh->b_blocknr, &ih->ih_key, i); + fsck_log ("%s: block %lu: The directory item %k has a not properly " + "hashed entry (%d)\n", __FUNCTION__, bh->b_blocknr, + &ih->ih_key, i); + one_more_corruption (fs, FATAL); return 1; } @@ -551,10 +598,12 @@ static int bad_directory_item (reiserfs_filsys_t * fs, struct buffer_head * bh, /* ok, items looks like a directory */ for (i = 0; i < count; i ++, deh ++) { if (get_deh_state (deh) != state) { - fsck_log ("bad_directory_item: block %lu: The directory item %k has the entry (%d) " - "\"%.*s\" with a not legal state (%o), (%o) expected", - bh->b_blocknr, &ih->ih_key, i, name_in_entry_length (ih, deh, i), - name_in_entry (deh, i), get_deh_state (deh), state); + fsck_log ("bad_directory_item: block %lu: The directory item %k " + "has the entry (%d) \"%.*s\" with a not legal state " + "(%o), (%o) expected", bh->b_blocknr, &ih->ih_key, i, + name_in_entry_length (ih, deh, i), name_in_entry (deh, i), + get_deh_state (deh), state); + if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { set_deh_state (deh, 1 << DEH_Visible2); mark_buffer_dirty (bh); @@ -580,11 +629,12 @@ static int bad_item (reiserfs_filsys_t * fs, struct buffer_head * bh, int num) if ((get_ih_flags(ih)) != 0) { if (fsck_mode(fs) != FSCK_FIX_FIXABLE) { one_more_corruption (fs, FIXABLE); - fsck_log ("%s: vpf-10570: block %lu: The item header (%d) has not cleaned flags.\n", - __FUNCTION__, bh->b_blocknr, num); + fsck_log ("%s: vpf-10570: block %lu: The item header (%d) has not " + "cleaned flags.\n", __FUNCTION__, bh->b_blocknr, num); } else { - fsck_log ("%s: vpf-10580: block %lu: Flags in the item header (%d) were cleaned\n", - __FUNCTION__, bh->b_blocknr, num); + fsck_log ("%s: vpf-10580: block %lu: Flags in the item header " + "(%d) were cleaned\n", __FUNCTION__, bh->b_blocknr, num); + clean_ih_flags(ih); mark_buffer_dirty(bh); } @@ -601,72 +651,54 @@ static int bad_item (reiserfs_filsys_t * fs, struct buffer_head * bh, int num) if (format != get_ih_key_format(ih)) { if (fsck_mode(fs) != FSCK_FIX_FIXABLE) { one_more_corruption (fs, FIXABLE); - fsck_log ("%s: vpf-10710: block %lu: The format (%d) specified in the item header (%d) " - "differs from the key format (%d).\n", __FUNCTION__, bh->b_blocknr, - get_ih_key_format(ih), num, format); + fsck_log ("%s: vpf-10710: block %lu: The format (%d) specified " + "in the item header (%d) differs from the key format " + "(%d).\n", __FUNCTION__, bh->b_blocknr, + get_ih_key_format(ih), num, format); } else { - fsck_log ("%s: vpf-10720: block %lu: The format (%d) specified in the item header (%d) " - "was fixed to the key format (%d).\n", __FUNCTION__, bh->b_blocknr, - get_ih_key_format(ih), num, format); + fsck_log ("%s: vpf-10720: block %lu: The format (%d) specified in " + "the item header (%d) was fixed to the key format (%d).\n", + __FUNCTION__, bh->b_blocknr, get_ih_key_format(ih), num, + format); set_ih_key_format(ih, format); mark_buffer_dirty(bh); } } - if (get_key_dirid (&ih->ih_key) == (__u32)-1) { - if (get_key_objectid (&ih->ih_key) != (__u32)-1) { - /* safe link can be + if (get_key_objectid (&ih->ih_key) == BADBLOCK_OBJID) { + if (get_key_dirid (&ih->ih_key) == BADBLOCK_DIRID && is_indirect_ih (ih)) { + /* Bad Block support. */ + return bad_badblocks_item (fs, bh, ih); + } + + goto error; + } else { + if (get_key_dirid (&ih->ih_key) == (__u32)-1) { + /* Safe Link support. Allowable safe links are: -1 object_id 0x1 INDIRECT (truncate) or - -1 object_id blocksize+1 DIRECT (unlink) - */ + -1 object_id blocksize+1 DIRECT (unlink) */ + if (is_direct_ih(ih) && get_offset(&ih->ih_key) == fs->fs_blocksize + 1) { + if (get_ih_item_len (ih) == 4) { + /*fsck_log("vpf-00010: safe link found %k\n", &ih->ih_key);*/ + fsck_check_stat(fs)->safe ++; + return 0; + } + } - if (is_direct_ih(ih)) - if (get_offset(&ih->ih_key) == fs->fs_blocksize + 1) - if (get_ih_item_len (ih) == 4) { - /*fsck_log("vpf-00010: safe link found %k\n", &ih->ih_key);*/ - fsck_check_stat(fs)->safe ++; - return 0; - } - - if (is_indirect_ih(ih)) - if(get_offset(&ih->ih_key) == 0x1) - if (get_ih_item_len (ih) == 4) { - /*fsck_log("vpf-00020: safe link found %k\n", &ih->ih_key);*/ - fsck_check_stat(fs)->safe ++; - return 0; - } + if (is_indirect_ih(ih) && get_offset(&ih->ih_key) == 0x1) { + if (get_ih_item_len (ih) == 4) { + /*fsck_log("vpf-00020: safe link found %k\n", &ih->ih_key);*/ + fsck_check_stat(fs)->safe ++; + return 0; + } + } /* it does not look like safe link */ - - /* dir_id == -1 can be used only by safe links */ - one_more_corruption (fs, FATAL); - fsck_log ("%s: vpf-10290: block %lu, item %d: The item has a wrong key %k\n", - __FUNCTION__, num, bh->b_blocknr, &ih->ih_key); - return 1; - } else { - -/* BAD BLOCK LIST SUPPORT - if (is_indirect_ih (ih)) { - // it looks like badblocks item - if (fs->fs_badblocks_bm) - return 0; - else - return bad_badblocks_item (fs, bh, ih); - } else {*/ - - one_more_corruption (fs, FATAL); - fsck_log ("%s: vpf-10300: block %lu, item %d: The item has a wrong key %k\n", - __FUNCTION__, num, bh->b_blocknr, &ih->ih_key); - return 1; + goto error; } - } else if (get_key_objectid (&ih->ih_key) == (__u32)-1) { - one_more_corruption (fs, FATAL); - fsck_log ("%s: vpf-10310: block %lu, item %d: The item has a wrong key %k\n", - __FUNCTION__, num, bh->b_blocknr, &ih->ih_key); - return 1; } - + if (is_stat_data_ih (ih)) return bad_stat_data (fs, bh, ih); @@ -677,12 +709,17 @@ static int bad_item (reiserfs_filsys_t * fs, struct buffer_head * bh, int num) return bad_indirect_item (fs, bh, ih); return bad_directory_item (fs, bh, ih); + + error: + one_more_corruption (fs, FATAL); + fsck_log ("%s: vpf-10310: block %lu, item %d: The item has a wrong " + "key %k\n", __FUNCTION__, num, bh->b_blocknr, &ih->ih_key); + return 1; } /* 1 if i-th and (i-1)-th items can not be neighbors in a leaf */ -int bad_pair (reiserfs_filsys_t * fs, struct buffer_head * bh, int pos) -{ +int bad_pair (reiserfs_filsys_t * fs, struct buffer_head * bh, int pos) { struct item_head * ih; ih = B_N_PITEM_HEAD (bh, pos); @@ -701,15 +738,15 @@ int bad_pair (reiserfs_filsys_t * fs, struct buffer_head * bh, int pos) return 1; } - if (get_key_dirid (&ih->ih_key) == (__u32)-1) { - if (get_key_objectid (&ih->ih_key) == (__u32)-1) { -/* BAD BLOCK LIST SUPPORT - if (is_indirect_ih (ih) && comp_short_keys (&((ih - 1)->ih_key), &ih->ih_key) != 0) - return 0; // badblocks item -*/ - /* it does not look like badblocks item */ - } else { - /* safe link ? */ + if (get_key_objectid (&ih->ih_key) == BADBLOCK_OBJID) { + /* BAD BLOCK LIST SUPPORT. */ + if (get_key_dirid(&ih->ih_key) == BADBLOCK_DIRID && + is_indirect_ih(ih) && comp_short_keys(&((ih - 1)->ih_key), + &ih->ih_key)) + return 0; + } else { + /* Safe link support. */ + if (get_key_dirid (&ih->ih_key) == (__u32)-1) { if (comp_short_keys (&((ih - 1)->ih_key), &ih->ih_key) == 0) { if (is_indirect_ih (ih - 1) && is_direct_ih(ih)) return 0; /* safe link */ @@ -719,24 +756,25 @@ int bad_pair (reiserfs_filsys_t * fs, struct buffer_head * bh, int pos) return 0; /* safe link */ /* it does not look like safe link */ } - } + } } - + if (is_direct_ih(ih)) { - /* left item must be indirect or stat data item of the same - file */ + /* left item must be indirect or stat data item of the same file */ if (not_of_one_file (&((ih - 1)->ih_key), &ih->ih_key)) { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); + return 1; } if (!((is_stat_data_ih (ih - 1) && get_offset (&ih->ih_key) == 1) || - (is_indirect_ih (ih - 1) && - get_offset (&(ih - 1)->ih_key) + get_bytes_number (ih-1, bh->b_size) == - get_offset (&ih->ih_key)))) { + (is_indirect_ih (ih - 1) && get_offset (&(ih - 1)->ih_key) + + get_bytes_number (ih-1, bh->b_size) == get_offset (&ih->ih_key)))) + { if (fsck_mode (fs) != FSCK_REBUILD) one_more_corruption (fs, FATAL); + return 1; } } @@ -764,14 +802,15 @@ static int bad_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh) for (i = 0; i < B_NR_ITEMS (bh); i ++) { if (bad_item (fs, bh, i)) { - fsck_log ("bad_leaf: block %lu, item %d: The corrupted item found (%H)\n", - bh->b_blocknr, i, B_N_PITEM_HEAD (bh, i)); + fsck_log ("bad_leaf: block %lu, item %d: The corrupted item found " + "(%H)\n", bh->b_blocknr, i, B_N_PITEM_HEAD (bh, i)); } if (i && bad_pair (fs, bh, i)) { - fsck_log ("bad_leaf: block %lu, items %d and %d: The wrong order of items: %k, %k\n", - bh->b_blocknr, i-1, i, &B_N_PITEM_HEAD (bh, i-1)->ih_key, - &B_N_PITEM_HEAD (bh, i)->ih_key); + fsck_log ("bad_leaf: block %lu, items %d and %d: The wrong order " + "of items: %k, %k\n", bh->b_blocknr, i - 1, i, + &B_N_PITEM_HEAD (bh, i-1)->ih_key, + &B_N_PITEM_HEAD (bh, i)->ih_key); } } return 0; @@ -785,19 +824,24 @@ static int bad_internal (reiserfs_filsys_t * fs, struct buffer_head * bh) for (i = 0; i <= B_NR_ITEMS (bh); i ++) { if (i != B_NR_ITEMS (bh) && i != B_NR_ITEMS (bh) - 1) /* make sure that keys are in increasing order */ - if (comp_keys (B_N_PDELIM_KEY (bh, i), B_N_PDELIM_KEY (bh, i + 1)) != -1) { - fsck_log ("%s: vpf-10320: block %lu, items %d and %d: The wrong order " - "of items: %k, %k\n", __FUNCTION__, bh->b_blocknr, i, i+1, - B_N_PDELIM_KEY (bh, i), B_N_PDELIM_KEY (bh, i + 1)); + if (comp_keys (B_N_PDELIM_KEY (bh, i), + B_N_PDELIM_KEY (bh, i + 1)) != -1) + { + fsck_log ("%s: vpf-10320: block %lu, items %d and %d: The " + "wrong order of items: %k, %k\n", __FUNCTION__, + bh->b_blocknr, i, i + 1, B_N_PDELIM_KEY (bh, i), + B_N_PDELIM_KEY (bh, i + 1)); + one_more_corruption (fs, FATAL); return 1; } /* make sure that the child is correct */ if (bad_block_number (fs, get_dc_child_blocknr (B_N_CHILD (bh,i)))) { - fsck_log ("%s: vpf-10330: block %lu, item %d: The internal item points to the " - "not legal block (%lu)\n", __FUNCTION__, bh->b_blocknr, i, - get_dc_child_blocknr (B_N_CHILD (bh,i))); + fsck_log ("%s: vpf-10330: block %lu, item %d: The internal item " + "points to the not legal block (%lu)\n", __FUNCTION__, + bh->b_blocknr, i, get_dc_child_blocknr (B_N_CHILD (bh,i))); + one_more_corruption (fs, FATAL); return 1; } @@ -819,22 +863,24 @@ static int bad_node (reiserfs_filsys_t * fs, struct buffer_head ** path, int h) struct buffer_head ** pbh = &path[h]; if (B_LEVEL (*pbh) != h_to_level (fs, h)) { - fsck_log ("block %lu: The level of the node (%d) is not correct, (%d) expected\n", - (*pbh)->b_blocknr, B_LEVEL (*pbh), h_to_level (fs, h)); + fsck_log ("block %lu: The level of the node (%d) is not correct, " + "(%d) expected\n", (*pbh)->b_blocknr, B_LEVEL (*pbh), + h_to_level (fs, h)); + one_more_corruption (fs, FATAL); return 1; } if (bad_block_number (fs, (*pbh)->b_blocknr)) { one_more_corruption (fs, FATAL); - fsck_log ("%s: vpf-10340: The node in the wrong block number (%lu) found in the tree\n", - __FUNCTION__, (*pbh)->b_blocknr); + fsck_log ("%s: vpf-10340: The node in the wrong block number (%lu) " + "found in the tree\n", __FUNCTION__, (*pbh)->b_blocknr); return 1; } if (got_already (fs, (*pbh)->b_blocknr)) { - fsck_log ("%s: vpf-10350: The block (%lu) is used more than once in the tree.\n", - __FUNCTION__, (*pbh)->b_blocknr); + fsck_log ("%s: vpf-10350: The block (%lu) is used more than once " + "in the tree.\n", __FUNCTION__, (*pbh)->b_blocknr); one_more_corruption (fs, FATAL); return 1; } @@ -927,7 +973,7 @@ static int bad_path (reiserfs_filsys_t * fs, struct buffer_head ** path, int h1) dk = rkey (path, h); if (dk && comp_keys (dk, B_N_PKEY (path[h], get_blkh_nr_items (B_BLK_HEAD (path[h])) - 1)) != 1) { - /* right delimiting key must be greater than the key of the last item in the node */ + /* right delimiting key must be gt the key of the last item in the node */ fsck_log ("bad_path: The right delimiting key %k of the node (%lu) must " "be greater than the last (%d) element's key %k within the node.\n", dk, path[h]->b_blocknr, get_blkh_nr_items (B_BLK_HEAD (path[h])) - 1, @@ -950,8 +996,11 @@ static int bad_path (reiserfs_filsys_t * fs, struct buffer_head ** path, int h1) if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { set_dc_child_size (B_N_CHILD(path[h-1],pos), path[h]->b_size - - get_blkh_free_space ((struct block_head *)path[h]->b_data) - BLKH_SIZE); - fsck_log (" - corrected to (%lu)\n", get_dc_child_size (B_N_CHILD(path[h-1],pos))); + get_blkh_free_space ((struct block_head *)path[h]->b_data) + - BLKH_SIZE); + fsck_log (" - corrected to (%lu)\n", + get_dc_child_size (B_N_CHILD(path[h-1], pos))); + mark_buffer_dirty (path[h-1]); } else { one_more_corruption (fs, FIXABLE); @@ -1010,13 +1059,17 @@ void check_fs_tree (reiserfs_filsys_t * fs) after_check_fs_tree (fs); } -static int clean_attributes_handler (reiserfs_filsys_t * fs, struct buffer_head ** path, int h) { +static int clean_attributes_handler (reiserfs_filsys_t * fs, + struct buffer_head ** path, + int h) +{ struct buffer_head * bh = path[h]; int i; if (B_LEVEL (bh) != h_to_level (fs, h)) { - reiserfs_panic ("The node (%lu) with wrong level (%d) found in the tree, (%d) expected\n", - bh->b_blocknr, B_LEVEL (bh), h_to_level (fs, h)); + reiserfs_panic ("The node (%lu) with wrong level (%d) found in the " + "tree, (%d) expected\n", bh->b_blocknr, B_LEVEL (bh), + h_to_level (fs, h)); } if (!is_leaf_node (bh)) @@ -1038,5 +1091,3 @@ void do_clean_attributes (reiserfs_filsys_t * fs) { set_sb_v2_flag (fs->fs_ondisk_sb, reiserfs_attrs_cleared); mark_buffer_dirty (fs->fs_super_bh); } - - diff --git a/fsck/fsck.h b/fsck/fsck.h index b71b68c..bc7e79c 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -22,6 +22,8 @@ #include "misc.h" #include "reiserfs_lib.h" +#include "../include/config.h" +#include "../version.h" /* main.c */ extern reiserfs_filsys_t * fs; @@ -30,6 +32,7 @@ int main (int argc, char * argv []); /* Exit codes. */ #define EXIT_OK 0 #define EXIT_FIXED 1 +#define EXIT_REBOOT 2 #define EXIT_FATAL 4 #define EXIT_FIXABLE 6 #define EXIT_OPER 8 /* Some operation returns error. */ @@ -187,7 +190,6 @@ void pass_3a_look_for_lost (reiserfs_filsys_t *); void load_lost_found_result (reiserfs_filsys_t *); /* pass4.c */ -//void get_next_key (struct path * path, int i, struct key * key); void pass_4_check_unaccessed_items (void); /* check.c */ @@ -406,6 +408,7 @@ struct check_info { struct fsck_data { unsigned short mode; /* check, rebuild, etc*/ unsigned long options; + unsigned long mounted; struct rebuild_info rebuild; struct check_info check; diff --git a/fsck/info.c b/fsck/info.c index a82d9fa..d5621dd 100644 --- a/fsck/info.c +++ b/fsck/info.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/fsck/lost+found.c b/fsck/lost+found.c index 2b3fa34..dfafa23 100644 --- a/fsck/lost+found.c +++ b/fsck/lost+found.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/fsck/main.c b/fsck/main.c index a16d6b1..801a84e 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -1,14 +1,12 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ #include "fsck.h" #include #include - -#include "../include/config.h" -#include "../version.h" +#include extern int screen_width; extern int screen_savebuffer_len; @@ -18,7 +16,7 @@ reiserfs_filsys_t * fs; char * badblocks_file; #define print_usage_and_exit() { \ -fsck_progress ("\nUsage: %s [mode] [options] " \ +fsck_progress ("Usage: %s [mode] [options] " \ " device\n" \ "\n" \ "Modes:\n" \ @@ -32,6 +30,7 @@ fsck_progress ("\nUsage: %s [mode] [options] " \ " --clean-attributes\t\tclean garbage in reserved fields in StatDatas \n" \ "Options:\n" \ " -j | --journal device\t\tspecify journal if relocated\n" \ +" -B | --badblocks file\t\tfile with list of all bad blocks on the fs\n" \ " -l | --logfile file\t\tmake fsck to complain to specifed file\n" \ " -n | --nolog\t\t\tmake fsck to not complain\n" \ " -z | --adjust-size\t\tfix file sizes to real size\n" \ @@ -49,9 +48,6 @@ fsck_progress ("\nUsage: %s [mode] [options] " \ } /* -" -B badblocks-file\n"\ -" \t\t\tlist of all bad blocks on the fs\n"\ - -B works with --fix-fixable fixes indirect pointers pointed to badblocks, adds badblocks to badblock list in fs. @@ -101,6 +97,7 @@ static char * parse_options (struct fsck_data * data, int argc, char * argv []) {"clean-attributes", no_argument, &mode, FSCK_CLEAN_ATTRIBUTES}, /* options */ {"logfile", required_argument, 0, 'l'}, + {"badblocks", required_argument, 0, 'B'}, {"interactive", no_argument, 0, 'i'}, {"adjust-size", no_argument, 0, 'z'}, {"quiet", no_argument, 0, 'q'}, @@ -124,7 +121,7 @@ static char * parse_options (struct fsck_data * data, int argc, char * argv []) {"journal", required_argument, 0, 'j'}, {"no-journal-available", no_argument, &flag, OPT_SKIP_JOURNAL}, -// {"bad-block-file", required_argument, 0, 'B'}, + {"bad-block-file", required_argument, 0, 'B'}, /* start reiserfsck in background and exit */ {"background", no_argument, 0, 'g'}, @@ -133,7 +130,7 @@ static char * parse_options (struct fsck_data * data, int argc, char * argv []) }; int option_index; - c = getopt_long (argc, argv, "iql:nb:Szd:R:h:j:gafVrpyt:", + c = getopt_long (argc, argv, "iql:nb:Szd:R:h:j:gafVrpyt:B:", options, &option_index); if (c == -1) break; @@ -280,9 +277,13 @@ static char * parse_options (struct fsck_data * data, int argc, char * argv []) print_usage_and_exit(); } - if ((data->options & BADBLOCKS_FILE) && ((mode == FSCK_SB) - || (mode == FSCK_CLEAN_ATTRIBUTES) || (mode == FSCK_CHECK))) + if ((data->options & BADBLOCKS_FILE) && mode != FSCK_REBUILD && + mode != FSCK_FIX_FIXABLE) + { + fprintf(stderr, "Badblocks can be specified with --fix-fixable or " + "--rebuild-tree only.\n"); print_usage_and_exit(); + } if ((mode == FSCK_REBUILD) && (data->options & OPT_YES)) data->options &= ~OPT_YES; @@ -296,36 +297,36 @@ static char * parse_options (struct fsck_data * data, int argc, char * argv []) #define REBUILD_WARNING \ -" *************************************************************\n\ - ** Do not run the program with --rebuild-tree unless **\n\ - ** something is broken and MAKE A BACKUP before using it. **\n\ - ** If you have bad sectors on a drive it is usually a bad **\n\ - ** idea to continue using it. Then you probably should get **\n\ - ** a working hard drive, copy the file system from the bad **\n\ - ** drive to the good one -- dd_rescue is a good tool for **\n\ - ** that -- and only then run this program. **\n\ - ** If you are using the latest reiserfsprogs and it fails **\n\ - ** please email bug reports to reiserfs-list@namesys.com, **\n\ - ** providing as much information as possible -- your **\n\ - ** hardware, kernel, patches, settings, all reiserfsck **\n\ - ** messages (including version), the reiserfsck logfile, **\n\ - ** check the syslog file for any related information. **\n\ - ** If you would like advice on using this program, support **\n\ - ** is available for $25 at www.namesys.com/support.html. **\n\ - *************************************************************\n\ +"*************************************************************\n\ +** Do not run the program with --rebuild-tree unless **\n\ +** something is broken and MAKE A BACKUP before using it. **\n\ +** If you have bad sectors on a drive it is usually a bad **\n\ +** idea to continue using it. Then you probably should get **\n\ +** a working hard drive, copy the file system from the bad **\n\ +** drive to the good one -- dd_rescue is a good tool for **\n\ +** that -- and only then run this program. **\n\ +** If you are using the latest reiserfsprogs and it fails **\n\ +** please email bug reports to reiserfs-list@namesys.com, **\n\ +** providing as much information as possible -- your **\n\ +** hardware, kernel, patches, settings, all reiserfsck **\n\ +** messages (including version), the reiserfsck logfile, **\n\ +** check the syslog file for any related information. **\n\ +** If you would like advice on using this program, support **\n\ +** is available for $25 at www.namesys.com/support.html. **\n\ +*************************************************************\n\ \nWill rebuild the filesystem (%s) tree\n" #define START_WARNING \ -" *************************************************************\n\ - ** If you are using the latest reiserfsprogs and it fails **\n\ - ** please email bug reports to reiserfs-list@namesys.com, **\n\ - ** providing as much information as possible -- your **\n\ - ** hardware, kernel, patches, settings, all reiserfsck **\n\ - ** messages (including version), the reiserfsck logfile, **\n\ - ** check the syslog file for any related information. **\n\ - ** If you would like advice on using this program, support **\n\ - ** is available for $25 at www.namesys.com/support.html. **\n\ - *************************************************************\n\ +"*************************************************************\n\ +** If you are using the latest reiserfsprogs and it fails **\n\ +** please email bug reports to reiserfs-list@namesys.com, **\n\ +** providing as much information as possible -- your **\n\ +** hardware, kernel, patches, settings, all reiserfsck **\n\ +** messages (including version), the reiserfsck logfile, **\n\ +** check the syslog file for any related information. **\n\ +** If you would like advice on using this program, support **\n\ +** is available for $25 at www.namesys.com/support.html. **\n\ +*************************************************************\n\ \n" @@ -530,7 +531,7 @@ static void reset_super_block (reiserfs_filsys_t * fs) set_sb_reserved_for_journal (sb, 0); set_jp_journal_dev (sb_jp(sb), 0); - set_jp_journal_magic (sb_jp(sb) ,0); + set_jp_journal_magic (sb_jp(sb), get_random()); set_jp_journal_1st_block (sb_jp(sb), get_journal_start_must (fs)); set_jp_journal_size (sb_jp(sb), journal_default_size (fs->fs_super_bh->b_blocknr, fs->fs_blocksize)); @@ -545,7 +546,8 @@ static void reset_super_block (reiserfs_filsys_t * fs) set_jp_journal_max_trans_age (sb_jp(sb), advise_journal_max_trans_age()); set_jp_journal_dev (&jh->jh_journal, 0); - set_jp_journal_magic (&jh->jh_journal ,0); + set_jp_journal_magic (&jh->jh_journal, + get_jp_journal_magic(sb_jp(sb))); set_jp_journal_1st_block (&jh->jh_journal, get_jp_journal_1st_block(sb_jp(sb))); set_jp_journal_size (&jh->jh_journal, get_jp_journal_size(sb_jp(sb))); @@ -722,9 +724,10 @@ static void reiserfsck_replay_journal (reiserfs_filsys_t * fs) { fs->fs_ondisk_sb = on_place_sb; } -static void the_end (reiserfs_filsys_t * fs) +static int the_end (reiserfs_filsys_t * fs) { struct reiserfs_super_block * sb; + int ret = EXIT_FIXED; sb = fs->fs_ondisk_sb; @@ -744,41 +747,85 @@ static void the_end (reiserfs_filsys_t * fs) mark_filesystem_consistent (fs); clear_buffer_do_not_flush (fs->fs_super_bh); + if (fsck_data(fs)->mounted == MF_RO) { + reiserfs_warning(stderr, "\nThe partition is mounted ro. It " + "is better to umount and mount it again.\n\n"); + ret = EXIT_REBOOT; + } + /* write all dirty blocks */ fsck_progress ("Syncing.."); fs->fs_dirt = 1; clean_after_dma_check(fs->fs_dev, &dma_info); reiserfs_close (fs); fsck_progress ("finished\n"); + + return ret; } +/* check umounted or read-only mounted filesystems only */ +static void prepare_fs_for_check(reiserfs_filsys_t * fs) { + /* The method could be called from auto_check already. */ + if (fs->fs_flags == O_RDWR) + return; -static void rebuild_tree (reiserfs_filsys_t * fs) -{ + reiserfs_reopen (fs, O_RDWR); + + fsck_data(fs)->mounted = misc_device_mounted(fs->fs_file_name); + + if (fsck_data(fs)->mounted > 0) { + if (fsck_data(fs)->mounted == MF_RW) { + fsck_progress ("Partition %s is mounted with write permissions, " + "cannot check it\n", fs->fs_file_name); + reiserfs_close(fs); + exit(EXIT_USER); + } + + /* If not CHECK mode, lock the process in the memory. */ + if (fsck_mode (fs) != FSCK_CHECK) { + if (mlockall(MCL_CURRENT)) { + reiserfs_warning (stderr, "Failed to lock the process to " + "fsck the mounted ro partition. %s.\n", + strerror(errno)); + exit(EXIT_OPER); + } + } + + if (!reiserfs_journal_opened (fs)) { + /* just to make sure */ + reiserfs_panic ("Journal is not opened"); + } else if (reiserfs_journal_params_check(fs)) { + reiserfs_close (fs); + exit(EXIT_FATAL); + } + + fsck_progress ("Filesystem seems mounted read-only. Skipping journal " + "replay.\n"); + + if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { + fsck_progress ("--fix-fixable ignored\n"); + fsck_mode (fs) = FSCK_CHECK; + } + } else if (!fsck_skip_journal (fs)) { + if (reiserfs_journal_params_check(fs)) { + reiserfs_close (fs); + exit(EXIT_FATAL); + } + + /* filesystem is not mounted, replay journal before checking */ + reiserfsck_replay_journal (fs); + } +} + +static void rebuild_tree (reiserfs_filsys_t * fs) { time_t t; int ret; - if (is_mounted (fs->fs_file_name)) { - fsck_progress ("rebuild_tree: Cannot rebuild tree of mounted filesystem\n"); - exit(EXIT_USER); - } - init_rollback_file (state_rollback_file(fs), &fs->fs_blocksize, fsck_data(fs)->log); - reiserfs_reopen (fs, O_RDWR); - - if (!fsck_skip_journal (fs)) { - if (reiserfs_journal_params_check(fs)) { - reiserfs_close(fs); - exit(EXIT_FATAL); - } - - /* rebuild starts with journal replaying */ - if (!fsck_skip_journal (fs)) - reiserfsck_replay_journal (fs); - } - + prepare_fs_for_check(fs); + ret = reiserfs_open_ondisk_bitmap (fs); if (ret < 0) { fsck_progress ("reiserfsck: Could not open bitmap\n"); @@ -818,67 +865,16 @@ static void rebuild_tree (reiserfs_filsys_t * fs) /* 4. look for unaccessed items in the leaves */ pass_4_check_unaccessed_items (); - the_end (fs); + ret = the_end (fs); } close_rollback_file (); - + time (&t); fsck_progress ("###########\n" "reiserfsck finished at %s" "###########\n", ctime (&t)); - exit (EXIT_OK); -} - - -/* check umounted or read-only mounted filesystems only */ -static void prepare_fs_for_check(reiserfs_filsys_t * fs) -{ - /* The method could be called from auto_check already. */ - if (fs->fs_flags == O_RDWR) - return; - - reiserfs_reopen (fs, O_RDWR); - - if (is_mounted (fs->fs_file_name)) { - /* filesystem seems mounted. */ - if (fsck_mode (fs) == FSCK_CLEAN_ATTRIBUTES) { - fsck_progress ("Partition %s is mounted, cannot clean attributes " - "on mounted device\n", fs->fs_file_name); - reiserfs_close (fs); - exit(EXIT_USER); - } - - if (!is_mounted_read_only (fs->fs_file_name)) { - fsck_progress ("Partition %s is mounted with write permissions, " - "cannot check it\n", fs->fs_file_name); - reiserfs_close (fs); - exit(EXIT_USER); - } - if (!reiserfs_journal_opened (fs)) { - /* just to make sure */ - reiserfs_panic ("Journal is not opened"); - } else if (reiserfs_journal_params_check(fs)) { - reiserfs_close (fs); - exit(EXIT_FATAL); - } - - fsck_progress ("Filesystem seems mounted read-only. Skipping journal " - "replay.\n"); - - if (fsck_mode (fs) == FSCK_FIX_FIXABLE) { - fsck_progress ("--fix-fixable ignored\n"); - fsck_mode (fs) = FSCK_CHECK; - } - } else if (!fsck_skip_journal (fs)) { - if (reiserfs_journal_params_check(fs)) { - reiserfs_close (fs); - exit(EXIT_FATAL); - } - - /* filesystem is not mounted, replay journal before checking */ - reiserfsck_replay_journal (fs); - } + exit (ret); } static void clean_attributes (reiserfs_filsys_t * fs) { @@ -990,6 +986,7 @@ static int auto_check (reiserfs_filsys_t *fs) { } check_fs_tree (fs); + if (fsck_data (fs)->check.fatal_corruptions) { fprintf(stderr, "%lu fatal corruption(s) found in the root block. Running " "with the --rebuild-tree is required.\n", @@ -1096,12 +1093,21 @@ static void check_fs (reiserfs_filsys_t * fs) } else { fsck_progress ("No corruptions found\n"); stage_report (5, fs); - retval = fsck_mode(fs) == FSCK_CHECK ? EXIT_OK : EXIT_FIXED; + + if (fsck_mode(fs) != FSCK_CHECK) { + if (misc_device_mounted(fs->fs_file_name) == MF_RO) { + reiserfs_warning(stderr, "\nThe partition is mounted ro. It is better " + "to umount and mount it again.\n\n"); + retval = EXIT_REBOOT; + } else + retval = EXIT_FIXED; + } else + retval = EXIT_OK; mark_filesystem_consistent (fs); } - if (fsck_mode (fs) == FSCK_FIX_FIXABLE) + if (fsck_mode (fs) == FSCK_FIX_FIXABLE && !fsck_data (fs)->check.fatal_corruptions) id_map_flush(proper_id_map (fs), fs); id_map_free(proper_id_map (fs)); @@ -1185,8 +1191,9 @@ int main (int argc, char * argv []) char * file_name; struct fsck_data * data; struct rlimit rlim = {0xffffffff, 0xffffffff}; - int retval; char *width; + int retval; + int errno; width = getenv("COLUMNS"); if ( width ) @@ -1250,17 +1257,22 @@ int main (int argc, char * argv []) if (open_devices_for_rollback (file_name, data) == -1) exit(EXIT_OPER); } else { - fs = reiserfs_open (file_name, O_RDONLY, 0, data, + fs = reiserfs_open (file_name, O_RDONLY, &errno, data, data->mode != FSCK_SB); if (data->mode != FSCK_SB) { - if (no_reiserfs_found (fs)) - die ("Failed to open the filesystem.\n\n" - "If the partition table has not been changed, and the partition is\n" - "valid and it really contains a reiserfs partition, then the\n" - "superblock is corrupted and you need to run this utility with\n" - "--rebuild-sb.\n"); - + if (no_reiserfs_found (fs)) { + if (errno) { + die ("Failed to open the device '%s': %s\n\n", + file_name, strerror(errno)); + } else { + die ("Failed to open the filesystem.\n\n" + "If the partition table has not been changed, and the partition is\n" + "valid and it really contains a reiserfs partition, then the\n" + "superblock is corrupted and you need to run this utility with\n" + "--rebuild-sb.\n"); + } + } if (fsck_skip_journal (fs) && !is_reiserfs_jr_magic_string (fs->fs_ondisk_sb)) { @@ -1270,21 +1282,26 @@ int main (int argc, char * argv []) } if (!fsck_skip_journal (fs)) { - if (reiserfs_open_journal(fs, data->journal_dev_name, O_RDONLY)) { + retval = reiserfs_open_journal(fs, data->journal_dev_name, O_RDONLY); + + if (retval) { fsck_progress ("Failed to open the journal device (%s).\n", data->journal_dev_name); + if (retval == 1) { + fsck_progress ("Run --rebuild-sb to rebuild journal parameters.\n"); + } + reiserfs_close (fs); exit(EXIT_OPER); } } if (data->options & BADBLOCKS_FILE) { - if (create_badblock_bitmap (fs, badblocks_file) != 0) { - badblocks_file = NULL; - data->options &= ~BADBLOCKS_FILE; - } + if (create_badblock_bitmap (fs, badblocks_file) != 0) + exit(EXIT_OPER); } + register_timer(); } } diff --git a/fsck/pass0.c b/fsck/pass0.c index 8a0702b..17d3bcc 100644 --- a/fsck/pass0.c +++ b/fsck/pass0.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -559,7 +559,7 @@ static __inline__ int does_it_fit_into_dev (__u64 offset, __u64 fs_size) { static int is_wrong_short_key (struct key * key) { if (get_key_dirid (key) == 0 || get_key_objectid (key) == 0 || get_key_objectid (key) == 1 || - get_key_dirid (key) == ~0ul || get_key_objectid (key) == ~0ul || + get_key_dirid (key) == ~(__u32)0 || get_key_objectid (key) == ~(__u32)0 || get_key_dirid (key) == get_key_objectid (key) || (get_key_dirid (key) == 1 && get_key_objectid (key) != 2) || (get_key_dirid (key) != 1 && get_key_objectid (key) == 2) ) @@ -642,9 +642,13 @@ static void pass0_correct_leaf (reiserfs_filsys_t * fs, /* Delete all safe links. */ for (i = get_blkh_nr_items (B_BLK_HEAD (bh)) - 1; i >= 0; i--) { - if (get_key_dirid (&B_N_PITEM_HEAD (bh, i)->ih_key) == ~0ul) { + if (get_key_dirid (&B_N_PITEM_HEAD (bh, i)->ih_key) == ~(__u32)0) { delete_item (fs, bh, i); } + if (get_key_dirid (&B_N_PITEM_HEAD (bh, i)->ih_key) == BADBLOCK_DIRID && + get_key_objectid (&B_N_PITEM_HEAD (bh, i)->ih_key) == BADBLOCK_OBJID) { + delete_item (fs, bh, i); + } } fs_size = (__u64)fs->fs_blocksize * get_sb_block_count (fs->fs_ondisk_sb); diff --git a/fsck/pass1.c b/fsck/pass1.c index 95a4c0a..b279f89 100644 --- a/fsck/pass1.c +++ b/fsck/pass1.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -28,10 +28,10 @@ struct buffer_head * make_buffer (int dev, unsigned long blocknr, int size, char int find_not_of_one_file(struct key * to_find, struct key * key) { - if ((get_key_objectid (to_find) != ~0ul) && + if ((get_key_objectid (to_find) != ~(__u32)0) && (get_key_objectid (to_find) != get_key_objectid (key))) return 1; - if ((get_key_dirid (to_find) != ~0ul) && + if ((get_key_dirid (to_find) != ~(__u32)0) && (get_key_dirid (to_find) != get_key_dirid (key))) return 1; return 0; @@ -246,7 +246,8 @@ static void get_max_buffer_key (struct buffer_head * bh, struct key * key) int tree_is_empty (void) { - return (get_sb_root_block (fs->fs_ondisk_sb) == ~0ul || get_sb_root_block (fs->fs_ondisk_sb) == 0) ? 1 : 0; + return (get_sb_root_block (fs->fs_ondisk_sb) == ~(__u32)0 || + get_sb_root_block (fs->fs_ondisk_sb) == 0) ? 1 : 0; } @@ -543,8 +544,9 @@ static void find_allocable_blocks (reiserfs_filsys_t * fs) } /* make allocable not leaves, not bad blocks */ - if (!is_used_leaf (i) && - (!fs->fs_badblocks_bm || !reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i))) { + if (!is_used_leaf (i) && (!fs->fs_badblocks_bm || + !reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i))) + { /* this is not leaf and it is not pointed by found indirect items, so it does not contains anything valuable */ make_allocable (i); diff --git a/fsck/pass2.c b/fsck/pass2.c index 7ffecba..a151369 100644 --- a/fsck/pass2.c +++ b/fsck/pass2.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -483,7 +483,7 @@ static void do_pass_2 (reiserfs_filsys_t * fs) { unsigned long done = 0, total; - total = reiserfs_bitmap_zeros (fsck_uninsertables (fs)) * 2; + total = reiserfs_bitmap_zeros(fsck_uninsertables(fs)) * 2; if (!total) return; @@ -491,7 +491,9 @@ static void do_pass_2 (reiserfs_filsys_t * fs) { for (i = 0; i < 2; i++) { j = 0; - while (reiserfs_bitmap_find_zero_bit (fsck_uninsertables (fs), &j) == 0) { + while ((j < fsck_uninsertables(fs)->bm_bit_size) && + reiserfs_bitmap_find_zero_bit(fsck_uninsertables(fs), &j) == 0) + { bh = bread (fs->fs_dev, j, fs->fs_blocksize); if (bh == 0) { fsck_log ("pass_2: Reading of the block (%lu) failed on the device 0x%x\n", @@ -508,8 +510,8 @@ static void do_pass_2 (reiserfs_filsys_t * fs) { /* this must be leaf */ what_node = who_is_this (bh->b_data, bh->b_size); if (what_node != THE_LEAF) { // || B_IS_KEYS_LEVEL(bh)) { - fsck_log ("%s: The block (%b), marked as a leaf on the first two passes, is not a leaf! Will be skipped.\n", - __FUNCTION__, bh); + fsck_log ("%s: The block (%b), marked as a leaf on the first two passes, " + "is not a leaf! Will be skipped.\n", __FUNCTION__, bh); goto cont; } /* @@ -622,7 +624,7 @@ void pass_2 (reiserfs_filsys_t * fs) after_pass_2 (fs); - if (get_sb_root_block (fs->fs_ondisk_sb) == ~0ul || + if (get_sb_root_block (fs->fs_ondisk_sb) == ~(__u32)0 || get_sb_root_block (fs->fs_ondisk_sb) == 0) die ( "\nNo reiserfs metadata found. If you are sure that you had the reiserfs\n" "on this partition, then the start of the partition might be changed\n" diff --git a/fsck/pass4.c b/fsck/pass4.c index 22e100d..3ecfe83 100644 --- a/fsck/pass4.c +++ b/fsck/pass4.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -31,7 +31,7 @@ void pass_4_check_unaccessed_items (void) for (i = get_item_pos (&path), ih = get_ih (&path); i < B_NR_ITEMS (bh); i ++, ih ++) { if (!is_item_reachable (ih)) { PATH_LAST_POSITION (&path) = i; - rdkey = get_next_key_2 (&path); + rdkey = reiserfs_next_key(&path); if (rdkey) key = *rdkey; else diff --git a/fsck/reiserfsck.8 b/fsck/reiserfsck.8 index 7762656..79cb612 100644 --- a/fsck/reiserfsck.8 +++ b/fsck/reiserfsck.8 @@ -1,9 +1,9 @@ .\" -*- nroff -*- -.\" Copyright 1996-2003 Hans Reiser. +.\" Copyright 1996-2004 Hans Reiser. .\" -.TH REISERFSCK 8 "April 2003" "Reiserfsprogs-3.6.9" +.TH REISERFSCK 8 "February 2004" "Reiserfsprogs-3.6.13" .SH NAME -reiserfsck \- check a Linux Reiserfs file system +reiserfsck \- checking tool for the ReiserFS filesystem .SH SYNOPSIS .B reiserfsck [ \fB-afprVy\fR ] @@ -13,6 +13,7 @@ reiserfsck \- check a Linux Reiserfs file system [ \fB-j\fR | \fB--journal\fR \fIdevice\fR ] [ \fB-z\fR | \fB--adjust-size\fR ] [ \fB-n\fR | \fB--nolog\fR ] +[ \fB-B\fR | \fB--badblocks \fIfile\fR ] [ \fB-l\fR | \fB--logfile \fIfile\fR ] [ \fB-q\fR | \fB--quiet\fR ] [ \fB-y\fR | \fB--yes\fR ] @@ -51,11 +52,15 @@ zeroing invalid data-block pointers, correcting st_size and st_blocks for directories, and deleting invalid directory entries. .TP .B --rebuild-tree -This option rebuilds the entire file system tree using leaf nodes found -on the device. Normally you only need this option if the \fB--check\fR -option reports "corruption that can be fixed only during \fB--rebuild-tree\fR". -You are strongly encouraged to make a backup copy of the whole partition -before attempting the \fB--rebuild-tree\fR option. +This option rebuilds the entire filesystem tree using leaf nodes +found on the device. Normally you only need this option if the +\fBreiserfsck --check\fR reports "Running with \fB--rebuild-tree\fR +is required". You are strongly encouraged to make a backup copy +of the whole partition before attempting the \fB--rebuild-tree\fR +option. Once \fBreiserfsck --rebuild-tree\fR is started it must +finish its work (and you should not interrupt it), otherwise the +filesystem will be left in the unmountable state to avoid subsequent +data corruptions. .TP .B --clean-attributes This option cleans reserved fields of Stat-Data items. @@ -76,6 +81,13 @@ implies that holes at the end of a file will be removed. File sizes that are smaller than the offset of the last discovered byte are corrected by --fix-fixable. .TP +\fB--badblocks \fIfile\fR, \fB-B \fI file\fR +This option sets the badblock list to be the list of blocks specified in +the given `file`. The filesystem badblock list is cleared before the new +list is added. Can be used with \fB--fix-fixable\fR to fix the list of +badblocks (see debugreiserfs -B) and must be given with \fB--rebuild-tree\fR +option every time if the block device has bad blocks. +.TP \fB--logfile \fIfile\fR, \fB-l \fI file\fR This option causes \fBreiserfsck\fR to report any corruption it finds to the specified log file rather than stderr. @@ -89,7 +101,7 @@ This option prevents \fBreiserfsck\fR from reporting its rate of progress. .B --yes, -y This option inhibits \fBreiserfsck\fR from asking you for confirmation after telling you what it is going to do, assuming yes. For safety, it does not -work with the --rebuild-tree option. +work with the \fB--rebuild-tree\fR option. .TP \fB-a\fR, \fB-p\fR These options are usually passed by fsck -A during the automatic checking @@ -140,9 +152,9 @@ If \fBreiserfsck --check\fR fails in some way you should also run \fBreiserfsck the whole partition before proceeding. Then run \fBreiserfsck --rebuild-tree --logfile rebuild.log /dev/hda1\fR. -6. If the \fB--rebuild-tree\fR step fails or does not recover what you expected, -please submit this as a bug report. Try to provide as much information as -possible and we will try to help solve the problem. +6. If the \fBreiserfsck --rebuild-tree\fR step fails or does not recover what +you expected, please submit this as a bug report. Try to provide as much +information as possible and we will try to help solve the problem. .SH EXIT CODES \fBreiserfsck\fR uses the following exit codes: .br @@ -150,6 +162,8 @@ possible and we will try to help solve the problem. .br \ \fI1\fR \-\ File system errors corrected. .br +\ \fI2\fR \-\ Reboot is needed. +.br \ \fI4\fR \-\ File system fatal errors left uncorrected, .br \ \fBreiserfsck --rebuild-tree\fR needs to be launched. @@ -168,7 +182,7 @@ This version of \fBreiserfsck\fR has been written by Vitaly Fertman . .SH TODO -Faster recovering, signal handling, i/o error handling, etc. +Faster recovering, signal handling. .SH SEE ALSO .BR mkreiserfs (8), .BR reiserfstune (8) diff --git a/fsck/semantic_check.c b/fsck/semantic_check.c index d97bc31..96a5f96 100644 --- a/fsck/semantic_check.c +++ b/fsck/semantic_check.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by reiserfsprogs/README + * Copyright 1996-2004 by Hans Reiser, licensing governed by reiserfsprogs/README */ #include "fsck.h" @@ -303,8 +303,10 @@ start_again: set_deh_objectid (deh, get_key_objectid (key)); mark_buffer_dirty (bh); fsck_log (" - corrected\n"); - } else + } else { + one_more_corruption (fs, FIXABLE); fsck_log ("\n"); + } } } @@ -318,8 +320,10 @@ start_again: set_deh_objectid (deh, get_key_objectid (parent)); mark_buffer_dirty (bh); fsck_log (" - corrected\n"); - } else + } else { + one_more_corruption (fs, FIXABLE); fsck_log ("\n"); + } } } } @@ -697,7 +701,7 @@ int check_safe_links () set_key_dirid(&key, le32_to_cpu(*(__u32 *)get_item(&safe_link_path))); set_key_objectid(&key, get_key_objectid(&tmp_ih->ih_key)); - if ( (rkey = get_next_key_2 (&safe_link_path)) == NULL ) + if ((rkey = reiserfs_next_key(&safe_link_path)) == NULL) set_key_dirid (&safe_link_key, 0); else safe_link_key = *rkey; @@ -799,7 +803,7 @@ void semantic_check (void) fsck_allocable_bitmap (fs) = NULL; set_sb_free_blocks (fs->fs_ondisk_sb, reiserfs_bitmap_zeros (fs->fs_bitmap2)); mark_buffer_dirty (fs->fs_super_bh); - add_badblock_list(fs, 0); + add_badblock_list(fs, 1); } fsck_progress ("finished\n"); diff --git a/fsck/semantic_rebuild.c b/fsck/semantic_rebuild.c index e4250e3..dbe696a 100644 --- a/fsck/semantic_rebuild.c +++ b/fsck/semantic_rebuild.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -105,7 +105,7 @@ int wrong_st_size (struct key * key, unsigned long long max_file_size, if (type == TYPE_DIRENTRY) { /* directory size must match to the sum of length of its entries */ fsck_log ("vpf-10650: The directory %K has the wrong size in the StatData " - "(%Ld)%s(%Ld)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? + "(%Lu)%s(%Lu)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? ", should be " : " - corrected to ", *size); return 1; } @@ -115,7 +115,7 @@ int wrong_st_size (struct key * key, unsigned long long max_file_size, if (fsck_adjust_file_size (fs) || type == TYPE_SYMLINK) { /* but it -o is given - fix that */ fsck_log ("vpf-10660: The file %K has too big size in the StatData " - "(%Ld)%s(%Ld)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? + "(%Lu)%s(%Lu)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? ", should be " : " - corrected to ", *size); sem_pass_stat (fs)->fixed_sizes ++; return 1; @@ -145,7 +145,7 @@ int wrong_st_size (struct key * key, unsigned long long max_file_size, } } - fsck_log ("vpf-10670: The file %K has the wrong size in the StatData (%Ld)%s(%Ld)\n", key, + fsck_log ("vpf-10670: The file %K has the wrong size in the StatData (%Lu)%s(%Lu)\n", key, sd_size, fsck_mode(fs) == FSCK_CHECK ? ", should be " : " - corrected to ", *size); sem_pass_stat (fs)->fixed_sizes ++; diff --git a/fsck/super.c b/fsck/super.c index dab146c..26371da 100644 --- a/fsck/super.c +++ b/fsck/super.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2003 by Hans Reiser, licensing governed by + * Copyright 2001-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -7,6 +7,10 @@ #include #include +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) +# include +#endif + #define fsck_conditional_log(sb_found, fmt, list...) { \ if (sb_found) \ fsck_log(fmt, ## list); \ @@ -189,6 +193,12 @@ void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * dat struct stat64 stat_buf; int retval, exit_code = EXIT_OK; +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + char uuid[37]; + + uuid[36] = '\0'; +#endif + if (!no_reiserfs_found (fs)) { sb = getmem (sizeof (*sb)); if (!is_opened_rw (fs)) { @@ -305,13 +315,12 @@ void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * dat getline (&answer, &n, stdin); if (strcmp ("\n", answer)) block_count = atoi (answer); - set_sb_block_count (sb, block_count); } else { fsck_conditional_log (magic_was_found, "rebuild-sb: wrong block count " "occured (%lu), fixed (%lu)\n", get_sb_block_count(sb), block_count); - - set_sb_block_count (sb, block_count); } + + set_sb_block_count (sb, block_count); } if (get_sb_block_size (sb) != fs->fs_blocksize) { @@ -491,14 +500,13 @@ void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * dat } if (version == 1 || version == 3) { - if (!uuid_is_correct(sb->s_uuid)) { - if (generate_random_uuid (sb->s_uuid)) { - fsck_log ("rebuild-sb: no uuid found, failed to genetate UUID\n"); - } else { - fsck_log ("rebuild-sb: no uuid found, a new uuid generated (%U)\n", - sb->s_uuid); - } +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + if (uuid_is_null(sb->s_uuid)) { + uuid_generate(sb->s_uuid); + fsck_log ("rebuild-sb: no uuid found, a new uuid was " + "generated (%U)\n", sb->s_uuid); } +#endif if (sb->s_flags != 0 && sb->s_flags != 1) { fsck_log ("rebuild-sb: super block flags found (%u), zeroed\n", sb->s_flags); @@ -557,10 +565,10 @@ void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * dat } if ((retval = reiserfs_open_journal(fs, filename, O_RDWR | O_LARGEFILE))) { - fsck_log("\nrebuild-sb: Failed to open the journal device (%s).", + fsck_log("\nrebuild-sb: Failed to open the journal device (%s).\n", filename); - exit(retval == 1 ? EXIT_USER : EXIT_OPER); + exit(retval < 0 ? EXIT_OPER : EXIT_USER); } } else if (!fsck_skip_journal(fs)) { /* Check that specified non-standard journal device exists. */ @@ -674,7 +682,7 @@ void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * dat fsck_log("\nrebuild-sb: Failed to open a journal device (%s).", journal_dev_name); - exit(retval == 1 ? EXIT_USER : EXIT_OPER); + exit(retval < 0 ? EXIT_OPER : EXIT_USER); } /* SB was found, but journal params were broken and have been recovered. @@ -760,8 +768,6 @@ void rebuild_sb (reiserfs_filsys_t * fs, char * filename, struct fsck_data * dat set_jp_journal_magic (&j_head->jh_journal, magic); } - } else { - set_jp_journal_magic (sb_jp(sb), 0); } retval = memcmp(&j_head->jh_journal, sb_jp(sb), sizeof(struct journal_params)); diff --git a/fsck/ubitmap.c b/fsck/ubitmap.c index 9348e89..5d1e70a 100644 --- a/fsck/ubitmap.c +++ b/fsck/ubitmap.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/fsck/ufile.c b/fsck/ufile.c index 063eef3..2d8110c 100644 --- a/fsck/ufile.c +++ b/fsck/ufile.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -225,7 +225,7 @@ int are_file_items_correct (struct item_head * sd_ih, void * sd, __u64 * size, _ } // does not change path - next_key = get_next_key_2 (&path); + next_key = reiserfs_next_key(&path); if (next_key == 0 || not_of_one_file (key, next_key) || (!is_indirect_key (next_key) && !is_direct_key(next_key))) diff --git a/fsck/uobjectid.c b/fsck/uobjectid.c index 581bf28..5aa82dc 100644 --- a/fsck/uobjectid.c +++ b/fsck/uobjectid.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -10,7 +10,7 @@ when --rebuild-tree - fsck builds map of objectids it inserts into tree */ #define ALLOC_SIZE 1024 -#define MAX_ID (~0ul) +#define MAX_ID (~(__u32)0) /* 2 bytes for the counter */ #define BM_SIZE (ALLOC_SIZE - sizeof(__u16)) @@ -21,10 +21,12 @@ #define id_map_local_count(interval) (interval + BM_SIZE) +/* typedef struct sb_id_map { __u32 * m_begin; __u32 m_size, m_used_slot_count; } sb_id_map_t; +*/ id_map_t *id_map_init() { id_map_t *map; @@ -103,7 +105,7 @@ int id_map_mark(id_map_t *map, __u32 id) { /* call this for proper_id_map only!! */ __u32 id_map_alloc(id_map_t *map) { __u32 i, zero_count; - __u32 id = 0, first = ~0ul; + __u32 id = 0, first = ~(__u32)0; for (i = 0, zero_count = 0; zero_count < 10 && i < INDEX_COUNT - 1; i++) { if (map->index[i] == (void *)0) { @@ -121,7 +123,7 @@ __u32 id_map_alloc(id_map_t *map) { die ("Id is out of interval size, interval looks corrupted."); id += i * BM_INTERVAL; - } else if (first != ~0ul) { + } else if (first != ~(__u32)0) { id = first * BM_INTERVAL; if (id == 0) id = 2; @@ -232,7 +234,7 @@ void id_map_flush(struct id_map * map, reiserfs_filsys_t * fs) { if (map->index[map->last_used] == (void *)1) { prev_id = BM_INTERVAL - 1; } else { - prev_id = ~0ul; + prev_id = ~(__u32)0; if (id < map->last_used * BM_INTERVAL) id = 0; @@ -248,7 +250,7 @@ void id_map_flush(struct id_map * map, reiserfs_filsys_t * fs) { prev_id = id; } - if (prev_id == ~0ul) + if (prev_id == ~(__u32)0) die ("Objectid interval does not contain any set bit what is expected."); prev_id++; diff --git a/fsck/ustree.c b/fsck/ustree.c index 7e5d7e0..1323b39 100644 --- a/fsck/ustree.c +++ b/fsck/ustree.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/include/Makefile.in b/include/Makefile.in index 21e7c11..d0ebba9 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/include/config.h.in b/include/config.h.in index dfd9c60..eb2d040 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -9,6 +9,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the `uuid' library (-luuid). */ +#undef HAVE_LIBUUID + /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H @@ -61,6 +64,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the header file. */ +#undef HAVE_UUID_UUID_H + /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF diff --git a/include/io.h b/include/io.h index 94b357d..167b941 100644 --- a/include/io.h +++ b/include/io.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -55,7 +55,6 @@ struct buffer_head * find_buffer (int dev, unsigned long block, unsigned long si struct buffer_head * get_hash_table(dev_t dev, unsigned long block, int size); struct buffer_head * bread (int dev, unsigned long block, size_t size); struct buffer_head * reiserfs_bread (int dev, unsigned long block, int size, int *repeat); -int valid_offset (int fd, loff_t offset); int bwrite (struct buffer_head * bh); void brelse (struct buffer_head * bh); void bforget (struct buffer_head * bh); @@ -67,6 +66,3 @@ void do_fsck_rollback (int fd_device, int fd_journal_device, FILE * log); void flush_buffers (int); void free_buffers (void); void invalidate_buffers (int); - - -int user_confirmed (FILE * fp, char * q, char * yes); diff --git a/include/misc.h b/include/misc.h index 05b3376..939d2ce 100644 --- a/include/misc.h +++ b/include/misc.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -13,10 +13,16 @@ #include #include #include +#include +#include + +#include #define POSITION_FOUND 8 #define POSITION_NOT_FOUND 9 +#define INVAL_PTR (void *)-1 + void check_memory_msg(void); void die (char * fmt, ...) __attribute__ ((format (printf, 1, 2))); void * getmem (int size); @@ -25,11 +31,24 @@ void freemem (void * p); void checkmem (char * p, int size); void * expandmem (void * p, int size, int by); unsigned int get_mem_size (char * p); -int is_mounted (char * device_name); -int is_mounted_read_only (char * device_name); void check_and_free_mem (void); char * kdevname (int dev); +typedef enum mount_flags { + MF_NOT_MOUNTED = 0x0, + MF_RO = 0x1, + MF_RW = 0x2 +} mount_flags_t; + +typedef struct mount_hint { + char *point; /* Mount point. */ + __u32 psize; /* Mount point buffer size. */ + __u32 flags; /* Mount flags. */ +} mount_hint_t; + +struct mntent *misc_mntent(char *device); +int misc_device_mounted(char *device); + void misc_print_credit(FILE *out); typedef struct dma_info { @@ -44,16 +63,15 @@ int prepare_dma_check(dma_info_t *dma_info); int get_dma_info(dma_info_t *dma_info); void clean_after_dma_check(int fd, dma_info_t *dma_info); +int valid_offset( int fd, loff_t offset); +unsigned long count_blocks (char * filename, int blocksize); + void print_how_far (FILE * fp, unsigned long *passed, unsigned long total, unsigned int inc, int quiet); void print_how_fast (unsigned long total, unsigned long passed, int cursor_pos, int reset_time); __u32 get_random (void); -int uuid_is_null(unsigned char * uuid); -int generate_random_uuid (unsigned char * uuid); -int uuid_is_correct (unsigned char * uuid); -int set_uuid (const unsigned char * text, unsigned char * UUID); -//#include +int user_confirmed (FILE * fp, char * q, char * yes); extern inline int misc_set_bit (unsigned long long nr, void * addr); extern inline int misc_clear_bit (unsigned long long nr, void * addr); @@ -85,15 +103,13 @@ extern inline unsigned long long misc_find_first_set_bit (const void *vaddr, uns # error "nuxi/pdp-endian archs are not supported" #endif +#define STAT_FIELD_H(Field, Type) \ +inline Type misc_device_##Field(char *device); - -unsigned long count_blocks (char * filename, int blocksize); - -mode_t get_st_mode (char * file_name); -dev_t get_st_rdev (char * file_name); -off64_t get_st_size (char * file_name); -blkcnt64_t get_st_blocks (char * file_name); - +STAT_FIELD_H(mode, mode_t); +STAT_FIELD_H(rdev, dev_t); +STAT_FIELD_H(size, off64_t); +STAT_FIELD_H(blocks, blkcnt64_t); /* these are to access bitfield in endian safe manner */ __u16 mask16 (int from, int count); diff --git a/include/reiserfs_fs.h b/include/reiserfs_fs.h index 5008dc7..47c88c1 100644 --- a/include/reiserfs_fs.h +++ b/include/reiserfs_fs.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -1020,6 +1020,12 @@ struct disk_child { #define get_dc_child_size(dc) get_le16 (dc, dc2_size) #define set_dc_child_size(dc,val) set_le16 (dc, dc2_size, val) +#define set_dc(dc, size, blocknr) \ +({ \ + set_dc_child_blocknr(dc, blocknr); \ + set_dc_child_size(dc, size); \ + set_le16(dc, dc2_reserved, 0); \ +}) /* Get disk child by buffer header and position in the tree node. */ #define B_N_CHILD(p_s_bh,n_pos) ((struct disk_child *)\ diff --git a/include/reiserfs_lib.h b/include/reiserfs_lib.h index 899563f..3a32987 100644 --- a/include/reiserfs_lib.h +++ b/include/reiserfs_lib.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -7,8 +7,10 @@ #define REISERFS_LIB_H -typedef struct reiserfs_filsys reiserfs_filsys_t; +#define BADBLOCK_DIRID 1 +#define BADBLOCK_OBJID (__u32)-1 +typedef struct reiserfs_filsys reiserfs_filsys_t; #include "reiserfs_fs.h" @@ -86,8 +88,6 @@ void reiserfs_close (reiserfs_filsys_t *); void reiserfs_reopen (reiserfs_filsys_t *, int flags); int is_opened_rw (reiserfs_filsys_t * fs); -struct key * get_next_key_2 (struct path * path); - /* void reiserfs_read_bitmap_blocks (reiserfs_filsys_t *); void reiserfs_free_bitmap_blocks (reiserfs_filsys_t *); @@ -146,9 +146,14 @@ void make_sure_root_dir_exists (reiserfs_filsys_t * fs, void (*modyfy_item)(struct item_head *, void *), int ih_flags); +typedef void (*badblock_func_t) (reiserfs_filsys_t *fs, + struct path *badblock_path, + void *data); + +void mark_badblock(reiserfs_filsys_t *fs, struct path *badblock_path, void *data); int create_badblock_bitmap (reiserfs_filsys_t * fs, char * badblocks_file); void add_badblock_list (reiserfs_filsys_t * fs, int no_badblock_in_tree_yet); - +void badblock_list(reiserfs_filsys_t * fs, badblock_func_t action, void *data); extern struct key root_dir_key; extern struct key parent_root_dir_key; diff --git a/include/swab.h b/include/swab.h index 3a77716..a3a7a35 100644 --- a/include/swab.h +++ b/include/swab.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003 by Hans Reiser, licensing governed by + * Copyright 2002-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/lib/Makefile.in b/lib/Makefile.in index 8322bb3..9bc5362 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/lib/io.c b/lib/io.c index 8701db6..57fbd3d 100644 --- a/lib/io.c +++ b/lib/io.c @@ -1,8 +1,9 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ +#define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE #include @@ -22,28 +23,25 @@ void check_memory_msg (void) { fprintf(stderr, - "\nThe problem has occurred looks like a hardware problem (perhaps memory).\n" - "Send us the bug report only if the second run dies at the same place with\n" - "the same block number.\n"); + "\nThe problem has occurred looks like a hardware problem (perhaps\n" + "memory). Send us the bug report only if the second run dies at\n" + "the same place with the same block number.\n"); } void check_hd_msg (void) { fprintf(stderr, - "\nThe problem has occurred looks like a hardware problem.\n" - "If you have bad blocks, we advise you to get a new hard\n" - "drive, because once you get one bad block that the disk\n" - "drive internals cannot hide from your sight, the chances\n" - "of getting more are generally said to become much higher\n" - "(precise statistics are unknown to us), and this disk drive\n" - "is probably not expensive enough for you to risk your time\n" - "and data on it. If you don't want to follow that advice,\n" - "then if you have just a few bad blocks, try writing to the\n" - "bad blocks and see if the drive remaps the bad blocks (that\n" - "means it takes a block it has in reserve and allocates it\n" - "for use for requests of that block number). If it cannot\n" - "remap the block, this could be quite bad, as it may mean\n" - "that so many blocks have gone bad that none remain in \n" - "reserve to allocate.\n"); + "\nThe problem has occurred looks like a hardware problem. If you have\n" + "bad blocks, we advise you to get a new hard drive, because once you\n" + "get one bad block that the disk drive internals cannot hide from\n" + "your sight,the chances of getting more are generally said to become\n" + "much higher (precise statistics are unknown to us), and this disk\n" + "drive is probably not expensive enough for you to you to risk your\n" + "time and data on it. If you don't want to follow that follow that\n" + "advice then if you have just a few bad blocks, try writing to the\n" + "bad blocks and see if the drive remaps the bad blocks (that means\n" + "it takes a block it has in reserve and allocates it for use for\n" + "of that block number). If it cannot remap the block, use badblock\n" + "option (-B) with reiserfs utils to handle this block correctly.\n"); } static int is_bad_block (unsigned long block) @@ -514,7 +512,7 @@ struct buffer_head * bread (int dev, unsigned long block, size_t size) ret = f_read(bh); if (ret > 0) - die ("%s: End of file, cannot read the block (%lu).\n", __FUNCTION__, bh->b_blocknr); + die ("%s: End of file, cannot read the block (%lu).\n", __FUNCTION__, block); else if (ret < 0) { /* BAD BLOCK LIST SUPPORT * die ("%s: Cannot read a block # %lu. Specify list of badblocks\n",*/ @@ -522,10 +520,10 @@ struct buffer_head * bread (int dev, unsigned long block, size_t size) if (errno == EIO) { check_hd_msg(); die ("%s: Cannot read the block (%lu): (%s).\n", __FUNCTION__, - bh->b_blocknr, strerror(errno)); + block, strerror(errno)); } else { fprintf (stderr, "%s: Cannot read the block (%lu): (%s).\n", __FUNCTION__, - bh->b_blocknr, strerror(errno)); + block, strerror(errno)); return NULL; } } @@ -534,26 +532,6 @@ struct buffer_head * bread (int dev, unsigned long block, size_t size) return bh; } - -int valid_offset( int fd, loff_t offset) -{ - char ch; - loff_t res; - - /*res = reiserfs_llseek (fd, offset, 0);*/ - res = lseek64 (fd, offset, SEEK_SET); - if (res < 0) - return 0; - - /* if (read (fd, &ch, 1) < 0) does not wirk on files */ - if (read (fd, &ch, 1) < 1) - return 0; - - - return 1; -} - - #define ROLLBACK_FILE_START_MAGIC "_RollBackFileForReiserfsFSCK" static struct block_handler * rollback_blocks_array; @@ -986,16 +964,3 @@ void invalidate_buffers (int dev) _invalidate_buffer_list(Buffer_list_head, dev) ; _invalidate_buffer_list(g_free_buffers, dev) ; } - - -int user_confirmed (FILE * fp, char * q, char * yes) -{ - char * answer = 0; - size_t n = 0; - - fprintf (fp, "%s", q); - if (getline (&answer, &n, stdin) != (ssize_t)strlen (yes) || strcmp (yes, answer)) - return 0; - - return 1; -} diff --git a/lib/misc.c b/lib/misc.c index 6f43736..47d8ceb 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -16,29 +16,34 @@ #include #include #include -#include #include #include #include #include #include +#include -#include -#include - -#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64) -# define BLKGETSIZE64 _IOR(0x12, 114, sizeof(__u64)) -#endif - -#include "swab.h" - -#include "io.h" #include "misc.h" /* Debian modifications by Ed Boraas */ #include /* End Debian mods */ +#define STAT_FIELD(Field, Type) \ +inline Type misc_device_##Field(char *device) { \ + struct stat st; \ + \ + if (stat(device, &st) == 0) \ + return st.st_##Field; \ + \ + fprintf(stderr, "Stat of the device '%s' failed.", device); \ + exit(8); \ +} + +STAT_FIELD(mode, mode_t); +STAT_FIELD(rdev, dev_t); +STAT_FIELD(size, off64_t); +STAT_FIELD(blocks, blkcnt64_t); void die (char * fmt, ...) { @@ -173,144 +178,174 @@ void freemem (void * vp) typedef int (*func_t) (char *); -static int is_readonly_dir (char * dir) +/* Lookup the @file in the @mntfile. @file is mntent.mnt_fsname if @fsname + is set; mntent.mnt_dir otherwise. Return the mnt entry from the @mntfile. + + Warning: if the root fs is mounted RO, the content of /etc/mtab may be + not correct. */ +static struct mntent *misc_mntent_lookup(char *mntfile, + char *file, + int fsname) { -/* - int fd; - char template [1024]; + struct mntent *mnt; + struct stat st; + dev_t rdev = 0; + dev_t dev = 0; + ino_t ino = 0; + FILE *fp; - snprintf (template, 1024, "%s/testXXXXXX", dir); - fd = mkstemp (template); - if (fd >= 0) { - close (fd); - return 0; - } -*/ - if (utime (dir, 0) != -1) - /* this is not ro mounted fs */ - return 0; - return (errno == EROFS) ? 1 : 0; -} + assert(mntfile != NULL); + assert(file != NULL); - -#ifdef __i386__ - -#include -#include - -#define __NR_bad_stat64 195 -_syscall2(long, bad_stat64, char *, filename, struct stat64 *, statbuf); - -#else - -#define bad_stat64 stat64 - -#endif - -/* yes, I know how ugly it is */ -#define return_stat_field(field) \ - struct stat st;\ - struct stat64 st64;\ -\ - if (bad_stat64 (file_name, &st64) == 0) {\ - return st64.st_##field;\ - } else if (stat (file_name, &st) == 0)\ - return st.st_##field;\ -\ - perror ("stat failed");\ - exit (8);\ - - -mode_t get_st_mode (char * file_name) -{ - return_stat_field (mode); -} - - -/* may I look at this undocumented (at least in the info of libc 2.3.1-58) - field? */ -dev_t get_st_rdev (char * file_name) -{ - return_stat_field (rdev); -} - - -off64_t get_st_size (char * file_name) -{ - return_stat_field (size); -} - - -blkcnt64_t get_st_blocks (char * file_name) -{ - return_stat_field (blocks); -} - - - -static int _is_mounted (char * device_name, func_t f) -{ - int retval; - FILE *fp; - struct mntent *mnt; - struct statfs stfs; - struct stat root_st; - mode_t mode; - - if (stat ("/", &root_st) == -1) - die ("is_mounted: could not stat \"/\": %s\n", strerror(errno)); - - - mode = get_st_mode (device_name); - if (S_ISREG (mode)) - /* regular file can not be mounted */ - return 0; - - if (!S_ISBLK (mode)) - die ("is_mounted: %s is neither regular file nor block device", device_name); - - if (root_st.st_dev == get_st_rdev (device_name)) { - /* device is mounted as root. Check whether it is mounted read-only */ - return (f ? f ("/") : 1); - } - - /* if proc filesystem is mounted */ - if (statfs ("/proc", &stfs) == -1 || stfs.f_type != 0x9fa0/*procfs magic*/ || - (fp = setmntent ("/proc/mounts", "r")) == NULL) { - /* proc filesystem is not mounted, or /proc/mounts does not - exist */ - if (f) - return (user_confirmed (stderr, - " (could not figure out) Is filesystem mounted read-only? (Yes)", - "Yes\n")); - else - return (user_confirmed (stderr, - " (could not figure out) Is filesystem mounted? (Yes)", "Yes\n")); - } - - retval = 0; - while ((mnt = getmntent (fp)) != NULL) - if (strcmp (device_name, mnt->mnt_fsname) == 0) { - retval = (f ? f (mnt->mnt_dir) : 1/*mounted*/); - break; + if (fsname && stat(file, &st) == 0) { + /* Devices is stated. */ + if (S_ISBLK(st.st_mode)) { + rdev = st.st_rdev; + } else { + dev = st.st_dev; + ino = st.st_ino; + } } - endmntent (fp); - return retval; + if ((fp = setmntent(mntfile, "r")) == NULL) + return INVAL_PTR; + + while ((mnt = getmntent(fp)) != NULL) { + /* Check if names match. */ + if (fsname) { + if (strcmp(file, mnt->mnt_fsname) == 0) + break; + } else { + if (strcmp(file, mnt->mnt_dir) == 0) + break; + + continue; + } + + /* Check if stats match. */ + if (stat(mnt->mnt_fsname, &st) == 0) { + if (rdev && S_ISBLK(st.st_mode)) { + if (rdev == st.st_rdev) + break; + } else { + if (dev == st.st_dev && + ino == st.st_ino) + break; + } + } + } + + endmntent (fp); + return mnt; } +static int misc_root_mounted(char *device) { + struct stat rootst, devst; + + assert(device != NULL); -int is_mounted_read_only (char * device_name) -{ - return _is_mounted (device_name, is_readonly_dir); + if (stat("/", &rootst) != 0) + return -1; + + if (stat(device, &devst) != 0) + return -1; + + if (!S_ISBLK(devst.st_mode) || + devst.st_rdev != rootst.st_dev) + return 0; + + return 1; } +static int misc_file_ro(char *file) { + if (utime(file, 0) == -1) { + if (errno == EROFS) + return 1; + } -int is_mounted (char * device_name) -{ - return _is_mounted (device_name, 0); + return 0; } +struct mntent *misc_mntent(char *device) { + int proc = 0, path = 0, root = 0; + + struct mntent *mnt; + struct statfs stfs; + + assert(device != NULL); + + /* Check if the root. */ + if (misc_root_mounted(device) == 1) + root = 1; + +#ifdef __linux__ + /* Check if /proc is procfs. */ + if (statfs("/proc", &stfs) == 0 && stfs.f_type == 0x9fa0) { + proc = 1; + + if (root) { + /* Lookup the "/" entry in /proc/mounts. Special + case as root entry can present as: + rootfs / rootfs rw 0 0 + Look up the mount point in this case. */ + mnt = misc_mntent_lookup("/proc/mounts", "/", 0); + } else { + /* Lookup the @device /proc/mounts */ + mnt = misc_mntent_lookup("/proc/mounts", device, 1); + } + + if (mnt == INVAL_PTR) + proc = 0; + else if (mnt) + return mnt; + } +#endif /* __linux__ */ + +#if defined(MOUNTED) || defined(_PATH_MOUNTED) + +#ifndef MOUNTED + #define MOUNTED _PATH_MOUNTED +#endif + /* Check in MOUNTED (/etc/mtab) if RW. */ + if (!misc_file_ro(MOUNTED)) { + path = 1; + + if (root) { + mnt = misc_mntent_lookup(MOUNTED, "/", 0); + } else { + mnt = misc_mntent_lookup(MOUNTED, device, 1); + } + + if (mnt == INVAL_PTR) + path = 0; + else if (mnt) + return mnt; + } +#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */ + + /* If has not been checked in neither /proc/mounts nor /etc/mtab (or + errors have occured), return INVAL_PTR, NULL otherwise. */ + return (!proc && !path) ? INVAL_PTR : NULL; +} + +int misc_device_mounted(char *device) { + struct mntent *mnt; + + /* Check for the "/" first to avoid any possible problem with + reflecting the root fs info in mtab files. */ + if (misc_root_mounted(device) == 1) { + return misc_file_ro("/") ? MF_RO : MF_RW; + } + + /* Lookup the mount entry. */ + if ((mnt = misc_mntent(device)) == NULL) { + return MF_NOT_MOUNTED; + } else if (mnt == INVAL_PTR) { + return 0; + } + + return hasmntopt(mnt, MNTOPT_RO) ? MF_RO : MF_RW; +} char buf1 [100]; char buf2 [100]; @@ -407,19 +442,42 @@ void print_how_far (FILE * fp, fflush (fp); } +#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64) +# define BLKGETSIZE64 _IOR(0x12, 114, __u64) +#endif + +/* To not have problem with last sectors on the block device when switching + to smaller one. */ +#define MAX_BS (64 * 1024) + +int valid_offset( int fd, loff_t offset) { + char ch; + loff_t res; + + /*res = reiserfs_llseek (fd, offset, 0);*/ + res = lseek64 (fd, offset, SEEK_SET); + if (res < 0) + return 0; + + /* if (read (fd, &ch, 1) < 0) does not wirk on files */ + if (read (fd, &ch, 1) < 1) + return 0; + return 1; +} /* calculates number of blocks in a file. Returns 0 for "sparse" regular files and files other than regular files and block devices */ unsigned long count_blocks (char * filename, int blocksize) { loff_t high, low; - int fd; unsigned long sz; __u64 size; + int fd; - if (!S_ISBLK (get_st_mode (filename)) && !S_ISREG (get_st_mode (filename))) + if (!S_ISBLK(misc_device_mode(filename)) && + !S_ISREG(misc_device_mode(filename))) return 0; fd = open (filename, O_RDONLY); @@ -429,10 +487,12 @@ unsigned long count_blocks (char * filename, int blocksize) #ifdef BLKGETSIZE64 { if (ioctl (fd, BLKGETSIZE64, &size) >= 0) { - size = (size / 4096) * 4096 / blocksize; + size = (size / MAX_BS) * MAX_BS / blocksize; sz = size; if ((__u64)sz != size) die ("count_blocks: block device too large"); + + close(fd); return sz; } } @@ -443,7 +503,9 @@ unsigned long count_blocks (char * filename, int blocksize) { if (ioctl (fd, BLKGETSIZE, &sz) >= 0) { size = sz; - return (size * 512 / 4096) * 4096 / blocksize; + + close(fd); + return (size * 512 / MAX_BS) * MAX_BS / blocksize; } } #endif @@ -459,15 +521,13 @@ unsigned long count_blocks (char * filename, int blocksize) else high = mid; } + valid_offset (fd, 0); close (fd); - - return (low + 1) * 4096 / 4096 / blocksize ; + return (low + 1) * MAX_BS / MAX_BS / blocksize; } - - /* there are masks for certain bits */ __u16 mask16 (int from, int count) { @@ -570,27 +630,6 @@ int blockdev_list_compare (const void * block1, const void * block2) { return 0; } -/* return -1 if smth found, otherwise return position which new item should be inserted into */ -/* -int blocklist__is_block_saved (struct block_handler ** base, __u32 * count, - __u32 blocknr, dev_t device, __u32 * position) { - struct block_handler block_h; - - *position = 0; - - if (*base == NULL) - return 0; - - block_h.blocknr = blocknr; - block_h.device = device; - - if (reiserfs_bin_search (&block_h, *base, *count, sizeof (block_h), - position, blocklist_compare) == POSITION_FOUND) - return 1; - - return 0; -} -*/ void blocklist__insert_in_position (void *elem, void **base, __u32 *count, int elem_size, __u32 *position) { @@ -614,93 +653,6 @@ void blocklist__insert_in_position (void *elem, void **base, __u32 *count, *count+=1; } -static int get_random_bytes (void *out, int size) { - int fd; - - if ((fd = open("/dev/urandom", O_RDONLY)) == -1) - return 1; - - if (read(fd, out, size) <= 0) { - close (fd); - return 1; - } - - close (fd); - return 0; -} - -int generate_random_uuid (unsigned char * uuid) -{ - if (get_random_bytes(uuid, 16)) { - return -1; - } - - /* Set the UUID variant to DCE */ - uuid[8] = (uuid[8] & 0x3F) | 0x80; - /* Set UUID version to 4 --- truely random generation */ - uuid[6] = (uuid[6] & 0x0F) | 0x40; - - return 0; -} - -int uuid_is_correct (unsigned char * uuid) -{ - int i; - - for (i = 0; i < 16; i++) - if (uuid[i]) - break; - - if (i == 16) - return 0; - - if (!misc_test_bit(7, &uuid[8]) || misc_test_bit(6, &uuid[8])) - return 0; - - if (misc_test_bit(7, &uuid[6]) || !misc_test_bit(6, &uuid[6]) || - misc_test_bit(5, &uuid[6]) || misc_test_bit(4, &uuid[6])) - return 0; - - return 1; -} - -static int parse_uuid (const unsigned char * in, unsigned char * uuid) -{ - int i, j = 0; - unsigned char frame[3]; - - if (strlen(in) != 36) - return -1; - - for (i = 0; i < 36; i++) { - if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { - if (in[i] != '-') - return 0; - } else if (!isxdigit(in[i])) { - return -1; - } - } - - frame[2] = 0; - for (i = 0; i < 36; i ++) { - if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) - continue; - - frame[0] = in[i++]; - frame[1] = in[i]; - uuid[j++] = strtoul(frame, NULL, 16); - } - return 0; -} - -int set_uuid (const unsigned char * text, unsigned char * UUID) -{ - if (parse_uuid (text, UUID) || !uuid_is_correct(UUID)) - return -1; - - return 0; -} - /* 0 - dma is not supported, scsi or regular file */ /* 1 - xt drive */ /* 2 - ide drive */ @@ -971,13 +923,30 @@ inline unsigned long long misc_find_next_set_bit(const void *vaddr, /* Reads the "CREDITS" file and prints one paragraph from it. */ void misc_print_credit(FILE *out) { char *line; + __u32 num1, num2; - fprintf(out, "\nA pair of credits:\n"); + fprintf(out, "A pair of credits:\n"); - line = credits[(random() % CREDITS_COUNT)]; - fprintf(out, "%s", line); + srandom (time (0)); - line = credits[(random() % CREDITS_COUNT)]; - fprintf(out, "%s", line); + num1 = random() % CREDITS_COUNT; + line = credits[num1]; + fprintf(out, "%s\n", line); + + while ((num1 == (num2 = random() % CREDITS_COUNT))) {} + + line = credits[num2]; + + fprintf(out, "%s\n", line); } +int user_confirmed (FILE * fp, char * q, char * yes) { + char * answer = 0; + size_t n = 0; + + fprintf (fp, "%s", q); + if (getline (&answer, &n, stdin) != (ssize_t)strlen (yes) || strcmp (yes, answer)) + return 0; + + return 1; +} diff --git a/mkreiserfs/Makefile.in b/mkreiserfs/Makefile.in index 9535178..8fa33f6 100644 --- a/mkreiserfs/Makefile.in +++ b/mkreiserfs/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/mkreiserfs/mkreiserfs.8 b/mkreiserfs/mkreiserfs.8 index bb40127..2e428c7 100644 --- a/mkreiserfs/mkreiserfs.8 +++ b/mkreiserfs/mkreiserfs.8 @@ -1,9 +1,9 @@ .\" -*- nroff -*- -.\" Copyright 1996-2003 Hans Reiser. +.\" Copyright 1996-2004 Hans Reiser. .\" -.TH MKREISERFS 8 "April 2003" "Reiserfsprogs-3.6.9" +.TH MKREISERFS 8 "February 2004" "Reiserfsprogs-3.6.13" .SH NAME -mkreiserfs \- create a Linux ReiserFS file system +mkreiserfs \- create tool for the Linux ReiserFS file system .SH SYNOPSIS .B mkreiserfs [ \fB-dfV\fR ] @@ -16,7 +16,8 @@ mkreiserfs \- create a Linux ReiserFS file system [ \fB-j\fR | \fB--journal-device \fIFILE\fR ] [ \fB-s\fR | \fB--journal-size \fIN\fR ] [ \fB-o\fR | \fB--journal-offset \fIN\fR ] -[ \fB-t\fR | \fB--transaction-max-size\fR \fIN\fR ] \fI device\fR +[ \fB-t\fR | \fB--transaction-max-size\fR \fIN\fR ] +[ \fB-B\fR | \fB--badblocks\fR \fIfile\fR ] \fI device\fR [ \fIfilesystem-size\fR ] .SH DESCRIPTION It creates a Linux ReiserFS file system on a device @@ -83,6 +84,11 @@ default, and max possible, value is 1024 blocks. It should be less than half the size of the journal. If specifed incorrectly, it will be adjusted. .TP +\fB-B\fR | \fB--badblocks \fIfile +\fIFile\fR is the file name of the file that contains the list of blocks +to be marked as bad on the filesystem. This list can be created by +\fB/sbin/badblocks -b block-size device\fR. +.TP \fB-f\fR This forces \fBmkreiserfs\fR to continue even if device is either whole disk, or looks mounted or is not a block device. Specified more than diff --git a/mkreiserfs/mkreiserfs.c b/mkreiserfs/mkreiserfs.c index aa57d58..fab25ff 100644 --- a/mkreiserfs/mkreiserfs.c +++ b/mkreiserfs/mkreiserfs.c @@ -1,20 +1,16 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ -/* mkreiserfs is very simple. It supports only 4k blocks. It skips - first 64k of device, and then writes the super - block, the needed amount of bitmap blocks (this amount is calculated - based on file system size), and root block. Bitmap policy is - primitive: it assumes, that device does not have unreadable blocks, - and it occupies first blocks for super, bitmap and root blocks. - bitmap blocks are interleaved across the disk, mainly to make - resizing faster. */ +/* mkreiserfs is very simple. It skips first 64k of device, and then + writes the super block, the needed amount of bitmap blocks (this + amount is calculated based on file system size), and root block. + Bitmap policy is primitive: it assumes, that device does not have + unreadable blocks, and it occupies first blocks for super, bitmap + and root blocks. bitmap blocks are interleaved across the disk, + mainly to make resizing faster. */ -// -// FIXME: not 'not-i386' safe. ? Ed -// #define _GNU_SOURCE #include @@ -40,6 +36,10 @@ #include "../include/config.h" #include "../version.h" +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) +# include +#endif + char *program_name; @@ -73,6 +73,7 @@ static void print_usage_and_exit(void) " -o | --journal-offset N offset of the journal from the start of\n" " the separate device, in blocks\n" " -t | --transaction-max-size N maximal size of transaction, in blocks\n" + " -B | --badblocks file store all bad blocks given in file on the fs\n" " -h | --hash rupasov|tea|r5 hash function to use by default\n" " -u | --uuid UUID store UUID in the superblock\n" " -l | --label LABEL store LABEL in the superblock\n" @@ -89,7 +90,6 @@ static void print_usage_and_exit(void) exit (1); } -// " -B badblocks-file list of all bad blocks on the fs\n" int Create_default_journal = 1; int Block_size = 4096; @@ -106,7 +106,8 @@ char * badblocks_file; enum mkfs_mode { DEBUG_MODE = 1 << 0, - QUIET_MODE = 1 << 1 + QUIET_MODE = 1 << 1, + DO_NOTHING = 1 << 2 }; int mode; @@ -118,10 +119,12 @@ static void make_super_block (reiserfs_filsys_t * fs) set_sb_tree_height (fs->fs_ondisk_sb, 2); set_sb_hash_code (fs->fs_ondisk_sb, Hash); if (fs->fs_format == REISERFS_FORMAT_3_6) { - if (!uuid_is_correct (UUID) && generate_random_uuid (UUID)) - reiserfs_warning (stderr, "failed to genetate UUID\n"); +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + if (uuid_is_null(UUID)) + uuid_generate(UUID); memcpy (fs->fs_ondisk_sb->s_uuid, UUID, 16); +#endif if (LABEL != NULL) { if (strlen (LABEL) > 16) reiserfs_warning (stderr, "\nSpecified LABEL is longer then 16 " @@ -140,6 +143,10 @@ static void make_super_block (reiserfs_filsys_t * fs) else set_sb_reserved_for_journal (fs->fs_ondisk_sb, get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)) + 1); + + if (fs->fs_badblocks_bm) + set_sb_free_blocks(fs->fs_ondisk_sb, get_sb_free_blocks(fs->fs_ondisk_sb) - + fs->fs_badblocks_bm->bm_set_bits); } @@ -295,11 +302,9 @@ static void make_root_block (reiserfs_filsys_t * fs) make_sure_root_dir_exists (fs, set_root_dir_nlink, 0); brelse (bh); - /**/ mark_objectid_used (fs, REISERFS_ROOT_PARENT_OBJECTID); mark_objectid_used (fs, REISERFS_ROOT_OBJECTID); - } @@ -543,12 +548,10 @@ int main (int argc, char **argv) else program_name = argv[ 0 ]; - - if (argc < 2) { - print_banner (program_name); - + if (argc < 2) print_usage_and_exit (); - } + + memset(UUID, 0, 16); while (1) { static struct option options[] = { @@ -557,6 +560,7 @@ int main (int argc, char **argv) {"journal-size", required_argument, 0, 's'}, {"transaction-max-size", required_argument, 0, 't'}, {"journal-offset", required_argument, 0, 'o'}, + {"badblocks", required_argument, 0, 'B'}, {"hash", required_argument, 0, 'h'}, {"uuid", required_argument, 0, 'u'}, {"label", required_argument, 0, 'l'}, @@ -614,7 +618,8 @@ int main (int argc, char **argv) break; case 'V': - print_usage_and_exit (); + mode = DO_NOTHING; + break; case 'f': force ++; @@ -625,11 +630,17 @@ int main (int argc, char **argv) break; case 'u': - if (set_uuid (optarg, UUID)) { - reiserfs_warning(stderr, "wrong UUID specified\n"); +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + if (uuid_parse(optarg, UUID) < 0) { + reiserfs_warning(stderr, "Invalid UUID '%s' is " + "specified\n", optarg); return 1; } - +#else + message ("Cannot set up the UUID, uuidlib was not " + "found by configure.\n"); + return 1; +#endif break; case 'l': @@ -637,13 +648,22 @@ int main (int argc, char **argv) break; case 'q': mode |= QUIET_MODE; - fclose(stdout); break; default: print_usage_and_exit(); } } + print_banner (program_name); + + misc_print_credit(stdout); + printf("\n"); + + if (mode & QUIET_MODE) + fclose(stdout); + + if (mode == DO_NOTHING) + exit(0); /* device to be formatted */ device_name = argv [optind]; @@ -687,20 +707,24 @@ int main (int argc, char **argv) /* these fill buffers (super block, first bitmap, root block) with reiserfs structures */ - if (uuid_is_correct (UUID) && fs->fs_format != REISERFS_FORMAT_3_6) { +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + if (!uuid_is_null(UUID) && fs->fs_format != REISERFS_FORMAT_3_6) { reiserfs_warning(stderr, "UUID can be specified only with 3.6 format\n"); return 1; } +#endif - if (badblocks_file) - create_badblock_bitmap (fs, badblocks_file); + if (badblocks_file) { + if (create_badblock_bitmap (fs, badblocks_file)) + exit(1); + } make_super_block (fs); make_bitmap (fs); make_root_block (fs); -// add_badblock_list (fs, 1); - + add_badblock_list (fs, 1); + report (fs, jdevice_name); if (!force && !(mode & QUIET_MODE)) { @@ -716,7 +740,6 @@ int main (int argc, char **argv) invalidate_other_formats (fs->fs_dev); - zero_journal (fs); reiserfs_close (fs); @@ -728,9 +751,9 @@ int main (int argc, char **argv) if (mode & DEBUG_MODE) return 0; - misc_print_credit(stdout); - printf("\nTell your friends to use the kernel based on 2.4.18 or later " - "when you use\nreiserFS. Have fun.\n\n"); + printf("\nTell your friends to use a kernel based on 2.4.18 or " + "later, and especially not a\nkernel based on 2.4.9, " + "when you use reiserFS. Have fun.\n\n"); printf("ReiserFS is successfully created on %s.\n", device_name); diff --git a/reiserfscore/Makefile.in b/reiserfscore/Makefile.in index 0bcfbca..858dcd0 100644 --- a/reiserfscore/Makefile.in +++ b/reiserfscore/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/reiserfscore/bitmap.c b/reiserfscore/bitmap.c index 5901e9f..4de8461 100644 --- a/reiserfscore/bitmap.c +++ b/reiserfscore/bitmap.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -56,12 +56,20 @@ int reiserfs_expand_bitmap (reiserfs_bitmap_t * bm, unsigned int bit_count) void reiserfs_shrink_bitmap (reiserfs_bitmap_t * bm, unsigned int bit_count) { + unsigned long i; + assert (bm->bm_bit_size >= bit_count); bm->bm_byte_size = (bit_count + 7) / 8; bm->bm_bit_size = bit_count; - + bm->bm_set_bits = 0; + bm->bm_dirty = 1; + + for (i = 0; i < bm->bm_bit_size; i++) { + if (reiserfs_bitmap_test_bit(bm, i)) + bm->bm_set_bits++; + } } /* bitmap destructor */ diff --git a/reiserfscore/do_balan.c b/reiserfscore/do_balan.c index fb9387b..43bfbc4 100644 --- a/reiserfscore/do_balan.c +++ b/reiserfscore/do_balan.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/reiserfscore/fix_node.c b/reiserfscore/fix_node.c index c2f996d..92ef814 100644 --- a/reiserfscore/fix_node.c +++ b/reiserfscore/fix_node.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/reiserfscore/hashes.c b/reiserfscore/hashes.c index 607472b..6a08072 100644 --- a/reiserfscore/hashes.c +++ b/reiserfscore/hashes.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/reiserfscore/ibalance.c b/reiserfscore/ibalance.c index ff0a2c6..38efff0 100644 --- a/reiserfscore/ibalance.c +++ b/reiserfscore/ibalance.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -136,10 +136,14 @@ static void internal_insert_childs (reiserfs_filsys_t * fs, /* make disk child array for insertion */ for (i = 0; i < count; i ++) { + set_dc(new_dc + i, MAX_CHILD_SIZE(bh[i]->b_size) - + get_blkh_free_space (B_BLK_HEAD (bh[i])), + bh[i]->b_blocknr); + /* set_dc_child_size (new_dc + i, MAX_CHILD_SIZE(bh[i]->b_size) - get_blkh_free_space (B_BLK_HEAD (bh[i]))); - set_dc_child_blocknr (new_dc + i, bh[i]->b_blocknr); + set_dc_child_blocknr (new_dc + i, bh[i]->b_blocknr);*/ } memcpy (dc, new_dc, DC_SIZE * count); @@ -667,10 +671,15 @@ int balance_internal (struct tree_balance * tb, /* tree_balance structure */ /* replace the first node-ptr in S[h] by node-ptr to insert_ptr[k] */ dc = B_N_CHILD(tbSh, 0); + + set_dc(dc, MAX_CHILD_SIZE(insert_ptr[k]->b_size) - + get_blkh_free_space (B_BLK_HEAD(insert_ptr[k])), + insert_ptr[k]->b_blocknr); + /* set_dc_child_size (dc, MAX_CHILD_SIZE(insert_ptr[k]->b_size) - get_blkh_free_space (B_BLK_HEAD(insert_ptr[k]))); set_dc_child_blocknr (dc, insert_ptr[k]->b_blocknr); - + */ mark_buffer_dirty (tbSh); k++; @@ -721,10 +730,14 @@ int balance_internal (struct tree_balance * tb, /* tree_balance structure */ /* replace the first node-ptr in R[h] by node-ptr insert_ptr[insert_num-k-1]*/ dc = B_N_CHILD(tb->R[h], 0); + set_dc(dc, MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]->b_size) - + get_blkh_free_space (B_BLK_HEAD(insert_ptr[insert_num-k-1])), + insert_ptr[insert_num-k-1]->b_blocknr); + /* set_dc_child_size (dc, MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]->b_size) - get_blkh_free_space (B_BLK_HEAD(insert_ptr[insert_num-k-1]))); set_dc_child_blocknr (dc, insert_ptr[insert_num-k-1]->b_blocknr); - + */ mark_buffer_dirty (tb->R[h]); insert_num -= (k + 1); @@ -754,9 +767,14 @@ int balance_internal (struct tree_balance * tb, /* tree_balance structure */ /* Put the unique node-pointer to S[h] that points to S[h-1]. */ dc = B_N_CHILD(tbSh, 0); + + set_dc(dc, MAX_CHILD_SIZE (tbSh_1->b_size) - + get_blkh_free_space (B_BLK_HEAD(tbSh_1)), + tbSh_1->b_blocknr); + /* set_dc_child_size (dc, MAX_CHILD_SIZE (tbSh_1->b_size) - get_blkh_free_space (B_BLK_HEAD(tbSh_1))); set_dc_child_blocknr (dc, tbSh_1->b_blocknr); - + */ tb->insert_size[h] -= DC_SIZE; set_blkh_free_space (B_BLK_HEAD(tbSh), get_blkh_free_space (B_BLK_HEAD(tbSh)) - DC_SIZE); @@ -835,10 +853,14 @@ int balance_internal (struct tree_balance * tb, /* tree_balance structure */ /* replace first node-ptr in S_new by node-ptr to insert_ptr[insert_num-k-1] */ dc = B_N_CHILD(S_new,0); + set_dc(dc, MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]->b_size) - + get_blkh_free_space (B_BLK_HEAD(insert_ptr[insert_num-k-1])), + insert_ptr[insert_num-k-1]->b_blocknr); + /* set_dc_child_size (dc, MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]->b_size) - get_blkh_free_space (B_BLK_HEAD(insert_ptr[insert_num-k-1]))); set_dc_child_blocknr (dc, insert_ptr[insert_num-k-1]->b_blocknr); - + */ mark_buffer_dirty (S_new); insert_num -= (k + 1); diff --git a/reiserfscore/includes.h b/reiserfscore/includes.h index 15178d4..c5bd15e 100644 --- a/reiserfscore/includes.h +++ b/reiserfscore/includes.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -21,3 +21,4 @@ #include "reiserfs_lib.h" #include "swab.h" +#include "../include/config.h" diff --git a/reiserfscore/journal.c b/reiserfscore/journal.c index c3fe777..a33f111 100644 --- a/reiserfscore/journal.c +++ b/reiserfscore/journal.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003 by Hans Reiser, licensing governed by + * Copyright 2002-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -481,10 +481,11 @@ int reiserfs_open_journal (reiserfs_filsys_t * fs, char * j_filename, int flags) sb = fs->fs_ondisk_sb; if (!j_filename) { + /* if (is_reiserfs_jr_magic_string (sb)) { - /* create a special file to access journal */ + // create a special file to access journal return 1; - } + } */ j_filename = fs->fs_file_name; } else if (!is_reiserfs_jr_magic_string (sb)) { @@ -492,7 +493,7 @@ int reiserfs_open_journal (reiserfs_filsys_t * fs, char * j_filename, int flags) if (strcmp (j_filename, fs->fs_file_name)) { reiserfs_warning (stderr, "Filesystem with standard journal found, " "wrong name of specified journal device %s \n", j_filename); - return 1; + return 2; } } @@ -503,9 +504,9 @@ int reiserfs_open_journal (reiserfs_filsys_t * fs, char * j_filename, int flags) asprintf (&fs->fs_j_file_name, "%s", j_filename); if (get_jp_journal_size(sb_jp(sb)) < JOURNAL_MIN_SIZE) { - reiserfs_warning (stderr, "Journal of (%lu) block size found on specified journal " - "device %s.\nMust be not less than (%lu).\nRun --rebuild-sb to rebuild journal " - "parameters.\n", get_jp_journal_size (sb_jp (sb)) + 1, j_filename, + reiserfs_warning (stderr, "Journal of (%lu) block size found on " + "specified journal device %s.\nMust be not less than (%lu).\n", + get_jp_journal_size (sb_jp (sb)) + 1, j_filename, JOURNAL_MIN_SIZE + 1); return 1; } @@ -513,10 +514,9 @@ int reiserfs_open_journal (reiserfs_filsys_t * fs, char * j_filename, int flags) count = count_blocks (j_filename, fs->fs_blocksize); if (get_jp_journal_1st_block (sb_jp (sb)) + get_jp_journal_size (sb_jp (sb)) + 1 > count) { reiserfs_warning (stderr, "Detected journal on specified device %s does not fit to " - "the device.\nStart block (%lu) + size (%lu) less than device size (%lu).\n" - "Run --rebuild-sb to rebuild journal parameters.\n", - get_jp_journal_1st_block(sb_jp (sb)), get_jp_journal_size(sb_jp (sb)) + 1, - count); + "the device.\nStart block (%lu) + size (%lu) less than device size (%lu).\n", + j_filename, get_jp_journal_1st_block(sb_jp (sb)), + get_jp_journal_size(sb_jp (sb)) + 1, count); return 1; } @@ -633,9 +633,9 @@ int reiserfs_create_journal( asprintf (&fs->fs_j_file_name, "%s", j_device); - if (len < JOURNAL_MIN_SIZE) { + if (len < JOURNAL_MIN_SIZE + 1) { reiserfs_warning (stderr, "WARNING: Journal size (%u) is less, than " - "minimal supported journal size (%u).", len, JOURNAL_MIN_SIZE + 1); + "minimal supported journal size (%u).\n", len, JOURNAL_MIN_SIZE + 1); return 0; } /* get journal header */ diff --git a/reiserfscore/lbalance.c b/reiserfscore/lbalance.c index 2a21ee0..c0e4e30 100644 --- a/reiserfscore/lbalance.c +++ b/reiserfscore/lbalance.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/reiserfscore/node_formats.c b/reiserfscore/node_formats.c index cc404bc..9a2c9a2 100644 --- a/reiserfscore/node_formats.c +++ b/reiserfscore/node_formats.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -1299,7 +1299,7 @@ void mark_objectid_used (reiserfs_filsys_t * fs, __u32 objectid) int is_blocksize_correct (unsigned int blocksize) { - return ((blocksize == 0) || (((blocksize & -blocksize) == blocksize) - && (blocksize >=512) && (blocksize <= 8192))); + return ((((blocksize & -blocksize) == blocksize) + && (blocksize >= 512) && (blocksize <= 8192))); } diff --git a/reiserfscore/prints.c b/reiserfscore/prints.c index e6597bc..9d9122b 100644 --- a/reiserfscore/prints.c +++ b/reiserfscore/prints.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -8,6 +8,10 @@ #include #include +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) +# include +#endif + #define PA_KEY (PA_LAST) #define PA_BUFFER_HEAD (PA_LAST + 1) #define PA_ITEM_HEAD (PA_LAST + 2) @@ -196,17 +200,16 @@ static int print_sd_uuid (FILE * stream, const struct printf_info *info, const void *const *args) { - int i; - const unsigned char * uuid; - int len = 0; - - uuid = *((const unsigned char **)(args[0])); - for (i = 0; i < 16; i++) { - if (i == 4 || i == 6 || i == 8 || i == 10) - len += fprintf (stream, "-"); - len += fprintf(stream, "%02x", uuid[i]); - } - return len; +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + const unsigned char *uuid = *((const unsigned char **)(args[0])); + char buf[37]; + + buf[36] = '\0'; + uuid_unparse(uuid, buf); + return fprintf(stream, "%s", buf); +#else + return fprintf(stream, ""); +#endif } void reiserfs_warning (FILE * fp, const char * fmt, ...) @@ -509,34 +512,34 @@ static int print_leaf (FILE * fp, reiserfs_filsys_t * fs, struct buffer_head * b struct item_head * ih; int i; int from, to; - int nr; + int real_nr, nr; if (!is_tree_node (bh, DISK_LEAF_NODE_LEVEL)) return 1; - blkh = B_BLK_HEAD (bh); ih = B_N_PITEM_HEAD (bh,0); - nr = leaf_count_ih(bh->b_data, bh->b_size); - + real_nr = leaf_count_ih(bh->b_data, bh->b_size); + nr = get_blkh_nr_items((struct block_head *)bh->b_data); + reiserfs_warning (fp, "\n===================================================================\n"); reiserfs_warning (fp, "LEAF NODE (%ld) contains %b (real items %d)\n", - bh->b_blocknr, bh, nr); + bh->b_blocknr, bh, real_nr); if (!(print_mode & PRINT_TREE_DETAILS)) { reiserfs_warning (fp, "FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n", - &(ih->ih_key), &((ih + nr - 1)->ih_key)); + &(ih->ih_key), &((ih + real_nr - 1)->ih_key)); return 0; } - if (first < 0 || first > nr - 1) + if (first < 0 || first > real_nr - 1) from = 0; else from = first; - if (last < 0 || last > nr) - to = nr; + if (last < 0 || last > real_nr) + to = real_nr; else to = last; @@ -548,7 +551,7 @@ static int print_leaf (FILE * fp, reiserfs_filsys_t * fs, struct buffer_head * b for (i = from; i < to; i++) { reiserfs_warning (fp, "-------------------------------------------------------------------------------\n" - "|%3d|%30H|\n", i, ih + i); + "|%3d|%30H|%s\n", i, ih + i, i >= nr ? " DELETED" : ""); if (I_IS_STAT_DATA_ITEM(ih+i)) { is_symlink = print_stat_data (fp, bh, ih + i, 0/*all times*/); @@ -612,7 +615,7 @@ int print_super_block (FILE * fp, reiserfs_filsys_t * fs, char * file_name, if (!does_look_like_super_block (sb)) return 1; - rdev = get_st_rdev (file_name); + rdev = misc_device_rdev(file_name); reiserfs_warning (fp, "Reiserfs super block in block %lu on 0x%x of ", bh->b_blocknr, rdev); @@ -643,7 +646,7 @@ int print_super_block (FILE * fp, reiserfs_filsys_t * fs, char * file_name, "bitmaps, data, reserved] blocks): %u\n", get_sb_free_blocks (sb)); reiserfs_warning (fp, "Root block: %u\n", get_sb_root_block (sb)); } - reiserfs_warning (fp, "Filesystem is %scleanly umounted\n", + reiserfs_warning (fp, "Filesystem marked as %scleanly umounted\n", (get_sb_umount_state (sb) == FS_CLEANLY_UMOUNTED) ? "" : "NOT "); if (short_print) @@ -967,7 +970,7 @@ void print_objectid_map (FILE * fp, reiserfs_filsys_t * fs) } else { reiserfs_warning(fp, "free(%u-%u) ", le32_to_cpu (omap[i]), ((i+1) == get_sb_oid_cursize (sb)) ? - ~0ul : (le32_to_cpu (omap[i+1]) - 1)); + ~(__u32)0 : (le32_to_cpu (omap[i+1]) - 1)); } } diff --git a/reiserfscore/reiserfslib.c b/reiserfscore/reiserfslib.c index f916868..8f5cef8 100644 --- a/reiserfscore/reiserfslib.c +++ b/reiserfscore/reiserfslib.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -9,6 +9,7 @@ struct key root_dir_key = {0, 0, {{0, 0},}}; struct key parent_root_dir_key = {0, 0, {{0, 0},}}; struct key lost_found_dir_key = {0, 0, {{0, 0}, }}; +struct key badblock_key = {BADBLOCK_DIRID, BADBLOCK_OBJID, {{0, 0},}}; __u16 root_dir_format = 0; __u16 lost_found_dir_format = 0; @@ -59,6 +60,8 @@ reiserfs_filsys_t * reiserfs_open (char * filename, int flags, int *error, void /* convert root dir key and parent root dir key to little endian format */ make_const_keys (); + if (error) + *error = 0; fd = open (filename, flags | O_LARGEFILE); if (fd == -1) { @@ -92,8 +95,6 @@ reiserfs_filsys_t * reiserfs_open (char * filename, int flags, int *error, void reiserfs_warning(stderr, "\nreiserfs_open: the reiserfs superblock cannot be found on %s.\n", filename); - if (error) - *error = 0; freemem (fs); close (fd); fs = NULL; @@ -101,19 +102,19 @@ reiserfs_filsys_t * reiserfs_open (char * filename, int flags, int *error, void found: + if (!is_blocksize_correct(get_sb_block_size(sb))) { + reiserfs_warning(stderr, "reiserfs_open: a superblock with wrong parameters " + "was found in the block (%d).\n", i); + freemem (fs); + close (fd); + brelse(bh); + return NULL; + } + if (check) { /* A few checks of found super block. */ struct buffer_head *tmp_bh; - if (!is_blocksize_correct(get_sb_block_size(sb))) { - reiserfs_warning(stderr, "reiserfs_open: a superblock with wrong parameters " - "was found in the block (%d).\n", i); - freemem (fs); - close (fd); - brelse(bh); - return NULL; - } - tmp_bh = bread (fd, get_sb_block_count(sb) - 1, get_sb_block_size(sb)); if (!tmp_bh) { @@ -393,7 +394,9 @@ void reiserfs_close (reiserfs_filsys_t * fs) int reiserfs_new_blocknrs (reiserfs_filsys_t * fs, - unsigned long * free_blocknrs, unsigned long start, int amount_needed) + unsigned long * free_blocknrs, + unsigned long start, + int amount_needed) { if (fs->block_allocator) return fs->block_allocator (fs, free_blocknrs, start, amount_needed); @@ -432,6 +435,9 @@ static int reiserfs_search_by_key_x (reiserfs_filsys_t * fs, struct key * key, block = get_sb_root_block (fs->fs_ondisk_sb); + if (not_data_block(fs, block)) + return IO_ERROR; + path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET; while (1) { curr = PATH_OFFSET_PELEMENT (path, ++ path->path_length); @@ -457,6 +463,8 @@ static int reiserfs_search_by_key_x (reiserfs_filsys_t * fs, struct key * key, return ITEM_NOT_FOUND; } block = get_dc_child_blocknr (B_N_CHILD (bh, curr->pe_position)); + if (not_data_block(fs, block)) + return IO_ERROR; } printf ("search_by_key: you can not get here\n"); return ITEM_NOT_FOUND; @@ -648,15 +656,7 @@ struct key * uget_rkey (struct path * path) return 0; } -struct key * get_next_key_2 (struct path * path) -{ - if (PATH_LAST_POSITION (path) < B_NR_ITEMS (get_bh (path)) - 1) - return B_N_PKEY (get_bh (path), PATH_LAST_POSITION (path) + 1); - return uget_rkey (path); -} - -struct key * reiserfs_next_key (struct path * path) -{ +struct key * reiserfs_next_key (struct path * path) { if (get_item_pos (path) < B_NR_ITEMS (get_bh (path)) - 1) return B_N_PKEY (get_bh (path), get_item_pos (path) + 1); @@ -1141,6 +1141,7 @@ int create_dir_sd (reiserfs_filsys_t * fs, else key_format = KEY_FORMAT_2; + memset(&sd, 0, sizeof(sd)); make_dir_stat_data (fs->fs_blocksize, key_format, get_key_dirid (key), get_key_objectid (key), &ih, &sd); @@ -1196,24 +1197,24 @@ int can_we_format_it (char * device_name, int force) dev_t rdev; - if (is_mounted (device_name)) { + if (misc_device_mounted(device_name) > 0) { /* device looks mounted */ reiserfs_warning (stderr, "'%s' looks mounted.", device_name); check_forcing_ask_confirmation (force); } - mode = get_st_mode (device_name); - rdev = get_st_rdev (device_name); + mode = misc_device_mode(device_name); + rdev = misc_device_rdev(device_name); if (!S_ISBLK (mode)) { /* file is not a block device */ - reiserfs_warning (stderr, "%s is not a block special device", device_name); + reiserfs_warning (stderr, "%s is not a block special device\n", device_name); check_forcing_ask_confirmation (force); } else { if ((IDE_DISK_MAJOR (MAJOR(rdev)) && MINOR(rdev) % 64 == 0) || (SCSI_BLK_MAJOR (MAJOR(rdev)) && MINOR(rdev) % 16 == 0)) { /* /dev/hda or similar */ - reiserfs_warning (stderr, "%s is entire device, not just one partition!", + reiserfs_warning (stderr, "%s is entire device, not just one partition!\n", device_name); check_forcing_ask_confirmation (force); } @@ -1228,16 +1229,20 @@ int create_badblock_bitmap (reiserfs_filsys_t * fs, char * badblocks_file) { __u32 blocknr; int count; + fs->fs_badblocks_bm = reiserfs_create_bitmap(get_sb_block_count(fs->fs_ondisk_sb)); + reiserfs_bitmap_zero (fs->fs_badblocks_bm); + + if (!badblocks_file) + return 0; + fd = fopen (badblocks_file, "r"); if (fd == NULL) { - fprintf (stderr, "%s: could not open badblock file %s, work without it\n", + fprintf (stderr, "%s: Failed to open the given badblock file '%s'.\n\n", __FUNCTION__, badblocks_file); return 1; } - fs->fs_badblocks_bm = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); - reiserfs_bitmap_zero (fs->fs_badblocks_bm); while (!feof (fd)) { if (fgets(buf, sizeof(buf), fd) == NULL) @@ -1247,12 +1252,18 @@ int create_badblock_bitmap (reiserfs_filsys_t * fs, char * badblocks_file) { if (count <= 0) continue; - if (blocknr < get_sb_block_count (fs->fs_ondisk_sb) && !not_data_block (fs, blocknr)) { - reiserfs_bitmap_set_bit (fs->fs_badblocks_bm, blocknr); + if (blocknr >= get_sb_block_count (fs->fs_ondisk_sb)) { + fprintf (stderr, "%s: block number (%u) points out of fs size " + "(%u).\n", __FUNCTION__, blocknr, + get_sb_block_count(fs->fs_ondisk_sb)); + } else if (not_data_block (fs, blocknr)) { + fprintf (stderr, "%s: block number (%u) belongs to system " + "reiserfs area. It cannot be relocated.\n", + __FUNCTION__, blocknr); + return 1; } else { - fprintf (stderr, "%s: block number %u belongs to internal reiserfs structures.\n", - __FUNCTION__, blocknr); - } + reiserfs_bitmap_set_bit (fs->fs_badblocks_bm, blocknr); + } } fclose (fd); @@ -1260,13 +1271,98 @@ int create_badblock_bitmap (reiserfs_filsys_t * fs, char * badblocks_file) { return 0; } -void add_badblock_list (reiserfs_filsys_t * fs, int no_badblock_in_tree_yet) { +void badblock_list(reiserfs_filsys_t * fs, badblock_func_t action, void *data) { + struct path badblock_path; + struct key rd_key = badblock_key; + struct key *key; + + badblock_path.path_length = ILLEGAL_PATH_ELEMENT_OFFSET; + set_type_and_offset (KEY_FORMAT_2, &badblock_key, 1, TYPE_INDIRECT); + + while (1) { + if (reiserfs_search_by_key_4 (fs, &rd_key, &badblock_path) == IO_ERROR) { + fprintf (stderr, "%s: Some problems while searching by the key " + "occured. Probably due to tree corruptions.\n", + __FUNCTION__); + pathrelse (&badblock_path); + break; + } + + + if (get_blkh_nr_items (B_BLK_HEAD (get_bh (&badblock_path))) <= + PATH_LAST_POSITION (&badblock_path)) + { + pathrelse (&badblock_path); + break; + } + + rd_key = get_ih(&badblock_path)->ih_key; + + if (get_key_dirid(&rd_key) != BADBLOCK_DIRID || + get_key_objectid(&rd_key) != BADBLOCK_OBJID || + !KEY_IS_INDIRECT_KEY(&rd_key)) + { + pathrelse (&badblock_path); + break; + } + + if ((key = reiserfs_next_key(&badblock_path))) + rd_key = *key; + else + memset(&rd_key, 0, sizeof(rd_key)); + + action(fs, &badblock_path, data); + + if (get_key_dirid(&rd_key) == 0) + break; + } +} + +static void callback_badblock_rm(reiserfs_filsys_t *fs, + struct path *badblock_path, + void *data) +{ + struct tree_balance tb; + struct item_head * tmp_ih; + + tmp_ih = get_ih(badblock_path); + memset (get_item (badblock_path), 0, get_ih_item_len (tmp_ih)); + + init_tb_struct (&tb, fs, badblock_path, + -(IH_SIZE + get_ih_item_len(PATH_PITEM_HEAD(badblock_path)))); + + if (fix_nodes (M_DELETE, &tb, 0) != CARRY_ON) + die ("%s: fix_nodes failed", __FUNCTION__); + + do_balance (/*tb.transaction_handle,*/ &tb, 0, 0, M_DELETE, 0/*zero num*/); +} + +void mark_badblock(reiserfs_filsys_t *fs, + struct path *badblock_path, + void *data) +{ + struct item_head *tmp_ih; + __u32 *ind_item; + __u32 i; + + if (!fs->fs_badblocks_bm) + create_badblock_bitmap(fs, NULL); + + tmp_ih = get_ih(badblock_path); + ind_item = (__u32 *)get_item(badblock_path); + + for (i = 0; i < I_UNFM_NUM(tmp_ih); i++, ind_item++) { + reiserfs_bitmap_set_bit(fs->fs_badblocks_bm, + le32_to_cpu(*ind_item)); + } + + pathrelse (badblock_path); +} + +void add_badblock_list (reiserfs_filsys_t * fs, int replace) { struct tree_balance tb; - struct key badblock_key = {-1, -1, {{0, 0}}}; struct path badblock_path; - struct item_head * tmp_ih; struct item_head badblock_ih; -// char item[UNFM_P_SIZE]; __u32 ni; __u64 offset; @@ -1276,42 +1372,16 @@ void add_badblock_list (reiserfs_filsys_t * fs, int no_badblock_in_tree_yet) { return; /* delete all items with badblock_key */ - while (1) { - reiserfs_search_by_key_4 (fs, &badblock_key, &badblock_path); - - if (get_blkh_nr_items ( B_BLK_HEAD (get_bh(&badblock_path))) <= PATH_LAST_POSITION (&badblock_path)) { - pathrelse (&badblock_path); - break; - } - - tmp_ih = get_ih(&badblock_path); - - if (get_key_dirid(&tmp_ih->ih_key) != (__u32)-1 || - get_key_objectid(&tmp_ih->ih_key) != (__u32)-1 || !is_indirect_ih (tmp_ih)) { - pathrelse (&badblock_path); - break; - } - - if (no_badblock_in_tree_yet) - reiserfs_panic ("$s: bad block list found in the tree\n", __FUNCTION__); - - memset (get_item (&badblock_path), 0, get_ih_item_len (tmp_ih)); - - - init_tb_struct (&tb, fs, &badblock_path, -(IH_SIZE + get_ih_item_len(PATH_PITEM_HEAD (&badblock_path)))); - - if (fix_nodes (M_DELETE, &tb, 0) != CARRY_ON) - die ("%s: fix_nodes failed", __FUNCTION__); - - do_balance (/*tb.transaction_handle,*/ &tb, 0, 0, M_DELETE, 0/*zero num*/); - } + if (replace) + badblock_list(fs, callback_badblock_rm, NULL); + memset(&badblock_ih, 0, sizeof(badblock_ih)); set_ih_key_format (&badblock_ih, KEY_FORMAT_2); set_ih_item_len (&badblock_ih, UNFM_P_SIZE); set_ih_free_space (&badblock_ih, 0); set_ih_location (&badblock_ih, 0); - set_key_dirid (&badblock_ih.ih_key, -1); - set_key_objectid (&badblock_ih.ih_key, -1); + set_key_dirid (&badblock_ih.ih_key, BADBLOCK_DIRID); + set_key_objectid (&badblock_ih.ih_key, BADBLOCK_OBJID); set_type (KEY_FORMAT_2, &badblock_ih.ih_key, TYPE_INDIRECT); j = 0; @@ -1327,21 +1397,25 @@ void add_badblock_list (reiserfs_filsys_t * fs, int no_badblock_in_tree_yet) { set_offset (KEY_FORMAT_2, &badblock_ih.ih_key, offset); ni = cpu_to_le32 (i); - retval = usearch_by_position (fs, &badblock_ih.ih_key, key_format (&badblock_ih.ih_key), &badblock_path); + retval = usearch_by_position (fs, &badblock_ih.ih_key, + key_format(&badblock_ih.ih_key), + &badblock_path); switch (retval) { case (FILE_NOT_FOUND): - init_tb_struct (&tb, fs, &badblock_path, IH_SIZE + get_ih_item_len(&badblock_ih)); - if (fix_nodes (/*tb.transaction_handle,*/ M_INSERT, &tb, &badblock_ih/*, body*/) != CARRY_ON) - die ("reiserfsck_insert_item: fix_nodes failed"); - do_balance (/*tb.transaction_handle,*/ &tb, &badblock_ih, (void *)&ni , M_INSERT, 0/*zero num*/); - -// reiserfsck_insert_item (&badblock_path, &badblock_ih, item); + init_tb_struct (&tb, fs, &badblock_path, + IH_SIZE + get_ih_item_len(&badblock_ih)); + if (fix_nodes (M_INSERT, &tb, &badblock_ih) != CARRY_ON) + die ("reiserfsck_insert_item: fix_nodes failed"); + + do_balance (&tb, &badblock_ih, (void *)&ni , M_INSERT, 0); + break; case (POSITION_NOT_FOUND): - /* take unformatted pointer from an indirect item */ + case (POSITION_FOUND): + /* Insert the new item to the found position. */ init_tb_struct (&tb, fs, &badblock_path, UNFM_P_SIZE); @@ -1349,10 +1423,6 @@ void add_badblock_list (reiserfs_filsys_t * fs, int no_badblock_in_tree_yet) { die ("reiserfsck_paste_into_item: fix_nodes failed"); do_balance (&tb, 0, (const char *)&ni, M_PASTE, 0); - -// reiserfsck_file_write (&badblock_ih, item, 1 /* was in tree to avoid problems with bitmaps */); -// reiserfsck_paste_into_item (path, (const char *)&ni, UNFM_P_SIZE); - break; } diff --git a/reiserfscore/stree.c b/reiserfscore/stree.c index 227b6cf..f13598d 100644 --- a/reiserfscore/stree.c +++ b/reiserfscore/stree.c @@ -1,5 +1,5 @@ /* - * Copyright 1996-2003 by Hans Reiser, licensing governed by + * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ diff --git a/reiserfsprogs.spec b/reiserfsprogs.spec index bd3cdb9..28695a2 100644 --- a/reiserfsprogs.spec +++ b/reiserfsprogs.spec @@ -1,10 +1,10 @@ -%define reiserfsprogsversion 3.6.9 +%define reiserfsprogsversion 3.6.13 Vendor: Hans Reiser Distribution: Hans Reiser Name: reiserfsprogs Release: 1 -Copyright: 2003 Hans Reiser +Copyright: 2004 Hans Reiser Group: Unsorted Packager: anthon@mnt.org diff --git a/resize_reiserfs/Makefile.in b/resize_reiserfs/Makefile.in index 06d7bd4..a875367 100644 --- a/resize_reiserfs/Makefile.in +++ b/resize_reiserfs/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/resize_reiserfs/do_shrink.c b/resize_reiserfs/do_shrink.c index 2b4bdc4..bf34a67 100644 --- a/resize_reiserfs/do_shrink.c +++ b/resize_reiserfs/do_shrink.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -111,6 +111,12 @@ static unsigned long move_formatted_block(reiserfs_filsys_t * fs, unsigned long for (i = 0; i < B_NR_ITEMS(bh); i++) { ih = B_N_PITEM_HEAD(bh, i); + + /* skip the bad blocks. */ + if (get_key_objectid (&ih->ih_key) == BADBLOCK_OBJID && + get_key_dirid (&ih->ih_key) == BADBLOCK_DIRID) + continue; + if (is_indirect_ih(ih)) { __u32 * indirect; @@ -163,14 +169,27 @@ static unsigned long move_formatted_block(reiserfs_filsys_t * fs, unsigned long return new_blocknr; } -int shrink_fs(reiserfs_filsys_t * fs, unsigned long blocks) +int shrink_fs(reiserfs_filsys_t * fs, long long int blocks) { unsigned long n_root_block; unsigned int bmap_nr_new; - + unsigned long bad_count; ondisk_sb = fs->fs_ondisk_sb; + + bmap_nr_new = (blocks - 1) / (8 * fs->fs_blocksize) + 1; + + /* is shrinking possible ? */ + if (get_sb_block_count(ondisk_sb) - blocks > + get_sb_free_blocks(ondisk_sb) + get_sb_bmap_nr(ondisk_sb) - + bmap_nr_new) + { + fprintf(stderr, "resize_reiserfs: can\'t shrink fs; too many " + "blocks already allocated\n"); + return -1; + } + /* warn about alpha version */ { int c; @@ -187,18 +206,6 @@ int shrink_fs(reiserfs_filsys_t * fs, unsigned long blocks) exit(1); } - bmap_nr_new = (blocks - 1) / (8 * fs->fs_blocksize) + 1; - - /* is shrinking possible ? */ - if (get_sb_block_count(ondisk_sb) - blocks > - get_sb_free_blocks(ondisk_sb) + get_sb_bmap_nr(ondisk_sb) - - bmap_nr_new) - { - fprintf(stderr, "resize_reiserfs: can\'t shrink fs; too many " - "blocks already allocated\n"); - return -1; - } - reiserfs_reopen(fs, O_RDWR); if (reiserfs_open_ondisk_bitmap (fs)) DIE("cannot open ondisk bitmap"); @@ -249,7 +256,6 @@ int shrink_fs(reiserfs_filsys_t * fs, unsigned long blocks) (unsigned long)total_node_cnt, blocks_used); } -#if 1 { unsigned long l; @@ -263,13 +269,23 @@ int shrink_fs(reiserfs_filsys_t * fs, unsigned long blocks) } printf("\n"); } -#endif + badblock_list(fs, mark_badblock, NULL); + + if (fs->fs_badblocks_bm) { + bad_count = reiserfs_bitmap_ones(fs->fs_badblocks_bm); + reiserfs_shrink_bitmap (fs->fs_badblocks_bm, blocks); + add_badblock_list(fs, 1); + bad_count -= reiserfs_bitmap_ones(fs->fs_badblocks_bm); + } else + bad_count = 0; + reiserfs_shrink_bitmap (fs->fs_bitmap2, blocks); set_sb_free_blocks (ondisk_sb, get_sb_free_blocks(ondisk_sb) - (get_sb_block_count(ondisk_sb) - blocks) - + (get_sb_bmap_nr(ondisk_sb) - bmap_nr_new)); + + (get_sb_bmap_nr(ondisk_sb) - bmap_nr_new) + + bad_count); set_sb_block_count (ondisk_sb, blocks); set_sb_bmap_nr (ondisk_sb, bmap_nr_new); diff --git a/resize_reiserfs/fe.c b/resize_reiserfs/fe.c index f405975..5b65117 100644 --- a/resize_reiserfs/fe.c +++ b/resize_reiserfs/fe.c @@ -1,37 +1,28 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ #include "resize.h" /* the front-end for kernel on-line resizer */ -int resize_fs_online(char * devname, unsigned long blocks) -{ - static char buf[40]; - FILE * f; - struct mntent * mnt; +int resize_fs_online(char * devname, long long int blocks) { + struct mntent *mnt; + char buf[40]; - if ((f = setmntent (MOUNTED, "r")) == NULL) - goto fail; + /* Find the mount entry. */ + if ((mnt = misc_mntent(devname)) == NULL) + die ("resize_reiserfs: can't find mount entry\n"); - while ((mnt = getmntent (f)) != NULL) - if(strcmp(devname, mnt->mnt_fsname) == 0) { + sprintf(buf,"resize=%lld", blocks); - if (strcmp(mnt->mnt_type,"reiserfs")) - die ("resize_reiserfs: can\'t resize fs other than reiserfs\n"); - - sprintf(buf,"resize=%lu", blocks); + if (mount(mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, + (unsigned long)(MS_MGC_VAL << 16 | MS_REMOUNT), buf)) + { + die ("resize_reiserfs: remount failed: %s\n", + strerror(errno)); + } - if (mount(mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, - (unsigned long)(MS_MGC_VAL | MS_REMOUNT), buf)) - die ("resize_reiserfs: remount failed: %s\n", strerror(errno)); - - endmntent(f); - return 0; - } -fail: - die ("resize_reiserfs: can't find mount entry\n"); - return 1; + return 0; } diff --git a/resize_reiserfs/resize.h b/resize_reiserfs/resize.h index fb37b5e..98f83c9 100644 --- a/resize_reiserfs/resize.h +++ b/resize_reiserfs/resize.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -31,7 +31,7 @@ #define print_usage_and_exit() {\ - fprintf (stderr, "Usage: %s [-s[+|-]#[G|M|K]] [-fqv] device\n\n", argv[0]);\ + fprintf (stderr, "Usage: %s [-s[+|-]#[G|M|K]] [-fqvV] device\n\n", argv[0]);\ exit(16);\ } @@ -47,7 +47,7 @@ extern int opt_nowrite; extern int opt_safe; /* fe.c */ -int resize_fs_online(char * devname, unsigned long blocks); +extern int resize_fs_online(char * devname, long long int blocks); /* do_shrink.c */ -int shrink_fs(reiserfs_filsys_t *, unsigned long blocks); +extern int shrink_fs(reiserfs_filsys_t *, long long int blocks); diff --git a/resize_reiserfs/resize_reiserfs.8 b/resize_reiserfs/resize_reiserfs.8 index b74a99a..2ddbd6f 100644 --- a/resize_reiserfs/resize_reiserfs.8 +++ b/resize_reiserfs/resize_reiserfs.8 @@ -1,9 +1,9 @@ .\" -*- nroff -*- -.\" Copyright 1996-2003 Hans Reiser. +.\" Copyright 1996-2004 Hans Reiser. .\" -.TH RESIZE_REISERFS 8 "April 2003" "Reiserfsprogs-3.6.9" +.TH RESIZE_REISERFS 8 "January 2004" "Reiserfsprogs-3.6.13" .SH NAME -resize_reiserfs \- Reiserfs filesystem resizer +resize_reiserfs \- resizer tool for the ReiserFS filesystem .SH SYNOPSIS .BR resize_reiserfs [ diff --git a/resize_reiserfs/resize_reiserfs.c b/resize_reiserfs/resize_reiserfs.c index 76009c1..690ed1b 100644 --- a/resize_reiserfs/resize_reiserfs.c +++ b/resize_reiserfs/resize_reiserfs.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 by Hans Reiser, licensing governed by + * Copyright 2000-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -11,8 +11,9 @@ */ #include "resize.h" -#include +#include +int opt_banner = 0; int opt_force = 0; int opt_verbose = 1; /* now "verbose" option is default */ int opt_nowrite = 0; @@ -23,17 +24,26 @@ char * g_progname; /* calculate the new fs size (in blocks) from old fs size and the string representation of new size */ -static unsigned long calc_new_fs_size(unsigned long count, int bs, +static long long int calc_new_fs_size(unsigned long count, + unsigned int bs, char *bytes_str) { long long int bytes; - unsigned long blocks; - int c; - - bytes = atoll(bytes_str); - c = bytes_str[strlen(bytes_str) - 1]; + long long int blocks; + char *end; + int rel; - switch (c) { + end = bytes_str + strlen(bytes_str) - 1; + rel = bytes_str[0] == '+' || bytes_str[0] == '-'; + bytes = strtoll(bytes_str, &bytes_str, 10); + + /* Some error occured while convertion or the specified + string is not valid. */ + if (bytes == LONG_LONG_MIN || bytes == LONG_LONG_MAX || + (bytes_str != end && bytes_str != end + 1)) + return -EINVAL; + + switch (*end) { case 'G': case 'g': bytes *= 1024; @@ -47,10 +57,7 @@ static unsigned long calc_new_fs_size(unsigned long count, int bs, blocks = bytes / bs; - if (bytes_str[0] == '+' || bytes_str[0] == '-') - return (count + blocks); - - return blocks; + return rel ? count + blocks : blocks; } /* print some fs parameters */ @@ -82,7 +89,7 @@ static int bwrite_cond (struct buffer_head * bh) /* the first one of the most important functions */ -static int expand_fs (reiserfs_filsys_t * fs, unsigned long block_count_new) { +static int expand_fs (reiserfs_filsys_t * fs, long long int block_count_new) { unsigned int bmap_nr_new, bmap_nr_old; struct reiserfs_super_block * sb; unsigned int i; @@ -131,6 +138,43 @@ static int expand_fs (reiserfs_filsys_t * fs, unsigned long block_count_new) { return 0; } +static int resizer_check_fs_size(reiserfs_filsys_t *fs, long long int new_size) { + if (new_size < 0) { + reiserfs_warning(stderr, "\nresizer_reiserfs: the new size " + "value is wrong.\n\n"); + return new_size; + } + + if (new_size == get_sb_block_count(fs->fs_ondisk_sb)) { + reiserfs_warning (stderr, "%s already is of the needed size. " + "Nothing to be done\n\n", fs->fs_file_name); + return 1; + } + + if (new_size < get_sb_block_count(fs->fs_ondisk_sb)) { + if (misc_device_mounted(fs->fs_file_name) > 0) { + reiserfs_warning (stderr, "Can't shrink filesystem on-line.\n\n"); + return 1; + } + } + + if (new_size >= get_sb_block_count(fs->fs_ondisk_sb)) { + loff_t offset = (loff_t)new_size * fs->fs_blocksize - 1; + + if(!valid_offset(fs->fs_dev, offset)) { + reiserfs_warning (stderr, "%s is of %lu blocks size only with " + "reiserfs of %d blocks\nsize on it. You are " + "trying to expand reiserfs up to %lu blocks " + "size.\nYou probably forgot to expand your " + "partition size.\n\n", fs->fs_file_name, + count_blocks(fs->fs_file_name, fs->fs_blocksize), + get_sb_block_count(fs->fs_ondisk_sb), new_size); + return 1; + } + } + + return 0; +} int main(int argc, char *argv[]) { char * bytes_count_str = NULL; @@ -144,12 +188,14 @@ int main(int argc, char *argv[]) { struct reiserfs_super_block *sb_old; - unsigned long block_count_new; + long long int block_count_new; g_progname = basename(argv[0]); - print_banner (g_progname); + + if (argc < 2) + print_usage_and_exit(); - while ((c = getopt(argc, argv, "fvcqks:j:")) != EOF) { + while ((c = getopt(argc, argv, "fvcqks:j:V")) != EOF) { switch (c) { case 's' : if (!optarg) @@ -179,13 +225,20 @@ int main(int argc, char *argv[]) { case 'k': opt_skipj = 1; break; + case 'V': + opt_banner++; + break; default: print_usage_and_exit (); } } - if (optind == argc ) - print_usage_and_exit(); + print_banner (g_progname); + + if (opt_banner) + exit(0); + + devname = argv[optind]; fs = reiserfs_open(devname, O_RDONLY, &error, 0, 1); @@ -212,22 +265,22 @@ int main(int argc, char *argv[]) { } sb = fs->fs_ondisk_sb; - - if(bytes_count_str) { /* new fs size is specified by user */ - block_count_new = calc_new_fs_size(get_sb_block_count(sb), - fs->fs_blocksize, bytes_count_str); - } else { /* use whole device */ - block_count_new = count_blocks(devname, fs->fs_blocksize); - } - if (is_mounted (devname)) { + /* If size change was specified by user, calculate it, + otherwise take the whole device. */ + block_count_new = bytes_count_str ? + calc_new_fs_size(get_sb_block_count(sb), + fs->fs_blocksize, bytes_count_str) : + count_blocks(devname, fs->fs_blocksize); + + if (resizer_check_fs_size(fs, block_count_new)) + return 1; + + if (misc_device_mounted(devname) > 0) { reiserfs_close(fs); - if ((error = resize_fs_online(devname, block_count_new))) - reiserfs_warning(stderr, "\n\nresize_reiserfs: On-line resizing " - "failed.\n\n "); - else - reiserfs_warning(stderr, "\n\nresize_reiserfs: On-line resizing " - "finished successfully.\n\n "); + error = resize_fs_online(devname, block_count_new); + reiserfs_warning(stderr, "\n\nresize_reiserfs: On-line resizing %s.\n\n", + error ? "failed" : "finished successfully"); return error; } @@ -242,26 +295,6 @@ int main(int argc, char *argv[]) { /* fixme: shouldn't we check for something like: fsck guarantees: fs is ok */ DIE ("the file system isn't in valid state."); - if (block_count_new >= get_sb_block_count(sb)) { - if (block_count_new == get_sb_block_count(sb)) { - reiserfs_warning (stderr, "%s already is of the needed size. " - "Nothing to be done\n\n", devname); - exit (1); - } - - if(!valid_offset(fs->fs_dev, - (loff_t)block_count_new * fs->fs_blocksize - 1)) - { - reiserfs_warning (stderr, "%s is of %lu blocks size only with " - "reiserfs of %d blocks\nsize on it. You are trying to expand " - "reiserfs up to %lu blocks size.\nYou probably forgot to " - "expand your partition size.\n\n", devname, - count_blocks(devname, fs->fs_blocksize), - get_sb_block_count(sb), block_count_new); - exit (1); - } - } - /* Needed to keep idiot compiler from issuing false warning */ sb_old = 0; diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index f57a5a9..0000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -SUBDIRS = PROGS - -sbin_PROGRAMS = - diff --git a/tests/Makefile.in b/tests/Makefile.in deleted file mode 100644 index f058c5b..0000000 --- a/tests/Makefile.in +++ /dev/null @@ -1,418 +0,0 @@ -# Makefile.in generated by automake 1.7.2 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__include = @am__include@ -am__quote = @am__quote@ -bindir = @bindir@ -build_alias = @build_alias@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -SUBDIRS = PROGS - -sbin_PROGRAMS = -subdir = tests -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/include/config.h -CONFIG_CLEAN_FILES = -sbin_PROGRAMS = -PROGRAMS = $(sbin_PROGRAMS) - -DIST_SOURCES = - -RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ - ps-recursive install-info-recursive uninstall-info-recursive \ - all-recursive install-data-recursive install-exec-recursive \ - installdirs-recursive install-recursive uninstall-recursive \ - check-recursive installcheck-recursive -DIST_COMMON = Makefile.am Makefile.in -DIST_SUBDIRS = $(SUBDIRS) -all: all-recursive - -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu tests/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \ - else :; fi; \ - done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ - rm -f $(DESTDIR)$(sbindir)/$$f; \ - done - -clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) -uninstall-info-am: - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @set fnord $$MAKEFLAGS; amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $$MAKEFLAGS; amf=$$2; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ETAGS = etags -ETAGSFLAGS = - -CTAGS = ctags -CTAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = .. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - (cd $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" \ - distdir=../$(distdir)/$$subdir \ - distdir) \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-recursive -all-am: Makefile $(PROGRAMS) -installdirs: installdirs-recursive -installdirs-am: - $(mkinstalldirs) $(DESTDIR)$(sbindir) - -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am - -distclean: distclean-recursive - -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-recursive - -dvi-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-exec-am: install-sbinPROGRAMS - -install-info: install-info-recursive - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS - -uninstall-info: uninstall-info-recursive - -.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \ - clean-generic clean-recursive clean-sbinPROGRAMS ctags \ - ctags-recursive distclean distclean-generic distclean-recursive \ - distclean-tags distdir dvi dvi-am dvi-recursive info info-am \ - info-recursive install install-am install-data install-data-am \ - install-data-recursive install-exec install-exec-am \ - install-exec-recursive install-info install-info-am \ - install-info-recursive install-man install-recursive \ - install-sbinPROGRAMS install-strip installcheck installcheck-am \ - installdirs installdirs-am installdirs-recursive \ - maintainer-clean maintainer-clean-generic \ - maintainer-clean-recursive mostlyclean mostlyclean-generic \ - mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \ - ps-recursive tags tags-recursive uninstall uninstall-am \ - uninstall-info-am uninstall-info-recursive uninstall-recursive \ - uninstall-sbinPROGRAMS - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/tests/PROGS/Makefile.am b/tests/PROGS/Makefile.am deleted file mode 100644 index f553f7d..0000000 --- a/tests/PROGS/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -sbin_PROGRAMS = reiserfs_corrupter - -SOURCES = corrupter.c -LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a - diff --git a/tests/PROGS/Makefile.in b/tests/PROGS/Makefile.in deleted file mode 100644 index 5b69df6..0000000 --- a/tests/PROGS/Makefile.in +++ /dev/null @@ -1,382 +0,0 @@ -# Makefile.in generated by automake 1.7.2 from Makefile.am. -# @configure_input@ - -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = ../.. - -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__include = @am__include@ -am__quote = @am__quote@ -bindir = @bindir@ -build_alias = @build_alias@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -sbin_PROGRAMS = reiserfs_corrupter - -SOURCES = corrupter.c -LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a -subdir = tests/PROGS -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/include/config.h -CONFIG_CLEAN_FILES = -sbin_PROGRAMS = reiserfs_corrupter$(EXEEXT) -PROGRAMS = $(sbin_PROGRAMS) - -reiserfs_corrupter_SOURCES = reiserfs_corrupter.c -reiserfs_corrupter_OBJECTS = reiserfs_corrupter.$(OBJEXT) -reiserfs_corrupter_LDADD = $(LDADD) -reiserfs_corrupter_DEPENDENCIES = $(top_srcdir)/lib/libmisc.a \ - $(top_srcdir)/reiserfscore/libcore.a -reiserfs_corrupter_LDFLAGS = - -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/reiserfs_corrupter.Po -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -DIST_SOURCES = reiserfs_corrupter.c -DIST_COMMON = Makefile.am Makefile.in -SOURCES = corrupter.c - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu tests/PROGS/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) -sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \ - $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \ - else :; fi; \ - done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \ - rm -f $(DESTDIR)$(sbindir)/$$f; \ - done - -clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) -reiserfs_corrupter$(EXEEXT): $(reiserfs_corrupter_OBJECTS) $(reiserfs_corrupter_DEPENDENCIES) - @rm -f reiserfs_corrupter$(EXEEXT) - $(LINK) $(reiserfs_corrupter_LDFLAGS) $(reiserfs_corrupter_OBJECTS) $(reiserfs_corrupter_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) core *.core - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_corrupter.Po@am__quote@ - -distclean-depend: - -rm -rf ./$(DEPDIR) - -.c.o: -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ -@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ -@am__fastdepCC_TRUE@ fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< - -.c.obj: -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ -@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ -@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ -@am__fastdepCC_TRUE@ fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` -uninstall-info-am: - -ETAGS = etags -ETAGSFLAGS = - -CTAGS = ctags -CTAGSFLAGS = - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique - -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -top_distdir = ../.. -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkinstalldirs) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(sbindir) - -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am - -distclean: distclean-am - -distclean-am: clean-am distclean-compile distclean-depend \ - distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: install-sbinPROGRAMS - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-sbinPROGRAMS ctags distclean distclean-compile \ - distclean-depend distclean-generic distclean-tags distdir dvi \ - dvi-am info info-am install install-am install-data \ - install-data-am install-exec install-exec-am install-info \ - install-info-am install-man install-sbinPROGRAMS install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-info-am uninstall-sbinPROGRAMS - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/tests/PROGS/reiserfs_corrupter.c b/tests/PROGS/reiserfs_corrupter.c deleted file mode 100644 index 3dc24d0..0000000 --- a/tests/PROGS/reiserfs_corrupter.c +++ /dev/null @@ -1,198 +0,0 @@ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "io.h" -#include "misc.h" -#include "reiserfs_lib.h" - -enum { - USED_BLOCKS, - ALL_BLOCKS, - EXTERN_BITMAP -}; - -typedef struct corrupter_options { - int bitmap_kind; - char * bm_name; - reiserfs_bitmap_t * bm; - int block_size; - int offset; -} corrupter_options_t; - -#define print_usage_and_exit() {\ -printf ("\nUsage: %s [options] device\n"\ -"Options:\n"\ -" -b bitmap\t\tscan blocks marked in bitmap\n"\ -" -S\t\t\tscan-whole-partition\n"\ -" -s blocksize\t\tfs blocksize\n"\ -" -o bitmap\t\tskip offset blocks\n\n"\ - , argv[0]);\ - exit (16);\ -} - -static char * parse_options (corrupter_options_t * options, int argc, char * argv []) -{ - int c; - options->bitmap_kind = USED_BLOCKS; - options->block_size = 4096; - options->offset = 0; - options->bm_name = NULL; - options->bm = NULL; - - while (1) { - int option_index; - - c = getopt_long (argc, argv, "Sb:s:o:", - NULL, &option_index); - if (c == -1) - break; - - switch (c) { - case 0: - /* long-only options */ - - break; - - case 'b': /* --scan-marked-in-bitmap */ - options->bitmap_kind = EXTERN_BITMAP; - options->bm_name = optarg; - break; - - case 'S': /* --scan-whole-partition */ - options->bitmap_kind = ALL_BLOCKS; - break; - - case 'o': /* --scan-marked-in-bitmap */ - options->offset = atoi (optarg); - break; - - case 's': /* --scan-marked-in-bitmap */ - options->block_size = atoi (optarg); - break; - - default: - print_usage_and_exit(); - } - } - - if (optind != argc - 1) - print_usage_and_exit(); - - return argv[optind]; -} - -void load_bitmap_from_file (corrupter_options_t * options) { - FILE * fd; - - fd = fopen (options->bm_name, "r"); - - if (!fd) - reiserfs_panic ("%s: could not load bitmap: %s\n", __FUNCTION__, strerror(errno)); - - options->bm = reiserfs_bitmap_load (fd); - - if (!options->bm) - reiserfs_panic ("could not load fitmap from \"%s\"", options->bm_name); - - fclose (fd); -} - -void warn_what_will_be_done (corrupter_options_t * options, char * file_name, int bl_count) { - printf ("====================\n"); - printf ("\tprogram will corrupt %s\n", file_name); - printf ("\tblock size is %d\n", options->block_size); - printf ("\toffset is %d blocks\n", options->offset); - - if (options->bitmap_kind == ALL_BLOCKS) { - printf ("\tall formatted blocks, bitmap and journal blocks will be corrupted\n"); - } else if (options->bitmap_kind == USED_BLOCKS) { - printf ("\tall formatted blocks, bitmap and journal blocks which are used in fs bitmap will be corrupted\n"); - } else if (options->bitmap_kind == EXTERN_BITMAP) { - printf ("\tall formatted blocks, bitmap and journal blocks from bitmap %s will be corrupted\n", options->bm_name); - } - - printf ("\tblocks count %d\n", bl_count); - printf ("====================\n"); -} - -int main (int argc, char * argv []) { - corrupter_options_t options; - char * file_name; - unsigned int block_count, i; - reiserfs_filsys_t * fs; - - file_name = parse_options (&options, argc, argv); - - fs = reiserfs_open (file_name, O_RDONLY, 0, &options, 1); - - if (no_reiserfs_found (fs)) - die ("could not open filesystem on \"%s\"", file_name); - - /* keep SB to separate memory */ - fs->fs_ondisk_sb = getmem(fs->fs_blocksize); - memcpy (fs->fs_ondisk_sb, fs->fs_super_bh->b_data, fs->fs_blocksize); - - block_count = get_sb_block_count (fs->fs_ondisk_sb); - - if (options.bm_name) { - load_bitmap_from_file (&options); - } else { - if (reiserfs_open_ondisk_bitmap (fs)) - die ("could not open bitmap\n"); - - options.bm = reiserfs_create_bitmap (fs->fs_bitmap2->bm_bit_size); - reiserfs_bitmap_copy (options.bm, fs->fs_bitmap2); - } - - if (options.bm && block_count > options.bm->bm_bit_size) { - printf ("fs is larger (%d blocks) then bitmap (%ld blocks), work with %ld blocks only\n", - block_count, options.bm->bm_bit_size, options.bm->bm_bit_size); - block_count = options.bm->bm_bit_size; - } - - warn_what_will_be_done (&options, file_name, block_count); - - for (i = options.offset; i < block_count; i++) { - int who; - struct buffer_head * bh; - /* read every block and corrupt all formatted blocks */ - if (!reiserfs_bitmap_test_bit (options.bm, i)) - continue; - - bh = bread (fs->fs_dev, i, fs->fs_blocksize); - - who = who_is_this (bh->b_data, bh->b_size); - - /* - if (block of bitmap || block of journal || leaf || internal) - take N random bytes and write them into N random place - within the block - */ - if (who != THE_SUPER && who != THE_LEAF && who != THE_INTERNAL && who != THE_JDESC && - !block_of_bitmap (fs, i) && !block_of_journal (fs, i)) - continue; - - printf ("\ncorrupt %d ", i); - } - - freemem(fs->fs_ondisk_sb); - - reiserfs_close (fs); - printf ("\nDone\n"); - return 0; -} diff --git a/tune/Makefile.in b/tune/Makefile.in index fb4d8d1..380caaf 100644 --- a/tune/Makefile.in +++ b/tune/Makefile.in @@ -77,6 +77,7 @@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ ac_ct_CC = @ac_ct_CC@ ac_ct_RANLIB = @ac_ct_RANLIB@ diff --git a/tune/reiserfstune.8 b/tune/reiserfstune.8 index 03d97e9..c44ed09 100644 --- a/tune/reiserfstune.8 +++ b/tune/reiserfstune.8 @@ -1,9 +1,9 @@ .\" -*- nroff -*- -.\" Copyright 1996-2003 Hans Reiser. +.\" Copyright 1996-2004 Hans Reiser. .\" -.TH REISERFSTUNE 8 "April 2003" "Reiserfsprogs-3.6.9" +.TH REISERFSTUNE 8 "February 2004" "Reiserfsprogs-3.6.13" .SH NAME -reiserfstune +reiserfstune \- tunning tool for the ReiserFS filesystem .SH SYNOPSIS .B reiserfstune [ \fB-f\fR ] @@ -13,6 +13,8 @@ reiserfstune [ \fB-s\fR | \fB--journal-new-size\fR \fIN\fR ] [ \fB-o\fR | \fB--journal-new-offset\fR \fIN\fR ] [ \fB-t\fR | \fB--max-transaction-size\fR \fIN\fR ] +[ \fB-b\fR | \fB--add-badblocks\fR \fIfile\fR ] +[ \fB-B\fR | \fB--badblocks\fR \fIfile\fR ] [ \fB-u\fR | \fB--uuid \fIUUID\fR ] [ \fB-l\fR | \fB--label \fILABEL\fR ] .I device @@ -72,11 +74,20 @@ multiple filesystems to reside on the same device, and you don't want to or cannot partition that device. .TP \fB \-t\fR | \fB\--maximal-transaction-size \fIN -\fI\fR is the maximum transaction size parameter for the new +\fIN\fR is the maximum transaction size parameter for the new journal. The default, and max possible, value is 1024 blocks. It should be less than half the size of the journal. If specifed incorrectly, it will be adjusted. .TP +\fB \-b\fR | \fB\--add-badblocks\fR \fIfile\fR +\fIFile\fR is the file name of the file that contains the list of blocks to be marked +as bad on the fs. The list is added to the fs list of bad blocks. +.TP +\fB \-B\fR | \fB\--badblocks\fR \fIfile\fR +\fIFile\fR is the file name of the file that contains the list of blocks to be marked +as bad on the fs. The bad block list on the fs is cleared before the list specified +in the \fIFile\fR is added to the fs. +.TP \fB\-f\fR | \fB--force\fR Normally \fBreiserfstune\fR will refuse to change a journal of a file system that was created before this journal relocation code. This diff --git a/tune/tune.c b/tune/tune.c index 44c6b6c..397664f 100644 --- a/tune/tune.c +++ b/tune/tune.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003 by Hans Reiser, licensing governed by + * Copyright 2002-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -31,34 +31,32 @@ reiserfs_filsys_t * fs; static void print_usage_and_exit(void) { - message ("Usage: %s [options] " - " device [block-count]\n" + message ("Usage: %s [options] device [block-count]\n" "\n" "Options:\n\n" - " -j | --journal-device file\n" - " --journal-new-device file\n" - " -o | --journal-new-offset N\n" - " -s | --journal-new-size N\n" - " -t | --transaction-max-size N\n" - " --no-journal-available\n" - " --make-journal-standard\n" + " -j | --journal-device file\tcurrent journal device\n" + " --journal-new-device file\tnew journal device\n" + " -o | --journal-new-offset N\tnew journal offset in blocks\n" + " -s | --journal-new-size N\tnew journal size in blocks\n" + " -t | --trans-max-size N\tnew journal max transaction size in blocks\n" + " --no-journal-available\tcurrent journal is not available\n" + " --make-journal-standard\tnew journal to be standard\n" /*"\t-p | --keep-old-journal-param (keep parametrs from old journal to new one)\n"*/ - " -u | --uuid UUID|random\n" - " -l | --label LABEL\n" - " -f | --force \n", program_name); + " -b | --add-badblocks file\tadd to bad block list\n" + " -B | --badblocks file\t\tset the bad block list\n" + " -u | --uuid UUID|random\tset new UUID\n" + " -l | --label LABEL\t\tset new label\n" + " -f | --force\t\t\tforce tuning, less confirmations\n" + " -V\t\t\t\tprint version and exit\n", program_name); exit (1); } -/* - Undocumented options: - -B badblock_file -*/ - unsigned long Journal_size = 0; int Max_trans_size = JOURNAL_TRANS_MAX; int Offset = 0; __u16 Options = 0; int Force = 0; +int Bads = 0; char * LABEL; unsigned char UUID[16]; char * badblocks_file; @@ -214,6 +212,104 @@ static void set_offset_in_journal_device (char * str) } +static void callback_new_badblocks(reiserfs_filsys_t *fs, + struct path *badblock_path, + void *data) +{ + struct item_head *tmp_ih; + __u32 *ind_item, i; + + tmp_ih = get_ih(badblock_path); + ind_item = (__u32 *)get_item(badblock_path); + + for (i = 0; i < I_UNFM_NUM(tmp_ih); i++, ind_item++) { + if (reiserfs_bitmap_test_bit(fs->fs_badblocks_bm, + le32_to_cpu(*ind_item))) + { + message("Block %u is marked as bad already.", + le32_to_cpu(*ind_item)); + + reiserfs_bitmap_clear_bit(fs->fs_badblocks_bm, + le32_to_cpu(*ind_item)); + } + } + + pathrelse (badblock_path); +} + +static void callback_clear_badblocks(reiserfs_filsys_t *fs, + struct path *badblock_path, + void *data) +{ + struct item_head *tmp_ih; + __u32 *ind_item, i; + + tmp_ih = get_ih(badblock_path); + ind_item = (__u32 *)get_item(badblock_path); + + for (i = 0; i < I_UNFM_NUM(tmp_ih); i++, ind_item++) { + reiserfs_bitmap_clear_bit(fs->fs_bitmap2, + le32_to_cpu(*ind_item)); + } + + pathrelse (badblock_path); +} + +static void add_badblocks(reiserfs_filsys_t *fs) { + unsigned long i, marked = 0; + + if (reiserfs_open_ondisk_bitmap (fs) < 0) { + message("Failed to open reiserfs ondisk bitmap.\n"); + reiserfs_close(fs); + exit(1); + } + + if (create_badblock_bitmap (fs, badblocks_file)) { + message("Failed to initialize the bad block bitmap.\n"); + reiserfs_close(fs); + exit(1); + } + + if (Bads == 1) + badblock_list(fs, callback_new_badblocks, NULL); + else + badblock_list(fs, callback_clear_badblocks, NULL); + + for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { + if (reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) { + if (!reiserfs_bitmap_test_bit (fs->fs_bitmap2, i)) { + reiserfs_bitmap_set_bit (fs->fs_bitmap2, i); + marked++; + } else { + /* Check that this is a block */ + message("Bad block %lu is used already in reiserfs tree. " + "To mark it as a bad block use reiserfsck\n" + "--fix-fixable with -B option.", i); + + reiserfs_bitmap_clear_bit (fs->fs_badblocks_bm, i); + } + } + } + + if (marked) { + set_sb_free_blocks(fs->fs_ondisk_sb, get_sb_free_blocks(fs->fs_ondisk_sb) - + fs->fs_badblocks_bm->bm_set_bits); + mark_buffer_dirty(fs->fs_super_bh); + } + + if (Bads == 1) { + /* fs->fs_badblocks_bm contains blocks which are not in the bad + block list yet. Merge it with what is in the tree already. */ + badblock_list(fs, mark_badblock, NULL); + } + + if (marked) { + add_badblock_list(fs, 1); + } + + message("%lu blocks were marked as bad.", marked); +} + int main (int argc, char **argv) { reiserfs_filsys_t * fs; @@ -233,8 +329,6 @@ int main (int argc, char **argv) else program_name = argv[ 0 ]; - print_banner (program_name); - if (argc < 2) print_usage_and_exit (); @@ -242,25 +336,28 @@ int main (int argc, char **argv) jdevice_name = 0; j_new_device_name = 0; + memset(UUID, 0, 16); + while (1) { static struct option options[] = { {"journal-device", required_argument, 0, 'j'}, {"journal-new-device", required_argument, &flag, OPT_NEW_J}, {"journal-new-size", required_argument, 0, 's'}, - {"transaction-max-size", required_argument, 0, 't'}, + {"trans-max-size", required_argument, 0, 't'}, {"journal-new-offset", required_argument, 0, 'o'}, {"no-journal-available", no_argument, &flag, OPT_SKIP_J}, /*{"keep-old-journal-param", no_argument, 0, 'p'},*/ {"uuid", required_argument, 0, 'u'}, {"label", required_argument, 0, 'l'}, + {"add-badblocks", required_argument, 0, 'b'}, + {"badblocks", required_argument, 0, 'B'}, {"force", no_argument, 0, 'f'}, - {"really-force", no_argument, &flag, OPT_SUPER_FORCE}, {"make-journal-standard", no_argument, &flag, OPT_STANDARD}, {0, 0, 0, 0} }; int option_index; - c = getopt_long (argc, argv, "j:s:t:o:fu:l:B:", + c = getopt_long (argc, argv, "j:s:t:o:fu:l:b:B:V", options, &option_index); if (c == -1) break; @@ -275,9 +372,6 @@ int main (int argc, char **argv) if (flag == OPT_SKIP_J) { Options |= OPT_SKIP_J; } - if (flag == OPT_SUPER_FORCE) { - Options |=OPT_SUPER_FORCE; - } if (flag == OPT_STANDARD) { Options |=OPT_STANDARD; } @@ -291,7 +385,7 @@ int main (int argc, char **argv) Is_journal_or_maxtrans_size_specified = 1; break; - case 't': /* --transaction-max-size */ + case 't': /* --trans-max-size */ set_transaction_max_size (optarg); Is_journal_or_maxtrans_size_specified = 1; break; @@ -306,26 +400,38 @@ int main (int argc, char **argv) confirmation */ Force ++; break; - case 'B': /* --badblock-list */ - asprintf (&badblocks_file, "%s", optarg); + case 'b': /* --add-badblocks */ + asprintf (&badblocks_file, "%s", optarg); + Bads = 1; + break; + case 'B': /* --badblocks */ + asprintf (&badblocks_file, "%s", optarg); + Bads = 2; break; case 'u': /* UUID */ +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) if (!strcmp(optarg, "random")) { - if (generate_random_uuid (UUID)) - message ("failed to genetate UUID\n"); + uuid_generate(UUID); } else { - if (set_uuid (optarg, UUID)) { - message ("wrong UUID specified\n"); + if (uuid_parse(optarg, UUID) < 0) { + message ("Invalid UUID '%s' was specified\n", optarg); return 1; } } - +#else + message ("Cannot set the UUID, uuidlib was not found " + "by configure.\n"); + return 1; +#endif break; case 'l': /* LABEL */ LABEL = optarg; break; + case 'V': + print_banner("reiserfstune"); + exit(0); #if 0 case 'J': /* --journal-new-device */ Options |= OPT_NEW_J; @@ -361,7 +467,7 @@ int main (int argc, char **argv) --no-journal-available has been specified by user */ /* make sure filesystem is not mounted */ - if (is_mounted (fs->fs_file_name)) { + if (misc_device_mounted(fs->fs_file_name) > 0) { /* fixme: it can not be mounted, btw */ message ("Reiserfstune is not allowed to be run on mounted filesystem."); reiserfs_close (fs); @@ -377,40 +483,7 @@ int main (int argc, char **argv) reiserfs_reopen (fs, O_RDWR); if (badblocks_file) { - unsigned long i, marked = 0; - - if (reiserfs_open_ondisk_bitmap (fs) < 0) { - message("Failed to open reiserfs ondisk bitmap.\n"); - reiserfs_close(fs); - exit(1); - } - - if (create_badblock_bitmap (fs, badblocks_file)) { - message("Failed to initialize the bad block bitmap.\n"); - reiserfs_close(fs); - exit(1); - } - - for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { - if (reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) { - if (!reiserfs_bitmap_test_bit (fs->fs_bitmap2, i)) { - reiserfs_bitmap_set_bit (fs->fs_bitmap2, i); - marked++; - } else { - /* Check that this is a block */ - if (not_data_block(fs, i)) { - message("Block %lu belongs to the internal reiserfs area " - "and cannot be reloacted.\n", i); - - exit(1); - } else { - message("Block %lu is used already in reiserfs tree.\n", i); - } - } - } - } - - message("%lu bad blocks were marked as used.\n", marked); + add_badblocks(fs); reiserfs_close(fs); exit(0); @@ -461,12 +534,10 @@ int main (int argc, char **argv) j_head = (struct reiserfs_journal_header *)(fs->fs_jh_bh->b_data); if (get_boundary_transactions(fs, &old, &new)) { if (new.trans_id != get_jh_last_flushed(j_head)) { - if (!(Options & OPT_SUPER_FORCE)) { - message ("There are non-replayed transaction in old journal," - " check filesystem consistency first"); - reiserfs_close (fs); - return 1; - } + message ("There are non-replayed transaction in old journal," + " check filesystem consistency first"); + reiserfs_close (fs); + return 1; } } if (!reiserfs_is_fs_consistent (fs)) { @@ -478,12 +549,13 @@ int main (int argc, char **argv) /* set UUID and LABEL if specified */ if (fs->fs_format == REISERFS_FORMAT_3_6) { - if (uuid_is_correct (UUID)) { +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + if (!uuid_is_null(UUID)) { memcpy (fs->fs_ondisk_sb->s_uuid, UUID, 16); mark_buffer_dirty (fs->fs_super_bh); fs->fs_dirt = 1; } - +#endif if (LABEL != NULL) { if (strlen (LABEL) > 16) message ("Specified LABEL is longer then 16 characters, will be truncated\n"); @@ -492,8 +564,10 @@ int main (int argc, char **argv) fs->fs_dirt = 1; } } else { - if (uuid_is_correct (UUID)) +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) + if (!uuid_is_null(UUID)) reiserfs_panic ("UUID cannot be specified for 3.5 format\n"); +#endif if (LABEL) reiserfs_panic ("LABEL cannot be specified for 3.5 format\n"); } diff --git a/tune/tune.h b/tune/tune.h index fb3cec2..26829d6 100644 --- a/tune/tune.h +++ b/tune/tune.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2003 by Hans Reiser, licensing governed by + * Copyright 2002-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ @@ -29,9 +29,9 @@ #include "../include/config.h" #include "../version.h" -/* main.c */ -extern reiserfs_filsys_t * fs; - +#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) +# include +#endif /* * options @@ -46,5 +46,3 @@ extern reiserfs_filsys_t * fs; #define OPT_KEEPO 0x4000 #define OPT_FORCE 0x8000 #define OPT_STANDARD 0x0020 - -extern char *program_name; diff --git a/version.h b/version.h index 86ec530..dd8dd95 100644 --- a/version.h +++ b/version.h @@ -1,7 +1,6 @@ /* - * Copyright 2002-2003 Hans Reiser, licensing governed by reiserfsprogs/README + * Copyright 2002-2004 Hans Reiser, licensing governed by reiserfsprogs/README */ #define print_banner(prog) \ -fprintf (stderr, "\n<-------------%s, 2003------------->\nreiserfsprogs %s\n\n", \ -prog, VERSION) +fprintf(stderr, "%s %s (2003 www.namesys.com)\n\n", prog, VERSION)