Imported reiserfsprogs-3.6.21

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:32:39 -04:00
1 parent dac518d099
commit 149a82e2e9
193 files changed
+32708 -44216

No files matched your search

+7
View File
@@ -0,0 +1,7 @@
sbin_PROGRAMS = debugreiserfs
debugreiserfs_SOURCES = debugreiserfs.c pack.c unpack.c stat.c corruption.c scan.c recover.c debugreiserfs.h
man_MANS = debugreiserfs.8
EXTRA_DIST = $(man_MANS)
LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
+485
View File
@@ -0,0 +1,485 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 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@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
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 = :
build_triplet = @build@
host_triplet = @host@
sbin_PROGRAMS = debugreiserfs$(EXEEXT)
subdir = debugreiserfs
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
am_debugreiserfs_OBJECTS = debugreiserfs.$(OBJEXT) pack.$(OBJEXT) \
unpack.$(OBJEXT) stat.$(OBJEXT) corruption.$(OBJEXT) \
scan.$(OBJEXT) recover.$(OBJEXT)
debugreiserfs_OBJECTS = $(am_debugreiserfs_OBJECTS)
debugreiserfs_LDADD = $(LDADD)
debugreiserfs_DEPENDENCIES = $(top_srcdir)/reiserfscore/libcore.a \
$(top_srcdir)/lib/libmisc.a
DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(debugreiserfs_SOURCES)
DIST_SOURCES = $(debugreiserfs_SOURCES)
man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(man_MANS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
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@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
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@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
debugreiserfs_SOURCES = debugreiserfs.c pack.c unpack.c stat.c corruption.c scan.c recover.c debugreiserfs.h
man_MANS = debugreiserfs.8
EXTRA_DIST = $(man_MANS)
LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu debugreiserfs/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu debugreiserfs/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(sbindir)" || $(MKDIR_P) "$(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)
debugreiserfs$(EXEEXT): $(debugreiserfs_OBJECTS) $(debugreiserfs_DEPENDENCIES)
@rm -f debugreiserfs$(EXEEXT)
$(LINK) $(debugreiserfs_OBJECTS) $(debugreiserfs_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corruption.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debugreiserfs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recover.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unpack.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
install-man8: $(man8_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
*) ext='8' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
done
uninstall-man8:
@$(NORMAL_UNINSTALL)
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.8*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
*) ext='8' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
done
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
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; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
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
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
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) $(MANS)
installdirs:
for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
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_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(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
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-exec-am: install-sbinPROGRAMS
install-html: install-html-am
install-info: install-info-am
install-man: install-man8
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
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-man uninstall-sbinPROGRAMS
uninstall-man: uninstall-man8
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-sbinPROGRAMS ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-man8 install-pdf \
install-pdf-am install-ps install-ps-am 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-man uninstall-man8 \
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:
File diff suppressed because it is too large. Load diff
+97
View File
@@ -0,0 +1,97 @@
.\" -*- nroff -*-
.\" Copyright 1996-2004 Hans Reiser.
.\"
.TH DEBUGREISERFS 8 "January 2009" "Reiserfsprogs 3.6.21"
.SH NAME
debugreiserfs \- The debugging tool for the ReiserFS filesystem.
.SH SYNOPSIS
.B debugreiserfs
[
.B -dDJmoqpuSV
] [
.B -j \fIdevice
] [
.B -B \fIfile
] [
.B -1 \fIN
]
.\" ] [
.\" .B -s
.\" ] [
.I device
.SH DESCRIPTION
\fBdebugreiserfs\fR sometimes helps to solve problems with reiserfs filesystems.
When run without options it prints the super block of the ReiserFS filesystem found
on the \fIdevice\fR.
.TP
.I device
is the special file corresponding to the device (e.g /dev/hdXX for
an IDE disk partition or /dev/sdXX for a SCSI disk partition).
.SH OPTIONS
.TP
\fB-j\fR \fIdevice\fR
prints the contents of the journal. The option -p allows it to pack the journal
with other metadata into the archive.
.TP
\fB-J\fR
prints the journal header.
.TP
.B -d
prints the formatted nodes of the internal tree of the filesystem.
.TP
.B -D
prints the formatted nodes of all used blocks of the filesystem.
.TP
.B -m
prints the contents of the bitmap (slightly useful).
.TP
.B -o
prints the objectid map (slightly useful).
.TP
\fB-B\fR \fIfile\fR
takes the list of bad blocks stored in the internal ReiserFS tree and translates it
into an ascii list written to the specified file.
.TP
\fB-1\fR \fIblocknumber\fR
prints the specified block of the filesystem.
.TP
.\" \fB-s
.\" scans the partition and prints a line when any kind of reiserfs
.\" formatted nodes found. Can be used to find specific key in the filesystem.
.\" .TP
.B -p
extracts the filesystem's metadata with \fBdebugreiserfs\fR -p /dev/xxx | gzip -c >
xxx.gz. None of your data are packed unless a filesystem corruption presents when
the whole block having this corruption is packed. You send us the output, and we use
it to create a filesystem with the same strucure as yours using \fBdebugreiserfs -u\fR.
When the data file is not too large, this usually allows us to quickly reproduce
and debug the problem.
.TP
.B -u
builds the ReiserFS filesystem image with gunzip -c xxx.gz | \fBdebugreiserfs\fR
-u /dev/image of the previously packed metadata with \fBdebugreiserfs -p\fR. The
result image is not the same as the original filesystem, because mostly only metadata
were packed with \fBdebugreiserfs -p\fR, but the filesystem structure is completely
recreated.
.TP
.B -S
When -S is not specified -p
.\" and -s
deals with blocks marked used in the filesystem bitmap only. With this option
set \fBdebugreiserfs\fR will work with the entire device.
.TP
.B -q
When
.\" -s or
-p is in use, suppress showing the speed of progress.
.SH AUTHOR
This version of \fBdebugreiserfs\fR has been written by Vitaly Fertman
<vitaly@namesys.com>.
.SH BUGS
Please report bugs to the ReiserFS developers <reiserfs-dev@namesys.com>, providing
as much information as possible--your hardware, kernel, patches, settings, all printed
messages; check the syslog file for any related information.
.SH SEE ALSO
.BR reiserfsck (8),
.BR mkreiserfs (8)
+779
View File
@@ -0,0 +1,779 @@
/*
* Copyright 2000-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#include "debugreiserfs.h"
reiserfs_filsys_t * fs;
#define print_usage_and_exit() {\
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\
-j filename\n\t\tprint journal located on the device 'filename'\n\
\t\tstores the journal in the specified file 'filename.\n\
-p\t\tsend filesystem metadata to stdout\n\
-u\t\tread stdin and unpack the metadata\n\
-S\t\thandle all blocks, not only used\n\
-1 block\tblock to print\n\
-q\t\tno speed info\n\
-V\t\tprint version and exit\n\n", argv[0]);\
exit (16);\
}
/*
Undocumented options:
-a map_file\n\tstore to the file the map of file. Is used with -n, -N, -r, -f\n
-f \tprints the file map specified by -a.\n
-n name\n\stcan device for specific name in reiserfs directories\n\
-N \tscan tree for specific key in reiserfs directories\n\
-k \tscan device either for specific key or for any metadata\n\
-r name\n\trecovers the file spacified by -a to the 'name' file.\n\
-S\t\tgo through whole device when running -p, -k or -n\n\
-U\t\tgo through unused blocks only when running -p, -k or -n\n\
-D\t\tprint blocks details scanning the device, not the tree as -d does\n\
-b bitmap_file\n\t\trunning -p, -k or -n read blocks marked in this bitmap only\n\
-C\tallow to change reiserfs metadata\n\
-J\tsearch block numbers in the journal\n\
-t\tstat the device\n\
-v\tverboes unpack, prints the block number of every block being unpacked\n\
-Z\tzero all data.
To build a map of a file blocks by name:
debugreiserfs device -a mapfile -n filename
To build a map of a file blocks by key:
debugreiserfs device -a mapfile -k
To extract some:
debugreiserfs device -a mapfile -r filename > backup
*/
#if 1
struct reiserfs_fsstat {
int nr_internals;
int nr_leaves;
int nr_files;
int nr_directories;
int nr_unformatted;
} g_stat_info;
#endif
static void print_disk_tree (reiserfs_filsys_t * fs, unsigned long block_nr)
{
struct buffer_head * bh;
int i, j, count;
static int level = -1;
if (level == -1)
level = get_sb_tree_height (fs->fs_ondisk_sb);
bh = bread (fs->fs_dev, block_nr, fs->fs_blocksize);
if (!bh) {
die ("Could not read block %lu\n", block_nr);
}
level --;
if (level < 1)
die ("level too small");
if (level != get_blkh_level (B_BLK_HEAD (bh))) {
printf ("%d expected, %d found in %lu\n", level,
get_blkh_level (B_BLK_HEAD (bh)), bh->b_blocknr);
}
if (is_internal_node (bh)) {
struct disk_child * dc;
g_stat_info.nr_internals ++;
print_block (stdout, fs, bh,
data(fs)->options & PRINT_TREE_DETAILS, -1, -1);
dc = B_N_CHILD (bh, 0);
count = B_NR_ITEMS(bh);
for (i = 0; i <= count; i++, dc++)
print_disk_tree (fs, get_dc_child_blocknr (dc));
} else if (is_leaf_node (bh)) {
struct item_head *ih;
g_stat_info.nr_leaves ++;
print_block (stdout, fs, bh,
data (fs)->options & PRINT_TREE_DETAILS, -1, -1);
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)) {
__u32 * ind_item = (__u32 *)B_I_PITEM (bh, ih);
for (j = 0; j < (int)I_UNFM_NUM (ih); j ++) {
if (d32_get (ind_item, j)) {
g_stat_info.nr_unformatted += 1;
}
}
}
}
} else {
print_block (stdout, fs, bh,
data (fs)->options & PRINT_TREE_DETAILS, -1, -1);
reiserfs_warning (stdout, "print_disk_tree: bad block "
"type (%b)\n", bh);
}
brelse (bh);
level ++;
}
static void print_disk_blocks (reiserfs_filsys_t * fs)
{
int type;
unsigned long done = 0, total;
struct buffer_head * bh;
unsigned int j;
total = reiserfs_bitmap_ones (input_bitmap(fs));
for (j = 0; j < get_sb_block_count (fs->fs_ondisk_sb); j ++) {
if (!reiserfs_bitmap_test_bit (input_bitmap (fs), j))
continue;
print_how_far (stderr, &done, total, 1, be_quiet (fs));
bh = bread (fs->fs_dev, j, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (stderr, "could not read block %lu\n", j);
continue;
}
type = who_is_this (bh->b_data, bh->b_size);
if (type != THE_UNKNOWN) {
print_block (stdout, fs, bh,
PRINT_TREE_DETAILS | PRINT_DIRECT_ITEMS,
-1, -1);
}
if (type == THE_INTERNAL)
g_stat_info.nr_internals ++;
else if (type == THE_LEAF || type == HAS_IH_ARRAY)
g_stat_info.nr_leaves ++;
brelse (bh);
}
fprintf (stderr, "\n");
}
void pack_one_block (reiserfs_filsys_t * fs, unsigned long block);
static void print_one_block (reiserfs_filsys_t * fs, unsigned long block)
{
struct buffer_head * bh;
if (!fs->fs_bitmap2) {
struct buffer_head * bm_bh;
unsigned long bm_block;
if (spread_bitmaps (fs))
bm_block =
( block / (fs->fs_blocksize * 8) ) ?
(block / (fs->fs_blocksize * 8)) *
(fs->fs_blocksize * 8) :
fs->fs_super_bh->b_blocknr + 1;
else
bm_block = fs->fs_super_bh->b_blocknr + 1 +
(block / (fs->fs_blocksize * 8));
bm_bh = bread (fs->fs_dev, bm_block, fs->fs_blocksize);
if (bm_bh) {
if (misc_test_bit((block % (fs->fs_blocksize * 8)),
bm_bh->b_data))
{
fprintf (stderr, "%lu is used in "
"ondisk bitmap\n", block);
} else {
fprintf (stderr, "%lu is free in "
"ondisk bitmap\n", block);
}
brelse (bm_bh);
}
} else {
if (reiserfs_bitmap_test_bit (fs->fs_bitmap2, block))
fprintf (stderr, "%lu is used in ondisk bitmap\n", block);
else
fprintf (stderr, "%lu is free in ondisk bitmap\n", block);
}
bh = bread (fs->fs_dev, block, fs->fs_blocksize);
if (!bh) {
printf ("print_one_block: bread failed\n");
return;
}
if (debug_mode (fs) == DO_PACK) {
pack_one_block (fs, bh->b_blocknr);
brelse (bh);
return;
}
if (who_is_this (bh->b_data, bh->b_size) != THE_UNKNOWN)
print_block (stdout, fs, bh, PRINT_TREE_DETAILS, -1, -1);
else
printf ("Looks like unformatted\n");
brelse (bh);
return;
}
/* debugreiserfs -p or -P compresses reiserfs meta data: super block, journal,
bitmap blocks and blocks looking like leaves. It may save "bitmap" of
blocks they packed in the file of special format. Reiserfsck can then load
"bitmap" saved in that file and build the tree of blocks marked used in
that "bitmap"
*/
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 [])
{
int c;
char * tmp;
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:pkn:Nfr:dDomj:JqtZl:LVB:uv"))
!= EOF)
{
switch (c) {
case 'a': /* -r will read this, -n and -N will write to it */
asprintf (&data->map_file, "%s", optarg);
break;
case 'b':
/* will load bitmap from a file and read only blocks
marked in it. This is for -p and -k */
asprintf (&data->input_bitmap, "%s", optarg);
data->scan_area = EXTERN_BITMAP;
break;
case 'S':
/* have debugreiserfs -p or -k to read all the device */
data->scan_area = ALL_BLOCKS;
break;
case 'U':
/* have debugreiserfs -p or -k to read unused blocks only */
data->scan_area = UNUSED_BLOCKS;
break;
case '1': /* print a single node */
data->block = strtol (optarg, &tmp, 0);
if (*tmp)
die ("parse_options: bad block number");
break;
case 'C':
data->mode = DO_CORRUPT_ONE;
data->block = strtol (optarg, &tmp, 0);
if (*tmp) {
die ("parse_options: bad block number");
}
break;
case 'F':
data->mode = DO_CORRUPT_FILE;
if (asprintf (&corruption_list_file, "%s", optarg) == -1 ) {
die ("parse_options: bad list corruption file");
}
break;
case 'p':
data->mode = DO_PACK;
break;
case 'u':
data->mode = DO_UNPACK;
break;
case 't':
data->mode = DO_STAT;
break;
case 'k':
/* read the device and print reiserfs blocks which contain
defined key */
data->mode = DO_SCAN;
break;
case 'n': /* scan for names matching a specified pattern */
data->mode = DO_SCAN_FOR_NAME;
data->pattern = optarg;
/*asprintf (&data->pattern, "%s", optarg);*/
break;
case 'N': /* search name in the tree */
data->mode = DO_LOOK_FOR_NAME;
break;
case 'f':
data->mode = DO_FILE_MAP;
break;
case 'r':
asprintf (&data->recovery_file, "%s", optarg);
data->mode = DO_RECOVER;
break;
case 'd':
/* print leaf details from internal tree */
data->options |= PRINT_TREE_DETAILS;
break;
case 'D':
/* print leaf details accordingly the bitmap - can be used
with -S */
data->options |= PRINT_DETAILS;
break;
case 'o':
/* print objectid map */
data->options |= PRINT_OBJECTID_MAP;
break;
case 'm': /* print a block map */
case 'M': /* print a block map with details */
data->options |= PRINT_BITMAP;
break;
case 'j': /* -j must have a parameter */
data->options |= PRINT_JOURNAL;
data->journal_device_name = optarg;
break;
case 'J':
data->options |= PRINT_JOURNAL_HEADER;
break;
case 'R': /* read block numbers from stdin and look for them in the
journal */
data->mode = DO_SCAN_JOURNAL;
data->JJ ++;
break;
case 'B': /*disabled for a while*/
asprintf (&badblocks_file, "%s", optarg);
data->mode = DO_EXTRACT_BADBLOCKS;
break;
case 'q':
/* this makes packing to not show speed info during -p or -P */
data->options |= BE_QUIET;
break;
case 'Z':
data->mode = DO_ZERO;
break;
case 'l': /* --logfile */
data->log_file_name = optarg;
data->log = fopen (optarg, "w");
if (!data->log) {
fprintf (stderr, "debugreiserfs: Cannot not open "
"\'%s\': %s", optarg, strerror(errno));
}
break;
case 'L' :
/* random fs corruption */
data->mode = DO_RANDOM_CORRUPTION;
break;
case 'V':
data->mode = DO_NOTHING;
break;
case 'v':
data->options |= BE_VERBOSE;
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];
}
void pack_partition (reiserfs_filsys_t * fs);
static void do_pack (reiserfs_filsys_t * fs)
{
if (certain_block (fs))
pack_one_block (fs, certain_block (fs));
else
pack_partition (fs);
}
/*
static int comp (const void * vp1, const void * vp2)
{
const int * p1, * p2;
p1 = vp1; p2 = vp2;
if (*p1 < *p2)
return -1;
if (*p1 > *p2)
return 1;
return 0;
}
*/
static void init_bitmap (reiserfs_filsys_t * fs)
{
FILE * fp;
unsigned long block_count;
if (reiserfs_open_ondisk_bitmap (fs) < 0)
reiserfs_exit (1, "Could not open ondisk bitmap");
block_count = get_sb_block_count (fs->fs_ondisk_sb);
switch (scan_area (fs)) {
case ALL_BLOCKS:
input_bitmap (fs) = reiserfs_create_bitmap (block_count);
reiserfs_bitmap_fill (input_bitmap (fs));
reiserfs_warning (stderr, "Whole device (%d blocks) is to be scanned\n",
reiserfs_bitmap_ones (input_bitmap (fs)));
break;
case USED_BLOCKS:
reiserfs_warning (stderr, "Loading on-disk bitmap .. ");
input_bitmap (fs) = reiserfs_create_bitmap (block_count);
reiserfs_bitmap_copy (input_bitmap (fs), fs->fs_bitmap2);
reiserfs_warning (stderr, "%d bits set - done\n",
reiserfs_bitmap_ones (input_bitmap (fs)));
break;
case UNUSED_BLOCKS:
reiserfs_warning (stderr, "Loading on-disk bitmap .. ");
input_bitmap (fs) = reiserfs_create_bitmap (block_count);
reiserfs_bitmap_copy (input_bitmap (fs), fs->fs_bitmap2);
reiserfs_bitmap_invert (input_bitmap (fs));
reiserfs_warning (stderr, "%d bits set - done\n",
reiserfs_bitmap_ones (input_bitmap (fs)));
break;
case EXTERN_BITMAP:
fp = fopen (input_bitmap_file_name(fs), "r");
if (!fp) {
reiserfs_exit (1, "init_bitmap: could not load bitmap: %m\n");
}
input_bitmap (fs) = reiserfs_bitmap_load (fp);
if (!input_bitmap (fs)) {
reiserfs_exit (1, "could not load fitmap from \"%s\"",
input_bitmap_file_name(fs));
}
reiserfs_warning (stderr, "%d blocks marked in the given bitmap\n",
reiserfs_bitmap_ones (input_bitmap (fs)));
fclose (fp);
break;
default:
reiserfs_panic ("No area to scan specified");
}
}
/* FIXME: statistics does not work */
static void do_dump_tree (reiserfs_filsys_t * fs)
{
if (certain_block (fs)) {
print_one_block (fs, certain_block (fs));
return;
}
if (((data (fs)->options & PRINT_JOURNAL) ||
(data (fs)->options & PRINT_JOURNAL_HEADER)) &&
!reiserfs_journal_opened (fs))
{
if (reiserfs_open_journal (fs, data(fs)->journal_device_name,
O_RDONLY))
{
printf ("Could not open journal\n");
return;
}
}
print_filesystem_state (stdout, fs);
print_block (stdout, fs, fs->fs_super_bh);
if (data (fs)->options & PRINT_JOURNAL)
print_journal (fs);
if (data (fs)->options & PRINT_JOURNAL_HEADER)
print_journal_header (fs);
if (data (fs)->options & PRINT_OBJECTID_MAP)
print_objectid_map (stdout, fs);
if (data (fs)->options & PRINT_BITMAP)
print_bmap (stdout, fs, 0/*opt_print_block_map == 1 ? 1 : 0*/);
if (data (fs)->options & PRINT_DETAILS)
init_bitmap (fs);
if (data (fs)->options & PRINT_DETAILS ||
data (fs)->options & PRINT_TREE_DETAILS)
{
if (data (fs)->options & PRINT_DETAILS) {
print_disk_blocks (fs);
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 ("\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);
}
}
static void callback_badblock_print(reiserfs_filsys_t *fs,
struct path *badblock_path,
void *data)
{
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);
for (i = 0; i < I_UNFM_NUM(tmp_ih); i++)
fprintf (fd, "%u\n", d32_get (ind_item, i));
pathrelse (badblock_path);
}
void extract_badblock_list () {
FILE *fd;
if (!(fd = fopen (badblocks_file, "w"))) {
reiserfs_exit(1, "debugreiserfs: could not open badblock file %s\n",
badblocks_file);
}
badblock_list(fs, callback_badblock_print, fd);
fclose (fd);
}
static int str2int (char * str, int * res)
{
int val;
char * tmp;
val = (int) strtol (str, &tmp, 0);
if (tmp == str)
/* could not convert string into a number */
return 0;
*res = val;
return 1;
}
void do_corrupt_blocks (reiserfs_filsys_t * fs)
{
char * line;
FILE * fd;
size_t n = 0;
int numblock;
fd = fopen (corruption_list_file, "r");
if (fd == NULL) {
reiserfs_exit(1, "debugreiserfs: could not open corruption "
"list file %s\n", corruption_list_file);
}
while (1) {
line = NULL;
n = 0;
if (getline (&line, &n, fd) == -1) {
break;
}
/* remove '\n' */
line [strlen (line) - 1] = '\0';
if (str2int(line, &numblock)) {
data (fs)->block = (unsigned long) numblock;
} else {
do_corrupt_one_block(fs, line);
}
printf ("before free line : %s\n", line);
free (line);
printf ("after free\n");
reiserfs_reopen (fs, O_RDWR);
}
fclose (fd);
return;
}
void debugreiserfs_zero_reiserfs(reiserfs_filsys_t * fs) {
unsigned long done, total, i;
struct buffer_head * bh;
reiserfs_reopen (fs, O_RDWR);
total = reiserfs_bitmap_ones (input_bitmap (fs));
done = 0;
for (i = 0; i < input_bitmap(fs)->bm_bit_size; i ++) {
if (!reiserfs_bitmap_test_bit (input_bitmap(fs), i))
continue;
bh = getblk(fs->fs_dev, i, fs->fs_blocksize);
if (!bh)
die("Could not get block %lu\n", i);
memset(bh->b_data, 0, fs->fs_blocksize);
mark_buffer_dirty(bh);
mark_buffer_uptodate(bh, 0);
bwrite(bh);
brelse (bh);
print_how_far (stderr, &done, total, 1, be_quiet (fs));
}
fprintf(stderr, "\n");
fflush(stderr);
}
/* FIXME: need to open reiserfs filesystem first */
int main (int argc, char * argv[])
{
char * file_name;
int error;
struct debugreiserfs_data * data;
data = getmem (sizeof (struct debugreiserfs_data));
file_name = parse_options (data, argc, argv);
if (data->mode == DO_UNPACK) {
do_unpack(file_name, data->journal_device_name,
data->input_bitmap, data->options & BE_VERBOSE);
return 0;
}
fs = reiserfs_open (file_name, O_RDONLY, &error, data, 0);
if (no_reiserfs_found (fs)) {
reiserfs_exit (1, "\n\ndebugreiserfs: can not open reiserfs on "
"\"%s\": %s\n\n", file_name, error ? strerror(error)
: "no filesystem found");
exit(1) ;
}
if (reiserfs_open_journal (fs, data (fs)->journal_device_name, O_RDONLY)) {
fprintf(stderr,"\ndebugreiserfs: Failed to open the fs journal.\n");
}
switch (debug_mode (fs)) {
case DO_STAT:
init_bitmap (fs);
do_stat (fs);
break;
case DO_PACK:
init_bitmap (fs);
do_pack (fs);
break;
case DO_CORRUPT_ONE:
reiserfs_reopen (fs, O_RDWR);
do_corrupt_one_block (fs, (char *)NULL);
break;
case DO_CORRUPT_FILE:
reiserfs_reopen (fs, O_RDWR);
do_corrupt_blocks (fs);
break;
case DO_RANDOM_CORRUPTION:
reiserfs_reopen (fs, O_RDWR);
/*
do_leaves_corruption (fs);
do_bitmap_corruption (fs);
*/
do_fs_random_corrupt (fs);
break;
case DO_DUMP:
do_dump_tree (fs);
break;
case DO_SCAN:
case DO_SCAN_FOR_NAME:
case DO_LOOK_FOR_NAME:
case DO_SCAN_JOURNAL:
init_bitmap (fs);
do_scan (fs);
break;
case DO_FILE_MAP:
print_map(fs);
break;
case DO_RECOVER:
do_recover (fs);
break;
case DO_TEST:
/*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, "Done\n\n");
break;
case DO_ZERO:
init_bitmap (fs);
debugreiserfs_zero_reiserfs(fs);
break;
}
reiserfs_close (fs);
if (data(fs)->log) {
fclose (data(fs)->log);
}
return 0;
}
+294
View File
@@ -0,0 +1,294 @@
/*
* Copyright 2000-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#define _GNU_SOURCE
#ifndef HAVE_CONFIG_H
# include "config.h"
#endif
#include "io.h"
#include "misc.h"
#include "reiserfs_lib.h"
#include "../version.h"
#include <string.h>
#include <errno.h>
extern reiserfs_filsys_t * fs;
/*
* modes
*/
#define DO_DUMP 1 /* not a real dump, just printing to stdout contents of
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_SCAN 5
#define DO_RECOVER 6
#define DO_TEST 7
#define DO_PACK 8 /* -p extract meta data of reiserfs filesystem */
#define DO_UNPACK 9 /* -u create the fs by the givem metadata */
#define DO_STAT 10
#define DO_SCAN_FOR_NAME 11 /* -n */
#define DO_LOOK_FOR_NAME 12 /* -N */
#define DO_SCAN_JOURNAL 13 /* -J */
#define DO_EXTRACT_BADBLOCKS 14
#define DO_FILE_MAP 15
#define DO_ZERO 16
#define DO_NOTHING 17
/*first bits are in reiserfs_fs.b*/
#define PRINT_JOURNAL 0x10
#define PRINT_JOURNAL_HEADER 0x20
#define PRINT_BITMAP 0x40
#define PRINT_OBJECTID_MAP 0x80
#define BE_QUIET 0x100
#define BE_VERBOSE 0x200
/* these moved to reiserfs_fs.h */
//#define PRINT_TREE_DETAILS
//#define PRINT_DETAILS
//#define PRINT_ITEM_DETAILS
//#define PRINT_DIRECT_ITEMS
// the leaf is stored in compact form:
// start magic number
// block number __u32
// item number __u16
// struct packed_item
// ..
// end magic number
/* we store hash code in high byte of 16 bits */
#define LEAF_START_MAGIC 0xa6
#define LEAF_END_MAGIC 0x5a
#define FULL_BLOCK_START_MAGIC 0xb6
#define FULL_BLOCK_END_MAGIC 0x6b
#define UNFORMATTED_BITMAP_START_MAGIC 0xc7
#define UNFORMATTED_BITMAP_END_MAGIC 0x7c
#define END_MAGIC 0x8d
#define INTERNAL_START_MAGIC
#define INTERNAL_START_MAGIC
#define SEPARATED_JOURNAL_START_MAGIC 0xf8
#define SEPARATED_JOURNAL_END_MAGIC 0x8f
#define ITEM_START_MAGIC 0x476576
#define ITEM_END_MAGIC 0x2906504
#define MAP_MAGIC 0xe9
#define MAP_END_MAGIC 0x9e
/* 12 bits of mask are used to define */
#define NEW_FORMAT 0x01 /* 1. 0 here means - old format, 1 - new format */
#define DIR_ID 0x02 /* 2. dir_id is stored */
#define OBJECT_ID 0x04 /* 3. objectid is stored */
#define OFFSET_BITS_32 0x08 /* 4. offset is stored as 32 bit */
#define OFFSET_BITS_64 0x10 /* 5. offset is stored as 64 bit */
#define IH_ENTRY_COUNT 0x20 /* 6. ih_free_space/ih_entry_count is stored */
#define IH_FREE_SPACE 0x20
#define IH_FORMAT 0x40 /* 7. ih_format is stored */
#define WITH_SD_FIRST_DIRECT_BYTE 0x80 /* 8. for old stat data first_direct_byte is stored */
#define NLINK_BITS_32 0x0100 /* 9. nlinks stored in 32 bits */
#define SIZE_BITS_64 0x0200 /* 10. size has to be stored in 64 bit */
#define WHOLE_INDIRECT 0x0400 /* 11. indirect item is stored with compression */
#define SAFE_LINK 0x0800 /* 11. indirect item is stored with compression */
#define TYPE_MASK 0x3 /* two lowest bits are used to store item type */
//#define MASK_MASK 0xffffc /* what is packed: dirid, objectid, etc */
#define ITEM_LEN_MASK 0xfff00000 /* contents of ih_item_len of item_head */
struct packed_item {
__u32 type_2_mask_18_len_12;
};
/* defined as inlines in both pack.c and unpack.c */
inline void set_pi_type( struct packed_item *pi, __u32 val );
inline __u32 get_pi_type( const struct packed_item *pi );
inline void set_pi_mask( struct packed_item *pi, __u32 val );
inline __u32 get_pi_mask( const struct packed_item *pi );
inline void set_pi_item_len( struct packed_item *pi, __u32 val );
inline __u32 get_pi_item_len( const struct packed_item *pi );
#define HAS_DIR_ID 0x01
#define HAS_GEN_COUNTER 0x02
#define HAS_STATE 0x04
#define YURA 0x08
#define TEA 0x10
#define R5 0x20
struct packed_dir_entry {
__u8 mask;
__u16 entrylen;
};
/* packed_dir_entry.mask is *always* endian safe, since it's 8 bit */
#define get_pe_entrylen(pe) (le16_to_cpu((pe)->entrylen))
#define set_pe_entrylen(pe,v) ((pe)->entrylen = cpu_to_le16(v))
#define fread8(pv) fread (pv, sizeof (__u8), 1, stdin)
#define fread_le16(pv)\
{\
__u16 tmp; \
fread16(&tmp); \
*pv = le16_to_cpu(tmp); \
}
#define fread_le32(pv)\
{\
__u32 tmp; \
fread32(&tmp); \
*pv = le32_to_cpu(tmp); \
}
#define fread_le64(pv)\
{\
__u64 tmp; \
fread64(&tmp); \
*pv = le64_to_cpu(tmp); \
}
#define fread8(pv) fread (pv, sizeof (__u8), 1, stdin)
#define fread16(pv) fread (pv, sizeof (__u16), 1, stdin)
#define fread32(pv) fread (pv, sizeof (__u32), 1, stdin)
#define fread64(pv) fread (pv, sizeof (__u64), 1, stdin)
#define fwrite_le16(pv)\
{\
__u16 tmp = cpu_to_le16(*(pv));\
fwrite16(&tmp);\
}
#define fwrite_le32(pv)\
{\
__u32 tmp = cpu_to_le32(*(pv));\
fwrite32(&tmp);\
}
#define fwrite_le64(pv)\
{\
__u64 tmp = cpu_to_le64(*(pv));\
fwrite64(&tmp);\
}
#define fwrite8(pv) {\
if (fwrite (pv, sizeof (__u8), 1, stdout) != 1)\
reiserfs_panic ("fwrite8 failed: %m");\
sent_bytes ++;\
}
#define fwrite16(pv) {\
if (fwrite (pv, sizeof (__u16), 1, stdout) != 1)\
reiserfs_panic ("fwrite16 failed: %m");\
sent_bytes += 2;\
}
#define fwrite32(pv) {\
if (fwrite (pv, sizeof (__u32), 1, stdout) != 1)\
reiserfs_panic ("fwrite32 failed: %m");\
sent_bytes += 4;\
}
#define fwrite64(pv) {\
if (fwrite (pv, sizeof (__u64), 1, stdout) != 1)\
reiserfs_panic ("fwrite64 failed: %m");\
sent_bytes += 8;\
}
struct debugreiserfs_data {
int mode; /* DO_DUMP | DO_PACK | DO_CORRUPT_ONE... */
#define USED_BLOCKS 1
#define EXTERN_BITMAP 2
#define ALL_BLOCKS 3
#define UNUSED_BLOCKS 4
int scan_area; /* for -p, -s and -n */
char * input_bitmap; /* when ->scan_area is set to EXTERN_BITMAP */
reiserfs_bitmap_t * bitmap; /* bitmap is read from ->input_bitmap */
unsigned long block; /* set by -B. this is a must for -C, option for -p and -d */
char * pattern; /* for -n */
char * device_name;
char * journal_device_name; /* for -j */
char * map_file; /* for -n, -N and -f */
char * recovery_file; /* for -r */
unsigned long options; /* -q only yet*/
int JJ;
/* log file name and handle */
char * log_file_name;
FILE * log ;
};
#define data(fs) ((struct debugreiserfs_data *)((fs)->fs_vp))
#define debug_mode(fs) (data(fs)->mode)
#define certain_block(fs) (data(fs)->block)
#define input_bitmap(fs) (data(fs)->bitmap)
#define input_bitmap_file_name(fs) (data(fs)->input_bitmap)
#define scan_area(fs) (data(fs)->scan_area)
#define name_pattern(fs) (data(fs)->pattern)
#define device_name(fs) (data(fs)->device_name)
#define journal_device_name(fs) (data(fs)->journal_device_name)
#define map_file(fs) (data(fs)->map_file)
#define recovery_file(fs) (data(fs)->recovery_file)
#define be_quiet(fs) (data(fs)->options & BE_QUIET)
/* stat.c */
void do_stat (reiserfs_filsys_t * fs);
/* corruption.c */
void do_corrupt_one_block (reiserfs_filsys_t * fs, char * fline);
void do_leaves_corruption (reiserfs_filsys_t * fs, unsigned long nr_leaves_cr);
void do_bitmap_corruption (reiserfs_filsys_t * fs);
void do_fs_random_corrupt (reiserfs_filsys_t * fs);
/* recover.c */
void do_recover (reiserfs_filsys_t * fs);
/* scan.c */
void do_scan (reiserfs_filsys_t * fs);
/* journal.c */
void scan_journal (reiserfs_filsys_t * fs);
/* unpack.c */
extern int do_unpack(char *host, char *j_filename, char *filename, int verbose);
void print_map(reiserfs_filsys_t * fs);
struct saved_item {
struct item_head si_ih;
unsigned long si_block;
int si_item_num, si_entry_pos;
struct saved_item *si_next; /* list of items having the same key */
};
/*
Local variables:
c-indentation-style: "K&R"
mode-name: "LC"
c-basic-offset: 4
tab-width: 4
fill-column: 80
End:
*/
+743
View File
@@ -0,0 +1,743 @@
/*
* Copyright 2000-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#include "debugreiserfs.h"
/* counters for each kind of blocks */
int packed,
packed_leaves,
full_blocks,
having_ih_array, /* blocks with broken block head */
bad_leaves, /* failed to compress */
internals,
descs,
others;
reiserfs_bitmap_t * what_to_pack;
/* these are to calculate compression */
unsigned long sent_bytes; /* how many bytes sent to stdout */
unsigned long had_to_be_sent; /* how many bytes were to be sent */
inline void set_pi_type( struct packed_item *pi, __u32 val )
{
set_bit_field_XX (32, pi, val, 0, 2);
}
inline __u32 get_pi_type( const struct packed_item *pi )
{
get_bit_field_XX (32, pi, 0, 2);
}
inline void set_pi_mask( struct packed_item *pi, __u32 val )
{
set_bit_field_XX (32, pi, val, 2, 18);
}
__u32 get_pi_mask( const struct packed_item *pi )
{
get_bit_field_XX (32, pi, 2, 18);
}
inline void set_pi_item_len( struct packed_item *pi, __u32 val )
{
set_bit_field_XX (32, pi, val, 20, 12);
}
inline __u32 get_pi_item_len( const struct packed_item *pi )
{
get_bit_field_XX (32, pi, 20, 12);
}
static void pack_ih (struct packed_item * pi, struct item_head * ih)
{
__u32 v32;
__u16 v16;
/* send packed item head first */
fwrite (pi, sizeof (*pi), 1, stdout);
sent_bytes += sizeof (*pi);
/* sen key components which are to be sent */
if (get_pi_mask(pi) & DIR_ID) {
v32 = get_key_dirid (&ih->ih_key);
fwrite_le32 (&v32);
}
if (get_pi_mask(pi) & OBJECT_ID) {
v32 = get_key_objectid (&ih->ih_key);
fwrite_le32 (&v32);
}
if (get_pi_mask(pi) & OFFSET_BITS_64) {
__u64 offset;
offset = get_offset (&ih->ih_key);
fwrite_le64 (&offset);
}
if (get_pi_mask(pi) & OFFSET_BITS_32) {
__u32 offset;
offset = get_offset (&ih->ih_key);
fwrite_le32 (&offset);
}
if (get_pi_mask(pi) & IH_FREE_SPACE) {
v16 = get_ih_entry_count (ih);
fwrite_le16 (&v16);
}
if (get_pi_mask(pi) & IH_FORMAT) {
/* fixme */
fwrite16 (&ih->ih_format);
}
}
static void pack_direct (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
if (get_ih_free_space (ih) != 0xffff)
/* ih_free_space has unexpected value */
set_pi_mask (pi, get_pi_mask (pi) | IH_FREE_SPACE);
if (get_pi_mask(pi) & SAFE_LINK)
set_key_dirid(&ih->ih_key, d32_get((__u32 *)B_I_PITEM (bh, ih), 0) );
/* send key components which are to be sent */
pack_ih (pi, ih);
}
/* if there is at least one extent longer than 2 - it is worth packing */
static int should_pack_indirect (__u32 * ind_item, int unfm_num)
{
int i, len;
for (i = 1, len = 1; i < unfm_num; i ++) {
if ((d32_get(ind_item, i) == 0 && d32_get(ind_item, i - 1) == 0) ||
d32_get(ind_item, i) == d32_get(ind_item, i - 1) + 1)
{
len ++;
if (len > 2)
return 1;
} else {
/* sequence of blocks or hole broke */
len = 1;
}
}
return 0;
}
/* indirect item can be either packed using "extents" (when it is
worth doing) or be stored as is. Size of item in packed form is not
stored. Unpacking will stop when full item length is reached */
static void pack_indirect (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
unsigned int i;
__u32 * ind_item;
__u16 len;
if (get_ih_entry_count (ih))
set_pi_mask (pi, get_pi_mask (pi) | IH_FREE_SPACE);
ind_item = (__u32 *)B_I_PITEM (bh, ih);
if (!should_pack_indirect (ind_item, I_UNFM_NUM (ih)))
set_pi_mask (pi, get_pi_mask (pi) | WHOLE_INDIRECT);
if (get_pi_mask(pi) & SAFE_LINK)
set_key_dirid(&ih->ih_key, d32_get(ind_item, 0));
pack_ih (pi, ih);
if (get_pi_mask(pi) & SAFE_LINK)
return;
if (get_pi_mask(pi) & WHOLE_INDIRECT) {
fwrite (ind_item, get_ih_item_len (ih), 1, stdout);
sent_bytes += get_ih_item_len (ih);
return;
}
fwrite32 (&ind_item [0]);
for (i = 1, len = 1; i < I_UNFM_NUM (ih); i ++) {
if ((d32_get(ind_item, i) == 0 && d32_get(ind_item, i - 1) == 0) ||
d32_get(ind_item, i) == d32_get(ind_item, i - 1) + 1)
{
len ++;
} else {
fwrite_le16 (&len);
fwrite32 ((char *)(ind_item + i));
len = 1;
}
}
fwrite_le16 (&len);
return;
}
/* directory item is packed:
entry count - 16 bits
for each entry
mask (8 bits) - it shows whether there are any of (deh_dir_id, gen counter, deh_state)
entry length 16 bits
entry itself
deh_objectid - 32 bits
maybe deh_dir_id (32 bits)
maybe gencounter (16)
maybe deh_state (16)
*/
static void pack_direntry (reiserfs_filsys_t * fs, struct packed_item * pi,
struct buffer_head * bh,
struct item_head * ih)
{
int i;
struct reiserfs_de_head * deh;
struct packed_dir_entry pe;
__u16 entry_count, gen_counter;
set_pi_mask (pi, get_pi_mask (pi) | IH_ENTRY_COUNT);
/* send item_head components which are to be sent */
pack_ih (pi, ih);
/* entry count is sent unconditionally */
entry_count = get_ih_entry_count (ih);
deh = B_I_DEH (bh, ih);
for (i = 0; i < entry_count; i ++, deh ++) {
pe.entrylen = entry_length (ih, deh, i);
pe.mask = 0;
if (get_deh_dirid (deh) != get_key_objectid (&ih->ih_key))
/* entry points to name of another directory, store deh_dir_id */
pe.mask |= HAS_DIR_ID;
gen_counter = GET_GENERATION_NUMBER (get_deh_offset (deh));
if (gen_counter != 0)
/* store generation counter if it is != 0 */
pe.mask |= HAS_GEN_COUNTER;
if (get_deh_state (deh) != 4)
/* something unusual in deh_state. Store it */
pe.mask |= HAS_STATE;
fwrite8 (&pe.mask);
fwrite_le16 (&pe.entrylen);
fwrite (name_in_entry (deh, i), pe.entrylen, 1, stdout);
sent_bytes += pe.entrylen;
fwrite32 (&(deh->deh2_objectid));
if (pe.mask & HAS_DIR_ID)
fwrite32 (&deh->deh2_dir_id);
if (pe.mask & HAS_GEN_COUNTER)
fwrite_le16 (&gen_counter);
if (pe.mask & HAS_STATE)
fwrite16 (&deh->deh2_state);
}
}
static void pack_stat_data (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
if (get_ih_free_space (ih) != 0xffff)
/* ih_free_space has unexpected value */
set_pi_mask (pi, get_pi_mask (pi) | IH_FREE_SPACE);
if (stat_data_v1 (ih)) {
/* for old stat data: we take
mode - 16 bits
nlink - 16 bits
size - 32 bits
blocks/rdev - 32 bits
maybe first_direct byte 32 bits
*/
struct stat_data_v1 * sd_v1;
sd_v1 = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
if (sd_v1->sd_first_direct_byte != 0xffffffff) /* ok if -1 */
set_pi_mask (pi, get_pi_mask (pi) | WITH_SD_FIRST_DIRECT_BYTE);
pack_ih (pi, ih);
fwrite16 (&sd_v1->sd_mode);
fwrite16 (&sd_v1->sd_nlink);
fwrite32 (&sd_v1->sd_size);
fwrite32 (&sd_v1->u.sd_blocks);
if (get_pi_mask(pi) & WITH_SD_FIRST_DIRECT_BYTE)
fwrite32 (&sd_v1->sd_first_direct_byte);
} else {
/* for new stat data
mode - 16 bits
nlink in either 16 or 32 bits
size in either 32 or 64 bits
blocks - 32 bits
*/
struct stat_data * sd;
/* these will maintain disk-order values */
__u16 nlink16;
__u32 nlink32, size32;
__u64 size64;
sd = (struct stat_data *)B_I_PITEM (bh, ih);
if (sd_v2_nlink (sd) > 0xffff) {
set_pi_mask (pi, get_pi_mask (pi) | NLINK_BITS_32);
nlink32 = sd->sd_nlink;
} else {
/* This is required to deal with big endian systems */
nlink16 = cpu_to_le16 ((__u16)sd_v2_nlink (sd));
}
if (sd_v2_size (sd) > 0xffffffff) {
set_pi_mask (pi, get_pi_mask (pi) | SIZE_BITS_64);
size64 = sd->sd_size;
} else {
/* This is required to deal with big endian systems */
size32 = cpu_to_le32 ((__u32)sd_v2_size (sd));
}
pack_ih (pi, ih);
fwrite16 (&sd->sd_mode);
if (get_pi_mask (pi) & NLINK_BITS_32) {
fwrite32 (&nlink32);
} else {
fwrite16 (&nlink16);
}
if (get_pi_mask (pi) & SIZE_BITS_64) {
fwrite64 (&size64);
} else {
fwrite32 (&size32);
}
fwrite32 (&sd->sd_blocks);
}
}
static void pack_full_block (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
__u16 magic;
__u32 block;
magic = FULL_BLOCK_START_MAGIC;
fwrite_le16 (&magic);
block = bh->b_blocknr;
fwrite_le32 (&block);
fwrite (bh->b_data, fs->fs_blocksize, 1, stdout);
sent_bytes += fs->fs_blocksize;
had_to_be_sent += fs->fs_blocksize;
full_blocks ++;
}
#if 0
/* unformatted node pointer is considered bad when it points either to blocks
of journal, bitmap blocks, super block or is transparently out of range of
disk block numbers */
static int check_unfm_ptr (reiserfs_filsys_t * fs, __u32 block)
{
if (block >= SB_BLOCK_COUNT (fs))
return 1;
if (not_data_block (fs, block))
return 1;
return 0;
}
#endif
/* we only pack leaves which do not have any corruptions */
static int can_pack_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
int i;
struct item_head * ih;
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) {
if (is_it_bad_item (fs, ih, B_I_PITEM (bh, ih), 0/*check_unfm_ptr*/, 1/*bad dir*/))
return 0;
}
return 1;
}
/* pack leaf only if all its items are correct: keys are correct,
direntries are hashed properly and hash function is defined,
indirect items are correct, stat data ?, */
static void pack_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
int i;
struct item_head * ih;
struct packed_item pi;
__u16 v16;
if (!can_pack_leaf (fs, bh)) {
/* something looks suspicious in this leaf - pack whole block */
bad_leaves ++;
pack_full_block (fs, 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);
/* block number */
fwrite_le32 (&bh->b_blocknr);
/* item number */
v16 = get_blkh_nr_items (B_BLK_HEAD (bh));
fwrite_le16 (&v16);
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < v16; i ++, ih ++) {
#if 0
v32 = ITEM_START_MAGIC;
fwrite32 (&v32);
#endif
set_pi_mask (&pi, 0);
set_pi_item_len (&pi, get_ih_item_len (ih));
set_pi_type (&pi, get_type (&ih->ih_key));
// format
if (get_ih_key_format (ih) == KEY_FORMAT_2)
set_pi_mask( &pi, get_pi_mask(&pi) | NEW_FORMAT );
// k_dir_id
if (!i || (i && get_key_dirid (&ih->ih_key) != get_key_dirid (&(ih - 1)->ih_key))) {
/* if item is first in the leaf or if previous item has different
k_dir_id - store it */
set_pi_mask (&pi, get_pi_mask (&pi) | DIR_ID);
}
// k_object_id
if (!i || (i && get_key_objectid (&ih->ih_key) != get_key_objectid (&(ih - 1)->ih_key))) {
/* if item is first in the leaf or if previous item has different
k_objectid - store it */
set_pi_mask (&pi, get_pi_mask (&pi) | OBJECT_ID);
}
/* store offset if it is != 0 in 32 or 64 bits */
if (get_offset (&ih->ih_key)) {
int send_offset = 1;
if ((get_pi_mask (&pi) & DIR_ID) == 0 && (get_pi_mask (&pi) & OBJECT_ID) == 0) {
/* previous item is of the same object, so try to avoid
sending k_offset */
if ((is_stat_data_ih (ih - 1) && get_offset (&ih->ih_key) == 1) ||
(is_indirect_ih (ih - 1) && is_direct_ih (ih) &&
get_offset (&(ih - 1)->ih_key) + get_bytes_number (ih - 1, fs->fs_blocksize) == get_offset (&ih->ih_key)))
/* unpack can calculate offset itself */
send_offset = 0;
}
if (send_offset) {
if (get_offset (&ih->ih_key) > 0xffffffffULL)
set_pi_mask (&pi, get_pi_mask (&pi) | OFFSET_BITS_64);
else
set_pi_mask (&pi, get_pi_mask (&pi) | OFFSET_BITS_32);
}
}
/* ih key format is correct, check fsck_need field */
if (get_ih_flags (ih))
set_pi_mask (&pi, get_pi_mask (&pi) | IH_FORMAT);
if ((get_key_dirid (&ih->ih_key) == (__u32)-1) && (get_ih_item_len (ih) == 4))
set_pi_mask (&pi, get_pi_mask (&pi) | SAFE_LINK);
if (is_direct_ih (ih)) {
pack_direct (&pi, bh, ih);
} else if (is_indirect_ih (ih))
pack_indirect (&pi, bh, ih);
else if (is_direntry_ih (ih))
pack_direntry (fs, &pi, bh, ih);
else if (is_stat_data_ih (ih))
pack_stat_data (&pi, bh, ih);
else
die ("pack_leaf: unknown item found");
#if 0
v32 = ITEM_END_MAGIC;
fwrite32 (&v32);
#endif
}
v16 = LEAF_END_MAGIC;
fwrite_le16 (&v16);
had_to_be_sent += fs->fs_blocksize;
packed_leaves ++;
return;
}
static int can_pack_internal (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
return 0;
}
/* pack internal node as a full block */
static void pack_internal (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
internals ++;
if (!can_pack_internal (fs, bh)) {
pack_full_block (fs, bh);
return;
}
reiserfs_panic ("pack_internal: packing code is not ready");
}
/* packed blocks are marked free in the bitmap*/
static void send_block (reiserfs_filsys_t * fs, struct buffer_head * bh, int send_unknown)
{
int type;
packed ++;
type = who_is_this (bh->b_data, bh->b_size);
switch (type) {
case THE_LEAF:
pack_leaf (fs, bh);
break;
case HAS_IH_ARRAY:
having_ih_array ++;
// fprintf (stderr, "BROKEN BLOCK HEAD %lu\n", bh->b_blocknr);
pack_full_block (fs, bh);
break;
case THE_INTERNAL:
pack_internal (fs, bh);
break;
default:
if (send_unknown)
pack_full_block (fs, bh);
else
packed --;
break;
}
/* do not send one block twice */
reiserfs_bitmap_clear_bit (what_to_pack, bh->b_blocknr);
}
/* super block, journal, bitmaps */
static void pack_frozen_data (reiserfs_filsys_t * fs)
{
struct buffer_head * bh;
unsigned long block;
__u16 magic16;
int sent_journal_start_magic = 0;
unsigned int i;
if (is_reiserfs_jr_magic_string(fs->fs_ondisk_sb) &&
get_jp_journal_dev(sb_jp(fs->fs_ondisk_sb)) &&
!journal_device_name(fs)) {
if (!user_confirmed (stderr,
"\n File system has non-standard journal "
"that hasn't been specified.\n"
"Continue packing without journal? [N/Yes] (note need to type Yes):", "Yes\n"))
exit (0);
}
/* super block */
reiserfs_warning (stderr, "super block..");fflush (stderr);
send_block (fs, fs->fs_super_bh, 1/*send block even if its format is not determined */);
reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", reiserfs_fs_bmap_nr(fs));
fflush (stderr);
/* bitmaps */
block = fs->fs_super_bh->b_blocknr + 1;
for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
bh = bread (fs->fs_dev, block, fs->fs_blocksize);
if (!bh) {
fprintf (stderr, "pack_frozen_data: bread failed: %lu\n", block);
continue;
}
send_block (fs, bh, 1);
if (spread_bitmaps (fs))
block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8);
else
block ++;
brelse (bh);
}
/* journal */
if (get_jp_journal_dev (sb_jp (fs->fs_ondisk_sb))) {
/* non-standard journal is on a separate device */
if (journal_device_name (fs) && !reiserfs_journal_opened (fs))
die ("Specified journal is not available. Specify it correctly or "
"don't specify at all");
else if (!journal_device_name(fs))
/* non-standard journal was not specified (that confirmed by user) -
skipped packing journal */
return;
else {
magic16 = SEPARATED_JOURNAL_START_MAGIC;
fwrite_le16 (&magic16);
sent_journal_start_magic = 1;
}
}
block = get_jp_journal_1st_block (sb_jp (fs->fs_ondisk_sb));
reiserfs_warning (stderr, "ok\njournal (from %lu to %lu)..",
block, block + get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)));
fflush (stderr);
for (i = 0; i <= get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)); i ++) {
bh = bread (fs->fs_journal_dev, block + i, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (stderr, "could not read %lu, skipped\n", i);
continue;
}
send_block (fs, bh, 1);
brelse (bh);
}
if (sent_journal_start_magic) {
magic16 = SEPARATED_JOURNAL_END_MAGIC;
fwrite_le16 (&magic16);
}
reiserfs_warning (stderr, "ok\n");fflush (stderr);
reiserfs_warning (stderr,
"Super block, bitmaps, journal - %d blocks - done, %d blocks left\n",
packed, reiserfs_bitmap_ones (what_to_pack));
}
/* pack all "not data blocks" and correct leaf */
void pack_partition (reiserfs_filsys_t * fs)
{
struct buffer_head * bh;
__u32 magic32;
__u16 blocksize;
__u16 magic16;
unsigned long done = 0, total;
unsigned int i;
magic32 = REISERFS_SUPER_MAGIC;
fwrite_le32 (&magic32);
blocksize = fs->fs_blocksize;
fwrite_le16 (&blocksize);
/* will get information about what is to be packed. Bits corresponding to
packed blocks will be cleared */
what_to_pack = input_bitmap(fs);
/* super block, journal, bitmaps */
pack_frozen_data (fs);
/* what's left */
total = reiserfs_bitmap_ones (what_to_pack);
for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) {
if (!reiserfs_bitmap_test_bit (what_to_pack, i))
continue;
print_how_far (stderr, &done, total, 1, be_quiet (fs));
bh = bread (fs->fs_dev, i, blocksize);
if (!bh) {
reiserfs_warning (stderr, "could not read block %lu\n", i);
continue;
}
send_block (fs, bh, 0/*do not send block of not determined format */);
brelse (bh);
}
magic16 = END_MAGIC;
fwrite_le16 (&magic16);
fprintf (stderr, "\nPacked %d blocks:\n"
"\tcompessed %d\n"
"\tfull blocks %d\n"
"\t\tleaves with broken block head %d\n"
"\t\tcorrupted leaves %d\n"
"\t\tinternals %d\n"
"\t\tdescriptors %d\n",
packed,
packed_leaves, full_blocks, having_ih_array,
bad_leaves, internals, descs);
fprintf (stderr, "data packed with ratio %.2f\n", (double)sent_bytes / had_to_be_sent);
}
void pack_one_block (reiserfs_filsys_t * fs, unsigned long block)
{
__u32 magic32;
__u16 magic16;
struct buffer_head * bh;
// reiserfs magic
magic32 = REISERFS_SUPER_MAGIC;
fwrite_le32 (&magic32);
// blocksize
fwrite_le16 (&fs->fs_blocksize);
bh = bread (fs->fs_dev, block, fs->fs_blocksize);
if (!bh)
return;
if (who_is_this (bh->b_data, bh->b_size) == THE_LEAF)
pack_leaf (fs, bh);
else
pack_full_block (fs, bh);
brelse (bh);
// end magic
magic16 = END_MAGIC;
fwrite_le16 (&magic16);
fprintf (stderr, "Done\n");
}
+389
View File
@@ -0,0 +1,389 @@
/*
* Copyright 2000-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#include "debugreiserfs.h"
#if 0
/* this reads stdin and recover file of given key: */
/* the input has to be in the follwong format:
K dirid objectid
N name
B blocknumber
..
then recover_file will read every block, look there specified file and put it into
*/
void do_recover (reiserfs_filsys_t fs)
{
char name [100];
char * line = 0;
int n = 0;
int fd;
struct key key = {0, 0, };
struct buffer_head * bh;
struct item_head * ih;
unsigned long block;
char code;
loff_t recovered = 0;
int i, j;
reiserfs_bitmap_t bitmap;
int used, not_used;
bitmap = reiserfs_create_bitmap (SB_BLOCK_COUNT (fs));
reiserfs_fetch_disk_bitmap (bitmap, fs);
/* we check how many blocks recoverd items point to are free or used */
used = 0;
not_used = 0;
fd = 0;
while (getline (&line, &n, stdin) != -1) {
if (line [0] == '#' || line [0] == '\n')
continue;
switch (line [0]) {
case 'K':
/* get a key of file which is to be recovered */
if (sscanf (line, "%c %u %u\n", &code, &key.k_dir_id, &key.k_objectid) != 3) {
die ("recover_file: wrong input K format");
}
printf ("Recovering file (%u, %u)\n", key.k_dir_id, key.k_objectid);
break;
case 'N':
/* get a file name */
recovered = 0;
if (sscanf (line, "%c %s\n", &code, name) != 2) {
die ("recover_file: wrong input N format");
}
fd = open (name, O_RDWR | O_CREAT | O_EXCL, 0644);
if (fd == -1)
die ("recover_file: could not create file %s: %s",
name,strerror (errno));
printf ("Recovering file %s..\n", name);
break;
case 'B':
if (!fd)
die ("recover_file: file name is not specified");
if (sscanf (line, "%c %lu\n", &code, &block) != 2) {
die ("recover_file: wrong input B format");
}
bh = bread (fs->s_dev, block, fs->s_blocksize);
if (!bh) {
printf ("reading block %lu failed\n", block);
continue;
}
printf ("working with block %lu..\n", block);
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < node_item_number (bh); i ++, ih ++) {
__u32 * indirect;
struct buffer_head * tmp_bh;
if (!is_indirect_ih (ih) || key.k_dir_id != ih->ih_key.k_dir_id ||
key.k_objectid != ih->ih_key.k_objectid)
continue;
indirect = (__u32 *)B_I_PITEM (bh, ih);
for (j = 0; j < I_UNFM_NUM (ih); j ++) {
block = le32_to_cpu (indirect [j]);
if (!block)
continue;
tmp_bh = bread (fs->s_dev, block, fs->s_blocksize);
if (!tmp_bh) {
printf ("reading block %Lu failed\n", (loff_t)block * fs->s_blocksize);
continue;
}
if (lseek64 (fd, get_offset (&ih->ih_key) + j * fs->s_blocksize - 1,
SEEK_SET) == (loff_t)-1) {
printf ("llseek failed to pos %Ld\n", (loff_t)block * fs->s_blocksize);
brelse (tmp_bh);
continue;
}
if (reiserfs_bitmap_test_bit (bitmap, block))
used ++;
else
not_used ++;
/*printf ("block of file %Ld gets block %lu\n",
(get_offset (&ih->ih_key) - 1) / fs->s_blocksize + j, block);*/
if (write (fd, tmp_bh->b_data, tmp_bh->b_size) != tmp_bh->b_size) {
printf ("write failed to pos %Ld\n", (loff_t)block * fs->s_blocksize);
brelse (tmp_bh);
continue;
}
recovered += fs->s_blocksize;
brelse (tmp_bh);
}
}
brelse (bh);
break;
}
}
printf ("recover_file: %Ld bytes recovered of file %s, key %u %u, %d blocks are free and %d are used\n",
recovered, name, key.k_dir_id, key.k_objectid, not_used, used);
}
#endif
/* read a file containing map of one or more files and either recover
them or just print info */
/*
static void read_map (FILE * fp)
{
int i;
__u32 v32;
char * buf;
__u32 ids [4];
int do_recover = 0;
buf = 0;
while (1) {
if (fread (&v32, sizeof (v32), 1, fp) != 1)
break;
if (v32 != MAP_MAGIC)
reiserfs_panic ("read_map: no magic found");
// device name length and name itself
fread (&v32, sizeof (v32), 1, fp);
buf = realloc (buf, v32);
if (!buf)
reiserfs_panic ("realloc failed");
fread (buf, v32, 1, fp);
reiserfs_warning (stdout, "\"%s\": ", buf);
// file name length and name itself
fread (&v32, sizeof (v32), 1, fp);
buf = realloc (buf, v32);
if (!buf)
reiserfs_panic ("realloc failed");
fread (buf, v32, 1, fp);
// read directory key and poined object key
fread (ids, sizeof (ids), 1, fp);
reiserfs_warning (stdout, "[%K]:\"%s\"-->[%K]\n",
&ids[0], buf, &ids[2]);
//do_recover = user_confirmed (stdout, "recover? (Y):", "Y\n");
//if (do_recover)
// reiserfs_warning (stderr, "recovering not ready\n");
// how many data blocks are there
fread (&v32, sizeof (v32), 1, fp);
if (v32) {
buf = realloc (buf, v32 * 4);
if (!buf)
reiserfs_panic ("realloc failed (%u)", v32);
// read list of data block numbers
fread (buf, 4, v32, fp);
if (!do_recover) {
for (i = 0; i < v32; i ++)
reiserfs_warning (stdout, "%d ", ((__u32 *)buf)[i]);
reiserfs_warning (stdout, "\n");
}
}
// main tail length
fread (&v32, sizeof (v32), 1, fp);
if (v32) {
// there is tail
buf = realloc (buf, v32);
if (!buf)
reiserfs_panic ("realloc failed");
fread (buf, v32, 1, fp);
if (!do_recover)
reiserfs_warning (stdout, "%d bytes long tail\n", v32);
} else {
if (!do_recover)
reiserfs_warning (stdout, "No tail\n");
}
if (fread (&v32, sizeof (v32), 1, fp) != 1)
break;
if (v32 != MAP_END_MAGIC)
reiserfs_panic ("read_map: no magic found");
}
free (buf);
}
void do_recover (reiserfs_filsys_t * fs)
{
FILE * fp;
if (map_file (fs)) {
fp = fopen (map_file (fs), "r");
if (fp == 0) {
reiserfs_warning (stderr, "do_recover: fopen failed: %m");
return;
}
} else {
reiserfs_warning (stderr, "Reading file map from stdin..\n");
fflush (stderr);
fp = stdin;
}
read_map (fp);
if (fp != stdin)
fclose (fp);
}
*/
#include <limits.h>
static long int get_answer(long int max) {
char *answer, *tmp;
size_t n = 0;
long int result = 0;
do {
printf("Which should be left?: ");
getline (&answer, &n, stdin);
result = strtol (answer, &tmp, 0);
if ((errno != ERANGE) && (result < max) && (result >= 0) &&
(answer != tmp))
break;
} while (1);
return result;
}
static void recover_items(FILE *fp, reiserfs_filsys_t * fs, FILE *target_file) {
struct buffer_head *bh, *bh_pointed;
struct item_head *ih;
struct saved_item item, *cur;
int size = sizeof(struct saved_item) - sizeof(struct saved_item *);
struct saved_item *map = NULL;
__u32 map_size = 0;
int start = -1;
unsigned int i, j;
__u64 offset = 0, length;
long int result = 0;
unsigned long unfm_ptr;
while (fread(&item, size, 1, fp) == 1) {
map_size += sizeof(struct saved_item);
map = realloc(map, map_size);
memcpy((void *)map + map_size - sizeof(struct saved_item), &item, size);
}
for (i = 1, cur = map + 1; i <= map_size / sizeof(struct saved_item); i++, cur++) {
bh = bread (fs->fs_dev, (cur - 1)->si_block, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
if (i == map_size / sizeof(struct saved_item)) {
if (start != -1) {
reiserfs_print_item(stdout, bh, B_N_PITEM_HEAD (bh, (cur - 1)->si_item_num));
result = get_answer(i - start) + start;
} else {
result = i - 1;
}
start = -1;
} else if (is_direntry_ih(&(cur - 1)->si_ih) || is_stat_data_ih(&(cur - 1)->si_ih)) {
brelse(bh);
continue;
} else {
length = get_bytes_number(&(cur - 1)->si_ih, fs->fs_blocksize);
if (offset < get_offset(&(cur - 1)->si_ih.ih_key) +
get_bytes_number(&(cur - 1)->si_ih, fs->fs_blocksize))
offset = get_offset(&(cur - 1)->si_ih.ih_key) + (length ? length - 1 : 0);
if (offset >= get_offset(&cur->si_ih.ih_key)) {
/* Problem interval */
if (start == -1)
start = i - 1;
printf("Problem item %d:\n", i - start - 1);
reiserfs_print_item(stdout, bh, B_N_PITEM_HEAD (bh, (cur - 1)->si_item_num));
} else if (start != -1) {
/* problem interval finished */
printf("Problem item %d:\n", i - start - 1);
reiserfs_print_item(stdout, bh, B_N_PITEM_HEAD (bh, (cur - 1)->si_item_num));
result = get_answer((long int)i - start) + start;
start = -1;
} else {
result = i - 1;
}
}
brelse(bh);
if (start != -1)
continue;
printf("write %ld\n", result);
bh = bread (fs->fs_dev, (map + result)->si_block, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
fseek(target_file, get_offset(&(map + result)->si_ih.ih_key) - 1, SEEK_SET);
ih = B_N_PITEM_HEAD (bh, (map + result)->si_item_num);
if (is_direct_ih(ih)) {
fwrite(B_I_PITEM(bh, ih), (map + result)->si_ih.ih2_item_len, 1, target_file);
} else if (is_indirect_ih(ih)) {
for (j = 0; j < I_UNFM_NUM (ih); j ++) {
unfm_ptr = d32_get((__u32 *)B_I_PITEM(bh, ih), j);
if (!unfm_ptr) {
fseek(target_file, fs->fs_blocksize, SEEK_CUR);
continue;
}
bh_pointed = bread (fs->fs_dev, unfm_ptr, fs->fs_blocksize);
if (!bh_pointed) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
fwrite(bh_pointed->b_data, fs->fs_blocksize, 1, target_file);
brelse(bh_pointed);
}
}
brelse(bh);
}
free(map);
}
void do_recover(reiserfs_filsys_t * fs) {
FILE *fp, *recovery;
if (map_file (fs)) {
fp = fopen (map_file (fs), "r");
if (fp == 0) {
reiserfs_warning (stderr, "fopen failed: %m\n");
return;
}
} else {
reiserfs_warning (stderr, "Reading file map from stdin..\n");
fflush (stderr);
fp = stdin;
}
if (!(recovery = fopen(recovery_file(fs), "w+"))) {
reiserfs_warning (stderr, "fopen failed: %m\n");
return;
}
recover_items(fp, fs, recovery);
if (fp != stdin)
fclose (fp);
fclose(recovery);
}
+1083
View File
File diff suppressed because it is too large. Load diff
+274
View File
@@ -0,0 +1,274 @@
/*
* Copyright 2002-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#include "debugreiserfs.h"
#include <search.h>
#include <obstack.h>
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
/* try to find blocks which contain only items which are */
/* read blocks marked in debug_bitmap and collect statistic of it:
number of stat data */
struct {
unsigned long all;
unsigned long items [5];
unsigned long unique_keys; /* keys of stat datas */
unsigned long unique_entry_keys; /* keys which appear in directory entries */
unsigned long names; /* dir entries but "." and ".." */
unsigned long dir_blocks; /* block containing only one directory item */
unsigned long unique_items;
unsigned long leaves;
unsigned long blocks_to_skip;
} fs_stat;
/* store unique item heads */
struct obstack items;
/* tree sorting item heades by comp_items_1 */
void * items_tree;
static int comp_items_1 (const void * p1, const void * p2)
{
int retval;
struct item_head * ih1, * ih2;
/*
if (*(int *)p1 != *(int *)p2)
retval = 1;
else
retval = 0;
*/
retval = comp_keys (p1, p2);
/*retval = comp_short_keys (p1, p2);*/
if (retval)
return retval;
ih1 = (struct item_head *)p1;
ih2 = (struct item_head *)p2;
if (get_ih_item_len (ih1) < get_ih_item_len (ih2))
return -1;
if (get_ih_item_len (ih1) > get_ih_item_len (ih2))
return 1;
if (get_ih_entry_count (ih1) < get_ih_entry_count (ih2))
return -1;
if (get_ih_entry_count (ih1) > get_ih_entry_count (ih2))
return 1;
return 0;
}
/*
static void print_node (const void *nodep, VISIT value, int level)
{
int i;
if (value == leaf) {
for (i = 0; i < level; i ++)
reiserfs_warning (stdout, "\t");
reiserfs_warning (stdout, "%H\n", *(struct item_head **)nodep);
return;
}
if (value == postorder) {
for (i = 0; i < level; i ++)
reiserfs_warning (stdout, "\t");
reiserfs_warning (stdout, "%H\n", *(struct item_head **)nodep);
}
}
*/
static int is_unique_item (struct obstack * ostack, void ** tree, void * ih)
{
void * res;
void * key1;
key1 = obstack_copy (ostack, ih, IH_SIZE);
res = tsearch (key1, tree, comp_items_1);
if (!res)
reiserfs_panic ("Too many keys found");
/* twalk (*tree, print_node);*/
/* reiserfs_warning (stderr, "\n\n");*/
if (*(void **)res != key1) {
/* key is in tree already, remove it from obstack */
/*reiserfs_warning (stdout, "%H is skipped\n", ih);fflush (stdout);*/
obstack_free (ostack, key1);
return 0;
}
/*reiserfs_warning (stdout, "%k is added\n", ih);fflush (stdout);*/
return 1;
}
static void stat1_the_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
int i, i_num;
struct item_head * ih;
int is_there_unique_item;
ih = B_N_PITEM_HEAD (bh, 0);
is_there_unique_item = 0;
i_num = leaf_item_number_estimate(bh);
for (i = 0; i < i_num; i ++, ih ++) {
/* count all items */
fs_stat.all ++;
if (is_unique_item (&items, &items_tree, ih)) {
/* this is item we have not seen yet */
fs_stat.unique_items ++;
is_there_unique_item ++;
}
}
if (!is_there_unique_item) {
/* the node contains only items we have seen already. so we will skip
it */
fs_stat.blocks_to_skip ++;
reiserfs_bitmap_clear_bit (input_bitmap (fs), bh->b_blocknr);
} else {
ih = B_N_PITEM_HEAD (bh, 0);
/* node contains at least one unique item. We will put it in, count items of each type */
for (i = 0; i < i_num; i ++, ih ++) {
fs_stat.items [get_type (&ih->ih_key)] ++;
}
}
}
/*
static void stat2_the_leaf (struct buffer_head * bh)
{
int i;
struct item_head * ih;
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < node_item_number (bh); i ++, ih ++) {
}
}
*/
void do_stat (reiserfs_filsys_t * fs)
{
unsigned long i;
unsigned long done, total;
struct buffer_head * bh;
int type;
FILE * fp;
obstack_init (&items);
items_tree = 0;
/*
bh = bread (fs->s_dev, 8211, fs->s_blocksize);
stat1_the_leaf (fs, bh);
return;
*/
/* pass 0 of stating */
total = reiserfs_bitmap_ones (input_bitmap (fs));
done = 0;
for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) {
if (!reiserfs_bitmap_test_bit (input_bitmap (fs), i))
continue;
print_how_far (stderr, &done, total, 1, be_quiet (fs));
bh = bread (fs->fs_dev, i, fs->fs_blocksize);
if (!bh) {
printf ("could not read block %lu\n", i);
continue;
}
type = who_is_this (bh->b_data, bh->b_size);
if (type != THE_LEAF && type != HAS_IH_ARRAY) {
reiserfs_bitmap_clear_bit (input_bitmap (fs), i);
brelse (bh);
continue;
}
fs_stat.leaves ++;
stat1_the_leaf (fs, bh);
brelse (bh);
}
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"
"\t\tindirect %lu\n"
"\t\tdirect %lu\n"
"\t\tdirectory items %lu\n"
"\tunique items %lu\n",
/*
"\tnames there (but \".\" and \"..\") %lu\n"
"\tpointing to unique keys %lu\n"
"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,
fs_stat.blocks_to_skip,
fs_stat.items [TYPE_STAT_DATA],
fs_stat.items [TYPE_INDIRECT],
fs_stat.items [TYPE_DIRECT],
fs_stat.items [TYPE_DIRENTRY],
fs_stat.unique_items);
/*
fs_stat.names,
fs_stat.unique_keys,
fs_stat.items [4],
fs_stat.dir_blocks);
*/
if (!input_bitmap_file_name(fs))
return;
fp = fopen (input_bitmap_file_name(fs), "w");
if (!fp) {
reiserfs_exit (1, "could not open %s to save bitmap: %m\n",
input_bitmap_file_name(fs));
}
reiserfs_warning (stderr, "Updated bitmap contains %d blocks marked\n",
reiserfs_bitmap_ones (input_bitmap (fs)));
reiserfs_bitmap_save (fp, input_bitmap (fs));
fclose (fp);
return;
/* pass 2 of stating */
reiserfs_warning (stderr, "Looking for blocks containing only keys not pointed by any of entries\n");
total = reiserfs_bitmap_ones (input_bitmap (fs));
done = 0;
for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) {
if (!reiserfs_bitmap_test_bit (input_bitmap (fs), i))
continue;
print_how_far (stderr, &done, total, 1, be_quiet (fs));
bh = bread (fs->fs_dev, i, fs->fs_blocksize);
if (!bh) {
printf ("could not read block %lu\n", i);
continue;
}
/*stat2_the_leaf (bh);*/
}
}
+631
View File
@@ -0,0 +1,631 @@
/*
* Copyright 2000-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#include "debugreiserfs.h"
#include <sys/resource.h>
#define print_usage_and_exit() die ("Usage: %s [-v] [-b filename] device\n\
-v prints blocks number of every block unpacked\n\
-b filename saves bitmap of blocks unpacked to filename\n\
-j filename stores journal in the filename\n", argv[0]);
/* when super block gets unpacked for the first time - create a bitmap
and mark in it what have been unpacked. Save that bitmap at the end */
reiserfs_bitmap_t * what_unpacked = 0;
int leaves, full;
int verbose = 0;
int Default_journal = 1;
static void unpack_offset (struct packed_item * pi, struct item_head * ih, int blocksize)
{
if (get_pi_mask(pi) & OFFSET_BITS_64) {
__u64 v64;
if (get_ih_key_format (ih) != KEY_FORMAT_2)
die ("unpack_offset: key format is not set or wrong");
fread_le64 (&v64);
set_offset (KEY_FORMAT_2, &ih->ih_key, v64);
return;
}
if (get_pi_mask(pi) & OFFSET_BITS_32) {
__u32 v32;
fread_le32 (&v32);
set_offset (get_ih_key_format (ih), &ih->ih_key, v32);
return;
}
if ((get_pi_mask(pi) & DIR_ID) == 0 && (get_pi_mask(pi) & OBJECT_ID) == 0) {
/* offset was not sent, as it can be calculated looking at the
previous item */
if (is_stat_data_ih (ih - 1))
set_offset (get_ih_key_format (ih), &ih->ih_key, 1);
if (is_indirect_ih (ih - 1))
set_offset (get_ih_key_format (ih), &ih->ih_key,
get_offset (&(ih - 1)->ih_key) + get_bytes_number (ih - 1, blocksize));
}
// offset is 0
return;
}
static void unpack_type (struct packed_item * pi, struct item_head * ih)
{
set_type (get_ih_key_format (ih), &ih->ih_key, get_pi_type(pi));
if (type_unknown (&ih->ih_key))
reiserfs_panic ("unpack_type: unknown type %d unpacked for %H\n",
get_pi_type(pi), ih);
}
/* direntry item comes in the following format:
for each entry
mask - 8 bits
entry length - 16 bits
entry itself
deh_objectid - 32 bits
maybe deh_dir_id (32 bits)
maybe gencounter (16)
maybe deh_state (16)
*/
static void unpack_direntry (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih, hashf_t hash_func)
{
__u16 entry_count, namelen, gen_counter, entry_len;
__u8 mask;
int i;
struct reiserfs_de_head * deh;
int location;
char * item;
/* if (!hash_func)
die ("unpack_direntry: hash function is not set");*/
if (!(get_pi_mask(pi) & IH_FREE_SPACE))
die ("ih_entry_count must be packed for directory items");
entry_count = get_ih_entry_count (ih);
/* if (!entry_count)
reiserfs_panic ("unpack_direntry: entry count should be set already");*/
item = bh->b_data + get_ih_location (ih);
deh = (struct reiserfs_de_head *)item;
location = get_pi_item_len(pi);
for (i = 0; i < entry_count; i ++, deh ++) {
fread8 (&mask);
fread_le16 (&entry_len);
location -= entry_len;
set_deh_location (deh, location);
fread (item + location, entry_len, 1, stdin);
/* find name length */
if (*(item + location + entry_len - 1))
namelen = entry_len;
else
namelen = strlen (item + location);
fread32 (&deh->deh2_objectid);
if (mask & HAS_DIR_ID)
fread32 (&deh->deh2_dir_id);
else
set_deh_dirid (deh, get_key_objectid (&ih->ih_key));
if (*(item + location) == '.' && namelen == 1)
/* old or new "." */
set_deh_offset (deh, DOT_OFFSET);
else if (*(item + location) == '.' && *(item + location + 1) == '.' && namelen == 2)
/* old or new ".." */
set_deh_offset (deh, DOT_DOT_OFFSET);
else if (hash_func)
set_deh_offset (deh, hash_value(hash_func, item + location, namelen));
if (mask & HAS_GEN_COUNTER) {
fread_le16 (&gen_counter);
set_deh_offset (deh, get_deh_offset (deh) | gen_counter);
}
if (mask & HAS_STATE)
fread16 (&deh->deh2_state);
else
set_deh_state (deh, (1 << DEH_Visible2));
}
return;
}
/* struct packed_item is already unpacked */
static void unpack_stat_data (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
if (!(get_pi_mask(pi) & IH_FREE_SPACE)) {
/* ih_free_space was not packed - set default */
set_ih_entry_count (ih, 0xffff);
}
if (get_ih_key_format (ih) == KEY_FORMAT_1) {
/* stat data comes in the following format:
if this is old stat data:
mode - 16 bits
nlink - 16 bits
size - 32 bits
blocks/rdev - 32 bits
maybe first_direct byte 32 bits
*/
struct stat_data_v1 * sd;
sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
memset (sd, 0, sizeof (sd));
fread16 (&sd->sd_mode);
fread16 (&sd->sd_nlink);
fread32 (&sd->sd_size);
fread32 (&sd->u.sd_blocks);
if (get_pi_mask(pi) & WITH_SD_FIRST_DIRECT_BYTE) {
fread32 (&sd->sd_first_direct_byte);
} else {
sd->sd_first_direct_byte = 0xffffffff;
}
} else {
/* for new stat data
mode - 16 bits
nlink in either 16 or 32 bits
size in either 32 or 64 bits
blocks - 32 bits
*/
struct stat_data * sd;
sd = (struct stat_data *)B_I_PITEM (bh, ih);
memset (sd, 0, sizeof (sd));
fread16 (&sd->sd_mode);
if (get_pi_mask(pi) & NLINK_BITS_32) {
fread32 (&sd->sd_nlink);
} else {
__u16 nlink16;
fread16 (&nlink16);
set_sd_v2_nlink (sd, le16_to_cpu(nlink16));
}
if (get_pi_mask(pi) & SIZE_BITS_64) {
fread64 (&sd->sd_size);
} else {
__u32 size32;
/* We need the endian conversions since sd->sd_size is 64 bit */
fread_le32 (&size32);
set_sd_v2_size (sd, size32 );
}
fread32 (&sd->sd_blocks);
}
return;
}
/* indirect item comes either in packed form or as is. ih_free_space
can go first */
static void unpack_indirect (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
__u32 * ind_item, * end;
int i;
__u16 v16;
if (!(get_pi_mask(pi) & IH_FREE_SPACE)) {
/* ih_free_space was not packed - set default */
set_ih_entry_count (ih, 0);
}
ind_item = (__u32 *)B_I_PITEM (bh, ih);
if (get_pi_mask(pi) & SAFE_LINK) {
d32_put(ind_item, 0, get_key_dirid(&ih->ih_key));
set_key_dirid(&ih->ih_key, (__u32)-1);
return;
}
if (get_pi_mask(pi) & WHOLE_INDIRECT) {
fread (ind_item, get_pi_item_len(pi), 1, stdin);
return;
}
end = ind_item + I_UNFM_NUM (ih);
while (ind_item < end) {
__u32 base;
fread32 (ind_item);
fread_le16 (&v16);
base = d32_get(ind_item, 0);
for (i = 1; i < v16; i ++) {
if (base != 0)
d32_put(ind_item, i, base + i);
else
d32_put(ind_item, i, 0);
}
ind_item += i;
}
return;
}
// FIXME: we have no way to preserve symlinks
static void unpack_direct (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
__u32 * d_item = (__u32 *)B_I_PITEM (bh, ih);
if (!(get_pi_mask(pi) & IH_FREE_SPACE))
/* ih_free_space was not packed - set default */
set_ih_entry_count (ih, 0xffff);
if (get_pi_mask(pi) & SAFE_LINK) {
d32_put(d_item, 0, get_key_dirid(&ih->ih_key));
set_key_dirid(&ih->ih_key, (__u32)-1);
} else {
memset (d_item, 'a', get_pi_item_len(pi));
}
return;
}
static void unpack_leaf (int dev, hashf_t hash_func, __u16 blocksize)
{
static int unpacked_leaves = 0;
struct buffer_head * bh;
struct packed_item pi;
struct item_head * ih;
int i;
__u16 v16;
__u32 v32;
/* block number */
fread_le32 (&v32);
/* item number */
fread_le16 (&v16);
if (verbose)
reiserfs_warning (stderr, "leaf %d: %d items\n", v32, v16);
bh = getblk (dev, v32, blocksize);
if (!bh)
die ("unpack_leaf: getblk failed");
set_blkh_nr_items (B_BLK_HEAD (bh), v16);
set_blkh_level (B_BLK_HEAD (bh), DISK_LEAF_NODE_LEVEL);
set_blkh_free_space (B_BLK_HEAD (bh), MAX_FREE_SPACE (bh->b_size));
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) {
#if 0
fread32 (&v32);
if (v32 != ITEM_START_MAGIC)
die ("unpack_leaf: no start item magic found: block %lu, item %i",
bh->b_blocknr, i);
#endif
fread (&pi, sizeof (struct packed_item), 1, stdin);
/* dir_id - if it is there */
if (get_pi_mask(&pi) & DIR_ID) {
fread32 (&v32);
set_key_dirid (&ih->ih_key, le32_to_cpu(v32));
} else {
if (!i)
die ("unpack_leaf: dir_id is not set");
set_key_dirid (&ih->ih_key, get_key_dirid (&(ih - 1)->ih_key));
}
/* object_id - if it is there */
if (get_pi_mask(&pi) & OBJECT_ID) {
fread32 (&v32);
set_key_objectid (&ih->ih_key, le32_to_cpu(v32));
} else {
if (!i)
die ("unpack_leaf: object_id is not set");
set_key_objectid (&ih->ih_key, get_key_objectid (&(ih - 1)->ih_key));
}
// we need to set item format before offset unpacking
set_ih_key_format (ih, (get_pi_mask(&pi) & NEW_FORMAT) ? KEY_FORMAT_2 : KEY_FORMAT_1);
// offset
unpack_offset (&pi, ih, bh->b_size);
/* type */
unpack_type (&pi, ih);
/* ih_free_space and ih_format */
if (get_pi_mask(&pi) & IH_FREE_SPACE) {
fread16 (&v16);
set_ih_entry_count (ih, le16_to_cpu(v16));
}
if (get_pi_mask(&pi) & IH_FORMAT)
fread16 (&ih->ih_format);
/* item length and item location */
set_ih_item_len (ih, get_pi_item_len(&pi));
set_ih_location (ih, (i ? get_ih_location (ih - 1) : bh->b_size) - get_pi_item_len(&pi));
// item itself
if (is_direct_ih (ih)) {
unpack_direct (&pi, bh, ih);
} else if (is_indirect_ih (ih)) {
unpack_indirect (&pi, bh, ih);
} else if (is_direntry_ih (ih)) {
unpack_direntry (&pi, bh, ih, hash_func);
} else if (is_stat_data_ih (ih)) {
unpack_stat_data (&pi, bh, ih);
}
set_blkh_free_space (B_BLK_HEAD (bh), get_blkh_free_space (B_BLK_HEAD (bh)) -
(IH_SIZE + get_ih_item_len (ih)));
#if 0
fread32 (&v32);
if (v32 != ITEM_END_MAGIC)
die ("unpack_leaf: no end item magic found: block %lu, item %i",
bh->b_blocknr, i);
if (verbose)
reiserfs_warning (stderr, "%d: %H\n", i, ih);
#endif
}
fread_le16 (&v16);
if (v16 != LEAF_END_MAGIC)
die ("unpack_leaf: wrong end signature found - %x, block %lu",
v16, bh->b_blocknr);
mark_buffer_uptodate (bh, 1);
mark_buffer_dirty (bh);
bwrite (bh);
/*
if (!not_data_block (bh->b_blocknr))
data_blocks_unpacked ++;
*/
brelse (bh);
if (what_unpacked)
reiserfs_bitmap_set_bit (what_unpacked, bh->b_blocknr);
/*unpacked ++;*/
if (!(++ unpacked_leaves % 10))
fprintf (stderr, "#");
}
static void unpack_full_block (int dev, int blocksize)
{
static int full_blocks_unpacked = 0;
__u32 block;
struct buffer_head * bh;
fread_le32 (&block);
if (verbose)
fprintf (stderr, "full #%d\n", block);
bh = getblk (dev, block, blocksize);
if (!bh)
die ("unpack_full_block: getblk failed");
fread (bh->b_data, bh->b_size, 1, stdin);
if (who_is_this (bh->b_data, bh->b_size) == THE_SUPER && !what_unpacked) {
unsigned long blocks;
struct buffer_head * tmp;
blocks = get_sb_block_count ((struct reiserfs_super_block *)(bh->b_data));
fprintf (stderr, "There were %lu blocks on the device\n", blocks);
what_unpacked = reiserfs_create_bitmap (blocks);
/* make file as long as filesystem is */
tmp = getblk (dev, blocks - 1, blocksize);
mark_buffer_dirty (tmp);
mark_buffer_uptodate (tmp, 0);
bwrite (tmp);
brelse (tmp);
}
mark_buffer_uptodate (bh, 1);
mark_buffer_dirty (bh);
bwrite (bh);
/*
if (!not_data_block (bh->b_blocknr))
data_blocks_unpacked ++;
*/
brelse (bh);
if (what_unpacked)
reiserfs_bitmap_set_bit (what_unpacked, block);
/*unpacked ++;*/
if (!(++ full_blocks_unpacked % 50))
fprintf (stderr, ".");
}
/* just skip bitmaps of unformatted nodes */
static void unpack_unformatted_bitmap (int dev, int blocksize)
{
__u16 bmap_num;
__u32 block_count;
int i;
char * buf;
fread_le16 (&bmap_num);
fread_le32 (&block_count);
buf = malloc (blocksize);
if (!buf)
reiserfs_panic ("unpack_unformatted_bitmap: malloc failed: %m");
for (i = 0; i < bmap_num; i ++) {
if (fread (buf, blocksize, 1, stdin) != 1)
reiserfs_panic ("unpack_unformatted_bitmap: "
"could not read bitmap #%d: %m", i);
}
free (buf);
}
// read packed reiserfs partition metadata from stdin
void unpack_partition (int fd, int jfd)
{
__u32 magic32;
long position;
__u16 magic16;
__u16 blocksize;
int dev = fd;
fread_le32 (&magic32);
if (magic32 != REISERFS_SUPER_MAGIC)
die ("unpack_partition: reiserfs magic number (0x%x) not found - %x\n",
REISERFS_SUPER_MAGIC, magic32);
fread_le16 (&blocksize);
if (verbose)
fprintf (stderr, "Blocksize %d\n", blocksize);
while (!feof (stdin)) {
char c[2];
fread (c, 1, 1, stdin);
switch (c[0]) {
case '.':
if (verbose)
fprintf (stderr, "\".\" skipped\n");
continue;
case '1':
fread (c, 1, 1, stdin); /* that was 100%, read in first 0 */
case '2':
case '4':
case '6':
case '8':
fread (c, 1, 1, stdin);
case '0':
fread (c + 1, 1, 1, stdin); /* read % */
if (c[0] != '0' || c[1] != '%')
die ("0%% expected\n");
if (verbose)
fprintf (stderr, "0%% skipped\n");
continue;
}
fread (c + 1, 1, 1, stdin);
magic16 = le16_to_cpu(*(__u16 *)c);
/*fread16 (&magic16);*/
switch (magic16 & 0xff) {
case LEAF_START_MAGIC:
leaves ++;
unpack_leaf (dev, code2func (magic16 >> 8), blocksize);
break;
case SEPARATED_JOURNAL_START_MAGIC:
if (Default_journal)
die ("file name for separated journal has to be specified");
dev = jfd;
break;
case SEPARATED_JOURNAL_END_MAGIC:
dev = fd;
break;
case FULL_BLOCK_START_MAGIC:
full ++;
unpack_full_block (dev, blocksize);
break;
case UNFORMATTED_BITMAP_START_MAGIC:
fprintf (stderr, "\nBitmap of unformatted - ignored\n");
unpack_unformatted_bitmap (dev, blocksize);
break;
case END_MAGIC:
goto out;
default:
position = ftell(stdin);
if (position == ~(long)0)
die ("unpack_partition: bad magic found - %x", magic16 & 0xff);
else
die ("unpack_partition: bad magic found - %x, position %lu",
magic16 & 0xff, ftell(stdin));
}
}
out:
fprintf (stderr, "Unpacked %d leaves, %d full blocks\n", leaves, full);
/* fclose (block_list);*/
}
int do_unpack(char *host, char *j_filename, char *filename, int verbose) {
int fd, fdj = -2;
struct rlimit lim = {RLIM_INFINITY, RLIM_INFINITY};
if (filename == NULL)
filename = ".bitmap";
if (j_filename)
Default_journal = 0;
/* with this 2.4.0-test9's file_write does not send SIGXFSZ */
if (setrlimit (RLIMIT_FSIZE, &lim)) {
fprintf (stderr, "sertlimit failed: %m\n");
}
if (misc_device_mounted(host) > 0) {
fprintf(stderr, "%s seems mounted, umount it first\n", host);
return 0;
}
fd = open (host, O_RDWR | O_LARGEFILE);
if (fd == -1) {
perror ("open failed");
return 0;
}
if (!Default_journal) {
fdj = open (j_filename, O_RDWR | O_LARGEFILE);
if (fdj == -1) {
perror ("open failed");
return 0;
}
}
unpack_partition (fd, fdj);
if (what_unpacked && filename) {
FILE * file = open_file(filename, "w+");
reiserfs_bitmap_save (file, what_unpacked);
close_file(file);
}
close (fd);
if (!Default_journal)
close (fdj);
return 0;
}