Imported reiserfsprogs-3.6.21
This commit is contained in:
1 parent
dac518d099
commit
149a82e2e9
193 files changed
+32708
-44216
No files matched your search
@@ -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
|
||||
@@ -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
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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);*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user