Initial commit -- seeded with reiserfsprogs 3.x.0j
This commit is contained in:
commit
e7102bdb66
77 files changed
+33513
No files matched your search
@@ -0,0 +1,10 @@
|
||||
sbin_PROGRAMS = debugreiserfs unpack
|
||||
|
||||
debugreiserfs_SOURCES = debugreiserfs.c pack.c
|
||||
unpack_SOURCES = unpack.c debugreiserfs.h
|
||||
man_MANS = debugreiserfs.8
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
LDADD = ../lib/libmisc.a ../reiserfscore/libcore.a
|
||||
|
||||
INCLUDES = -I../include
|
||||
@@ -0,0 +1,339 @@
|
||||
# Makefile.in generated automatically by automake 1.4 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999 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.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
CC = @CC@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
VERSION = @VERSION@
|
||||
|
||||
sbin_PROGRAMS = debugreiserfs unpack
|
||||
|
||||
debugreiserfs_SOURCES = debugreiserfs.c pack.c
|
||||
unpack_SOURCES = unpack.c debugreiserfs.h
|
||||
man_MANS = debugreiserfs.8
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
LDADD = ../lib/libmisc.a ../reiserfscore/libcore.a
|
||||
|
||||
INCLUDES = -I../include
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
|
||||
|
||||
DEFS = @DEFS@ -I. -I$(srcdir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
debugreiserfs_OBJECTS = debugreiserfs.o pack.o
|
||||
debugreiserfs_LDADD = $(LDADD)
|
||||
debugreiserfs_DEPENDENCIES = ../lib/libmisc.a ../reiserfscore/libcore.a
|
||||
debugreiserfs_LDFLAGS =
|
||||
unpack_OBJECTS = unpack.o
|
||||
unpack_LDADD = $(LDADD)
|
||||
unpack_DEPENDENCIES = ../lib/libmisc.a ../reiserfscore/libcore.a
|
||||
unpack_LDFLAGS =
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
man8dir = $(mandir)/man8
|
||||
MANS = $(man_MANS)
|
||||
|
||||
NROFF = nroff
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
SOURCES = $(debugreiserfs_SOURCES) $(unpack_SOURCES)
|
||||
OBJECTS = $(debugreiserfs_OBJECTS) $(unpack_OBJECTS)
|
||||
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .o .s
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps debugreiserfs/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
mostlyclean-sbinPROGRAMS:
|
||||
|
||||
clean-sbinPROGRAMS:
|
||||
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
|
||||
|
||||
distclean-sbinPROGRAMS:
|
||||
|
||||
maintainer-clean-sbinPROGRAMS:
|
||||
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(sbindir)
|
||||
@list='$(sbin_PROGRAMS)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-sbinPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(sbin_PROGRAMS)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
|
||||
done
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.S.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
|
||||
clean-compile:
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
maintainer-clean-compile:
|
||||
|
||||
debugreiserfs: $(debugreiserfs_OBJECTS) $(debugreiserfs_DEPENDENCIES)
|
||||
@rm -f debugreiserfs
|
||||
$(LINK) $(debugreiserfs_LDFLAGS) $(debugreiserfs_OBJECTS) $(debugreiserfs_LDADD) $(LIBS)
|
||||
|
||||
unpack: $(unpack_OBJECTS) $(unpack_DEPENDENCIES)
|
||||
@rm -f unpack
|
||||
$(LINK) $(unpack_LDFLAGS) $(unpack_OBJECTS) $(unpack_LDADD) $(LIBS)
|
||||
|
||||
install-man8:
|
||||
$(mkinstalldirs) $(DESTDIR)$(man8dir)
|
||||
@list='$(man8_MANS)'; \
|
||||
l2='$(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/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
|
||||
done
|
||||
|
||||
uninstall-man8:
|
||||
@list='$(man8_MANS)'; \
|
||||
l2='$(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/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
|
||||
rm -f $(DESTDIR)$(man8dir)/$$inst; \
|
||||
done
|
||||
install-man: $(MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-man8
|
||||
uninstall-man:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
$(MAKE) $(AM_MAKEFLAGS) uninstall-man8
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $$unique $(LISP)
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = debugreiserfs
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
debugreiserfs.o: debugreiserfs.c debugreiserfs.h ../include/io.h \
|
||||
../include/misc.h ../include/reiserfs_lib.h \
|
||||
../include/reiserfs_fs.h ../version.h
|
||||
pack.o: pack.c debugreiserfs.h ../include/io.h ../include/misc.h \
|
||||
../include/reiserfs_lib.h ../include/reiserfs_fs.h ../version.h
|
||||
unpack.o: unpack.c debugreiserfs.h ../include/io.h ../include/misc.h \
|
||||
../include/reiserfs_lib.h ../include/reiserfs_fs.h ../version.h
|
||||
|
||||
info-am:
|
||||
info: info-am
|
||||
dvi-am:
|
||||
dvi: dvi-am
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
installcheck-am:
|
||||
installcheck: installcheck-am
|
||||
install-exec-am: install-sbinPROGRAMS
|
||||
install-exec: install-exec-am
|
||||
|
||||
install-data-am: install-man
|
||||
install-data: install-data-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-am
|
||||
uninstall-am: uninstall-sbinPROGRAMS uninstall-man
|
||||
uninstall: uninstall-am
|
||||
all-am: Makefile $(PROGRAMS) $(MANS)
|
||||
all-redirect: all-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \
|
||||
mostlyclean-tags mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
clean-am: clean-sbinPROGRAMS clean-compile clean-tags clean-generic \
|
||||
mostlyclean-am
|
||||
|
||||
clean: clean-am
|
||||
|
||||
distclean-am: distclean-sbinPROGRAMS distclean-compile distclean-tags \
|
||||
distclean-generic clean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-sbinPROGRAMS \
|
||||
maintainer-clean-compile maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \
|
||||
clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
|
||||
install-sbinPROGRAMS mostlyclean-compile distclean-compile \
|
||||
clean-compile maintainer-clean-compile install-man8 uninstall-man8 \
|
||||
install-man uninstall-man tags mostlyclean-tags distclean-tags \
|
||||
clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
|
||||
check-am installcheck-am installcheck install-exec-am install-exec \
|
||||
install-data-am install-data install-am install uninstall-am uninstall \
|
||||
all-redirect all-am all installdirs mostlyclean-generic \
|
||||
distclean-generic clean-generic maintainer-clean-generic clean \
|
||||
mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# 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:
|
||||
@@ -0,0 +1,68 @@
|
||||
.\" -*- nroff -*-
|
||||
.\" Copyright 1996-2001 Hans Reiser.
|
||||
.\"
|
||||
.TH DEBUGREISERFS 8 "March 2001" "Reiserfsprogs 3.x.0j"
|
||||
.SH NAME
|
||||
debugreiserfs
|
||||
.SH SYNOPSIS
|
||||
.B debugreiserfs
|
||||
[
|
||||
.B -jdcmos
|
||||
] [
|
||||
.B -b \fIblocknumber
|
||||
] [
|
||||
.B -p \fIfilename.bmp
|
||||
] [
|
||||
.B -P \fIfilename.bmp
|
||||
]
|
||||
.I device
|
||||
.SH DESCRIPTION
|
||||
It helps sometimes to solve problems with reiserfs filesystems. Being
|
||||
called w/o options it prints super block of reiserfs filesystem found
|
||||
on the \fIdevice\fR.
|
||||
.TP
|
||||
.I device
|
||||
is the special file corresponding to the device (e.g /dev/hdXX for
|
||||
IDE disk partition or /dev/sdXX for SCSI disk partition).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB-j
|
||||
print contents of journal
|
||||
.TP
|
||||
\fB-d
|
||||
print formatted nodes of the filesystem
|
||||
.TP
|
||||
\fB-c
|
||||
print contents of direct items
|
||||
.TP
|
||||
\fB-m
|
||||
print contents of bitmap (not very useful)
|
||||
.TP
|
||||
\fB-o
|
||||
print objectid map (not very useful)
|
||||
.TP
|
||||
\fB-s
|
||||
scans the partition and prints a line when any kind of reiserfs formatted nodes found
|
||||
.TP
|
||||
\fB-b \fIblocknumber
|
||||
print specified block of the filesystem
|
||||
.TP
|
||||
\fB-p \fIfilename
|
||||
\fB-P \fIfilename
|
||||
|
||||
Makes \fBdebugreiserfs\fR to find filesystem metadata
|
||||
These exist to help reiserfsck debugging. If reiserfsck fails -
|
||||
you may extract filesystem metadata with \fBdebugreiserfs\fR -p filename /dev/xxx |gzip
|
||||
-c > xxx.gz. We download that data and make the filesystem similar
|
||||
to your with gunzip -c xxx.gz | unpack /dev/xxx (unpack is included
|
||||
into reiserfsprogs package). This usually allows to reproduce and
|
||||
debug the problem quickly. When data file is not too large.
|
||||
-P will cause \fBdebugreiserfs\fR to find and pack metadata from all the device whereas with -p it will only go through blocks marked used in filesystem bitmaps
|
||||
|
||||
.SH AUTHOR
|
||||
This version of \fBdebugreiserfs\fR has been written by Hans Reiser <reiser@idiom.com>.
|
||||
.SH BUGS
|
||||
There are probably few of them. Please, report bugs to Hans Reiser <reiser@idiom.com>.
|
||||
.SH SEE ALSO
|
||||
.BR reiserfsck (8),
|
||||
.BR mkreiserfs (8)
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
#include <asm/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "misc.h"
|
||||
#include "reiserfs_lib.h"
|
||||
#include "../version.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* modes
|
||||
*/
|
||||
#define DO_DUMP 1 /* not a real dump, just printing to stdout contents of
|
||||
tree nodes */
|
||||
#define DO_CORRUPT 2 /* used to make filesystem corruption and then test fsck */
|
||||
#define DO_SCAN 3
|
||||
#define DO_SCAN_FOR_NAME 4
|
||||
#define DO_RECOVER 5
|
||||
#define DO_TEST 6
|
||||
#define DO_PACK 7 /* -p extract meta data of reiserfs filesystem */
|
||||
#define DO_PACK_ALL 8 /* -p */
|
||||
|
||||
extern int opt_quiet;
|
||||
extern int mode;
|
||||
|
||||
|
||||
// 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 0xa5
|
||||
#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 ITEM_START_MAGIC 0x476576
|
||||
#define ITEM_END_MAGIC 0x2906504
|
||||
|
||||
/* flags in packed item mask */
|
||||
#define NEW_FORMAT 1 // 0 here means - old format, 1 - new format
|
||||
#define DIR_ID 2
|
||||
#define OBJECT_ID 4
|
||||
#define OFFSET_BITS_32 8
|
||||
#define OFFSET_BITS_64 16
|
||||
#define ENTRY_COUNT 32 // shows whether ih_free_space/ih_entry_count is stored
|
||||
|
||||
#define INDIRECT_ITEM 64
|
||||
#define DIRENTRY_ITEM 128
|
||||
#define DIRECT_ITEM 256
|
||||
#define STAT_DATA_ITEM 512
|
||||
|
||||
#define ITEM_BODY 1024
|
||||
#define WHOLE_INDIRECT 128
|
||||
#define WITH_SD_FIRST_DIRECT_BYTE 8192 /* for old stat data first_direct_byte
|
||||
is stored */
|
||||
#define NLINK_BITS_32 8192 /* nlinks stored in 32 bits */
|
||||
#define SIZE_BITS_64 16384 /* size has to be stored in 64 bit */
|
||||
|
||||
struct packed_item {
|
||||
/*__u16 length;*/ // length of the area we store item in
|
||||
__u16 mask; // what is stored: dirid, objectid, 32 bit offset or 64 bit offset, type
|
||||
__u16 item_len;
|
||||
};
|
||||
|
||||
#define HAS_DIR_ID 1
|
||||
#define HAS_GEN_COUNTER 2
|
||||
#define HAS_STATE 4
|
||||
#define YURA 8
|
||||
#define TEA 16
|
||||
#define R5 32
|
||||
struct packed_dir_entry {
|
||||
__u8 mask;
|
||||
__u16 entrylen;
|
||||
};
|
||||
|
||||
|
||||
#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 fwrite8(pv) {\
|
||||
if (fwrite (pv, sizeof (__u8), 1, stdout) != 1)\
|
||||
reiserfs_panic ("fwrite8 failed: %m");\
|
||||
}
|
||||
#define fwrite16(pv) {\
|
||||
if (fwrite (pv, sizeof (__u16), 1, stdout) != 1)\
|
||||
reiserfs_panic ("fwrite16 failed: %m");\
|
||||
}
|
||||
#define fwrite32(pv) {\
|
||||
if (fwrite (pv, sizeof (__u32), 1, stdout) != 1)\
|
||||
reiserfs_panic ("fwrite32 failed: %m");\
|
||||
}
|
||||
#define fwrite64(pv) {\
|
||||
if (fwrite (pv, sizeof (__u64), 1, stdout) != 1)\
|
||||
reiserfs_panic ("fwrite64 failed: %m");\
|
||||
}
|
||||
/*
|
||||
#define fwrite16(pv) fwrite (pv, sizeof (__u16), 1, stdout)
|
||||
#define fwrite32(pv) fwrite (pv, sizeof (__u32), 1, stdout)
|
||||
#define fwrite64(pv) fwrite (pv, sizeof (__u64), 1, stdout)
|
||||
*/
|
||||
|
||||
|
||||
#define BLOCKS_PER_READ 8
|
||||
extern char * where_to_save;
|
||||
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*/
|
||||
|
||||
#include "debugreiserfs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
reiserfs_bitmap_t what_to_pack;
|
||||
reiserfs_bitmap_t what_packed;
|
||||
|
||||
int packed_leaves, bad_leaves, full_blocks, internals, descs, full_of_journal;
|
||||
|
||||
|
||||
/* these are to calculate compression */
|
||||
unsigned long sent; /* how many bytes sent to stdout */
|
||||
unsigned long had_to_be_sent; /* how many bytes were to be sent */
|
||||
|
||||
|
||||
|
||||
static void pack_key (struct packed_item * pi, struct item_head * ih)
|
||||
{
|
||||
if (pi->mask & DIR_ID) {
|
||||
fwrite32 (&ih->ih_key.k_dir_id);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
if (pi->mask & OBJECT_ID) {
|
||||
fwrite32 (&ih->ih_key.k_objectid);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
if (pi->mask & OFFSET_BITS_64) {
|
||||
__u64 offset;
|
||||
|
||||
offset = get_offset (&ih->ih_key);
|
||||
fwrite64 (&offset);
|
||||
sent += sizeof (__u64);
|
||||
}
|
||||
|
||||
if (pi->mask & OFFSET_BITS_32) {
|
||||
__u32 offset;
|
||||
|
||||
offset = get_offset (&ih->ih_key);
|
||||
fwrite32 (&offset);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pack_direct (struct packed_item * pi, struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
pi->mask |= DIRECT_ITEM;
|
||||
|
||||
/* send packed item header to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (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 ((!ind_item [i] && !ind_item [i - 1]) || /* hole continues */
|
||||
ind_item [i] == ind_item [i - 1] + 1) { /* subsequent blocks */
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
__u32 * ind_item;
|
||||
__u16 len;
|
||||
|
||||
pi->mask |= INDIRECT_ITEM;
|
||||
if (ih_entry_count (ih))
|
||||
pi->mask |= ENTRY_COUNT;
|
||||
|
||||
ind_item = (__u32 *)B_I_PITEM (bh, ih);
|
||||
if (!should_pack_indirect (ind_item, I_UNFM_NUM (ih)))
|
||||
pi->mask |= WHOLE_INDIRECT;
|
||||
|
||||
/* send packed item header to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
if (pi->mask & ENTRY_COUNT) {
|
||||
__u16 ih_free_space;
|
||||
|
||||
ih_free_space = ih_entry_count (ih);
|
||||
fwrite16 (&ih_free_space);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
|
||||
if (pi->mask & WHOLE_INDIRECT) {
|
||||
fwrite (ind_item, ih_item_len (ih), 1, stdout);
|
||||
sent += ih_item_len (ih);
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite32 (&ind_item [0]);
|
||||
sent += sizeof (__u32);
|
||||
for (i = 1, len = 1; i < I_UNFM_NUM (ih); i ++) {
|
||||
if ((!ind_item [i] && !ind_item [i - 1]) || /* hole continues */
|
||||
ind_item [i] == ind_item[ i - 1] + 1) { /* subsequent blocks */
|
||||
len ++;
|
||||
} else {
|
||||
fwrite16 (&len);
|
||||
fwrite32 (&ind_item[i]);
|
||||
sent += (sizeof (__u32) + sizeof (__u16));
|
||||
len = 1;
|
||||
}
|
||||
}
|
||||
fwrite16 (&len);
|
||||
sent += sizeof (__u16);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
pi->mask |= (DIRENTRY_ITEM | ENTRY_COUNT);
|
||||
|
||||
/* send packed item header to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
/* entry count is sent unconditionally */
|
||||
entry_count = ih_entry_count (ih);
|
||||
fwrite16 (&entry_count);
|
||||
|
||||
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 (deh_dir_id (deh) != le32_to_cpu (ih->ih_key.k_objectid))
|
||||
/* entry points to name of another directory, store deh_dir_id */
|
||||
pe.mask |= HAS_DIR_ID;
|
||||
|
||||
gen_counter = GET_GENERATION_NUMBER (deh_offset (deh));
|
||||
if (gen_counter != 0)
|
||||
/* store generation counter if it is != 0 */
|
||||
pe.mask |= HAS_GEN_COUNTER;
|
||||
|
||||
if (le16_to_cpu (deh->deh_state) != 4)
|
||||
/* something unusual in deh_state. Store it */
|
||||
pe.mask |= HAS_STATE;
|
||||
|
||||
fwrite8 (&pe.mask);
|
||||
fwrite16 (&pe.entrylen);
|
||||
fwrite (name_in_entry (deh, i), pe.entrylen, 1, stdout);
|
||||
fwrite32 (&(deh->deh_objectid));
|
||||
sent += (sizeof (__u8) + sizeof (__u16) + pe.entrylen + sizeof (__u32));
|
||||
|
||||
if (pe.mask & HAS_DIR_ID) {
|
||||
fwrite32 (&deh->deh_dir_id);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
if (pe.mask & HAS_GEN_COUNTER) {
|
||||
fwrite16 (&gen_counter);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
|
||||
if (pe.mask & HAS_STATE) {
|
||||
fwrite16 (&deh->deh_state);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pack_stat_data (struct packed_item * pi, struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
pi->mask |= STAT_DATA_ITEM;
|
||||
|
||||
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)
|
||||
pi->mask |= WITH_SD_FIRST_DIRECT_BYTE;
|
||||
|
||||
/* we are done with packed_item send packed it to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
fwrite16 (&sd_v1->sd_mode);
|
||||
fwrite16 (&sd_v1->sd_nlink);
|
||||
fwrite32 (&sd_v1->sd_size);
|
||||
fwrite32 (&sd_v1->u.sd_blocks);
|
||||
sent += (sizeof (__u16) * 2 + sizeof (__u32) * 2);
|
||||
if (pi->mask & WITH_SD_FIRST_DIRECT_BYTE) {
|
||||
fwrite32 (&sd_v1->sd_first_direct_byte);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
} 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;
|
||||
__u16 nlink16;
|
||||
__u32 nlink32, size32;
|
||||
__u64 size64;
|
||||
|
||||
sd = (struct stat_data *)B_I_PITEM (bh, ih);
|
||||
if (sd->sd_nlink > 0xffff) {
|
||||
pi->mask |= NLINK_BITS_32;
|
||||
nlink32 = sd->sd_nlink;
|
||||
} else {
|
||||
nlink16 = sd->sd_nlink;
|
||||
}
|
||||
if (sd->sd_size > 0xffffffff) {
|
||||
pi->mask |= SIZE_BITS_64;
|
||||
size64 = sd->sd_size;
|
||||
} else {
|
||||
size32 = sd->sd_size;
|
||||
}
|
||||
|
||||
/* we are done with packed_item send packed it to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
fwrite16 (&sd->sd_mode);
|
||||
sent += sizeof (__u16);
|
||||
if (pi->mask & NLINK_BITS_32) {
|
||||
fwrite32 (&nlink32);
|
||||
sent += sizeof (__u32);
|
||||
} else {
|
||||
fwrite16 (&nlink16);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
|
||||
if (pi->mask & SIZE_BITS_64) {
|
||||
fwrite64 (&size64);
|
||||
sent += sizeof (__u64);
|
||||
} else {
|
||||
fwrite32 (&size32);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
fwrite32 (&sd->sd_blocks);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pack_full_block (reiserfs_filsys_t fs, struct buffer_head * bh)
|
||||
{
|
||||
__u16 magic;
|
||||
__u32 block;
|
||||
|
||||
magic = FULL_BLOCK_START_MAGIC;
|
||||
fwrite16 (&magic);
|
||||
|
||||
block = bh->b_blocknr;
|
||||
fwrite32 (&block);
|
||||
|
||||
fwrite (bh->b_data, 4096, 1, stdout);
|
||||
sent += 4096;
|
||||
had_to_be_sent += 4096;
|
||||
|
||||
full_blocks ++;
|
||||
|
||||
if (who_is_this (bh->b_data, bh->b_size) == THE_JDESC)
|
||||
descs ++;
|
||||
if (who_is_this (bh->b_data, bh->b_size) == THE_INTERNAL)
|
||||
internals ++;
|
||||
if (block_of_journal (fs, bh->b_blocknr))
|
||||
full_of_journal ++;
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* 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 < node_item_number (bh); i ++, ih ++) {
|
||||
if (is_it_bad_item (fs, ih, B_I_PITEM (bh, ih), 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)) {
|
||||
/* if something looks suspicious in this leaf - pack whole block */
|
||||
pack_full_block (fs, bh);
|
||||
fprintf (stderr, "leaf %lu is bad\n", bh->b_blocknr);
|
||||
bad_leaves ++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* start magic in low 8 bits, hash code in high 8 bits */
|
||||
v16 = (LEAF_START_MAGIC | (func2code (fs->s_hash_function) << 8));
|
||||
fwrite16 (&v16);
|
||||
|
||||
/* block number */
|
||||
fwrite32 (&bh->b_blocknr);
|
||||
|
||||
/* item number */
|
||||
v16 = node_item_number (bh);
|
||||
fwrite16 (&v16);
|
||||
|
||||
ih = B_N_PITEM_HEAD (bh, 0);
|
||||
|
||||
for (i = 0; i < node_item_number (bh); i ++, ih ++) {
|
||||
#if 0
|
||||
v32 = ITEM_START_MAGIC;
|
||||
fwrite32 (&v32);
|
||||
#endif
|
||||
|
||||
pi.mask = 0;
|
||||
pi.item_len = ih_item_len (ih);
|
||||
|
||||
// format
|
||||
if (ih_key_format (ih) == KEY_FORMAT_2)
|
||||
pi.mask |= NEW_FORMAT;
|
||||
|
||||
// k_dir_id
|
||||
if (!i || (i && ih->ih_key.k_dir_id != (ih - 1)->ih_key.k_dir_id)) {
|
||||
/* if item is first in the leaf or if previous item has different
|
||||
k_dir_id - store it */
|
||||
pi.mask |= DIR_ID;
|
||||
}
|
||||
// k_object_id
|
||||
if (!i || (i && ih->ih_key.k_objectid != (ih - 1)->ih_key.k_objectid)) {
|
||||
/* if item is first in the leaf or if previous item has different
|
||||
k_objectid - store it */
|
||||
pi.mask |= OBJECT_ID;
|
||||
}
|
||||
|
||||
/* store offset if it is != 0 in 32 or 64 bits */
|
||||
if (get_offset (&ih->ih_key)) {
|
||||
if (get_offset (&ih->ih_key) > 0xffffffffULL)
|
||||
pi.mask |= OFFSET_BITS_64;
|
||||
else
|
||||
pi.mask |= OFFSET_BITS_32;
|
||||
}
|
||||
|
||||
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;
|
||||
fwrite16 (&v16);
|
||||
|
||||
packed_leaves ++;
|
||||
had_to_be_sent += 4096;
|
||||
|
||||
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)
|
||||
{
|
||||
if (!can_pack_internal (fs, bh)) {
|
||||
pack_full_block (fs, bh);
|
||||
return;
|
||||
}
|
||||
|
||||
reiserfs_panic ("pack_internal: packing code is not ready");
|
||||
}
|
||||
|
||||
|
||||
static int how_many_to_pack (reiserfs_filsys_t fs, unsigned long first, int count)
|
||||
{
|
||||
int i;
|
||||
int used;
|
||||
|
||||
used = 0;
|
||||
for (i = 0; i < count; i ++) {
|
||||
if ((SB_BLOCK_COUNT (fs) > (first + i)) &&
|
||||
reiserfs_bitmap_test_bit (what_to_pack, first + i))
|
||||
used ++;
|
||||
}
|
||||
return used;
|
||||
}
|
||||
|
||||
|
||||
/* packed blocks are marked free in the bitmap*/
|
||||
static void send_block (reiserfs_filsys_t fs, struct buffer_head * bh)
|
||||
{
|
||||
int type;
|
||||
|
||||
|
||||
if ((type = who_is_this (bh->b_data, bh->b_size)) != THE_LEAF) {
|
||||
if (type == THE_INTERNAL) {
|
||||
pack_internal (fs, bh);
|
||||
} else if (!not_data_block (fs, bh->b_blocknr)) {
|
||||
/* unformatted */
|
||||
return;
|
||||
} else
|
||||
/* bitmaps, super block, blocks of journal - not leaves */
|
||||
pack_full_block (fs, bh);
|
||||
} else
|
||||
pack_leaf (fs, bh);
|
||||
|
||||
reiserfs_bitmap_set_bit (what_packed, bh->b_blocknr);
|
||||
reiserfs_bitmap_clear_bit (what_to_pack, bh->b_blocknr);
|
||||
}
|
||||
|
||||
|
||||
/* super block, journal, bitmaps */
|
||||
static void pack_frozen_data (reiserfs_filsys_t fs)
|
||||
{
|
||||
int i;
|
||||
struct buffer_head * bh;
|
||||
|
||||
/* super block */
|
||||
reiserfs_warning (stderr, "super block..");fflush (stderr);
|
||||
send_block (fs, fs->s_sbh);
|
||||
reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", SB_BMAP_NR (fs));
|
||||
fflush (stderr);
|
||||
|
||||
/* bitmaps */
|
||||
for (i = 0; i < SB_BMAP_NR (fs); i ++) {
|
||||
send_block (fs, SB_AP_BITMAP (fs)[i]);
|
||||
}
|
||||
|
||||
reiserfs_warning (stderr, "ok\njournal (from %lu to %lu)..",
|
||||
rs_journal_start (fs->s_rs),
|
||||
rs_journal_start (fs->s_rs) + rs_journal_size (fs->s_rs));
|
||||
fflush (stderr);
|
||||
/* journal */
|
||||
for (i = rs_journal_start (fs->s_rs);
|
||||
i <= rs_journal_start (fs->s_rs) + rs_journal_size (fs->s_rs);
|
||||
i ++) {
|
||||
bh = bread (fs->s_dev, i, fs->s_blocksize);
|
||||
send_block (fs, bh);
|
||||
brelse (bh);
|
||||
}
|
||||
reiserfs_warning (stderr, "ok\n");fflush (stderr);
|
||||
}
|
||||
|
||||
|
||||
/* pack all "not data blocks" and correct leaf */
|
||||
void pack_partition (reiserfs_filsys_t fs)
|
||||
{
|
||||
int i, j;
|
||||
struct buffer_head tmp, * bh;
|
||||
int nr_to_read = BLOCKS_PER_READ;
|
||||
__u32 magic32;
|
||||
__u16 blocksize;
|
||||
__u16 magic16;
|
||||
unsigned long done = 0, total;
|
||||
|
||||
|
||||
magic32 = REISERFS_SUPER_MAGIC;
|
||||
fwrite32 (&magic32);
|
||||
|
||||
blocksize = fs->s_blocksize;
|
||||
fwrite16 (&blocksize);
|
||||
|
||||
tmp.b_size = blocksize;
|
||||
|
||||
/* will save information about what packed here */
|
||||
what_packed = reiserfs_create_bitmap (SB_BLOCK_COUNT (fs));
|
||||
|
||||
/* will get information about what is to be packed */
|
||||
what_to_pack = reiserfs_create_bitmap (SB_BLOCK_COUNT (fs));
|
||||
if (!what_to_pack)
|
||||
die ("pack_partition: could not create bitmap");
|
||||
if (mode == DO_PACK) {
|
||||
/* read blocks marked used and pack them */
|
||||
reiserfs_fetch_disk_bitmap (what_to_pack, fs);
|
||||
reiserfs_warning (stderr, "Packing blocks marked used on the device %d\n",
|
||||
reiserfs_bitmap_ones (what_to_pack));
|
||||
} else {
|
||||
reiserfs_bitmap_fill (what_to_pack);
|
||||
reiserfs_warning (stderr, "Packing all blocks of the device %d\n",
|
||||
reiserfs_bitmap_ones (what_to_pack));
|
||||
}
|
||||
|
||||
|
||||
/* super block, journal, bitmaps */
|
||||
pack_frozen_data (fs);
|
||||
|
||||
reiserfs_warning (stderr,
|
||||
"Super block, bitmaps, journal - %d blocks - done, %d blocks left\n",
|
||||
reiserfs_bitmap_ones (what_packed), reiserfs_bitmap_ones (what_to_pack));
|
||||
total = reiserfs_bitmap_ones (what_to_pack);
|
||||
|
||||
for (i = 0; i < SB_BLOCK_COUNT (fs); i += nr_to_read) {
|
||||
int to_pack;
|
||||
|
||||
to_pack = how_many_to_pack (fs, i, nr_to_read);
|
||||
if (to_pack) {
|
||||
print_how_far (&done, total, to_pack, opt_quiet);
|
||||
|
||||
bh = bread (fs->s_dev, i / nr_to_read, blocksize * nr_to_read);
|
||||
if (bh) {
|
||||
for (j = 0; j < nr_to_read; j ++) {
|
||||
if (reiserfs_bitmap_test_bit (what_to_pack, i + j)) {
|
||||
tmp.b_data = bh->b_data + j * tmp.b_size;
|
||||
tmp.b_blocknr = i + j;
|
||||
send_block (fs, &tmp);
|
||||
}
|
||||
}
|
||||
brelse (bh);
|
||||
} else {
|
||||
/* bread failed */
|
||||
if (nr_to_read != 1) {
|
||||
/* we tryied to read bunch of blocks. Try to read them by one */
|
||||
nr_to_read = 1;
|
||||
i --;
|
||||
continue;
|
||||
} else {
|
||||
/* we were reading one block at time, and failed, so mark
|
||||
block bad */
|
||||
reiserfs_warning (stderr, "could not read block %lu\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
magic16 = END_MAGIC;
|
||||
fwrite16 (&magic16);
|
||||
|
||||
fprintf (stderr, "Packed\n\tleaves %d\n"
|
||||
"\tfull blocks %d\n"
|
||||
"\t\tof journal %d\n"
|
||||
"\t\tcorrupted leaves %d\n"
|
||||
"\t\tinternals %d\n"
|
||||
"\t\tdescriptors %d\n",
|
||||
packed_leaves, full_blocks, full_of_journal, bad_leaves, internals, descs);
|
||||
fprintf (stderr, "data packed with ratio %.2f\n", (double)sent / had_to_be_sent);
|
||||
|
||||
if (where_to_save)
|
||||
reiserfs_bitmap_save (where_to_save, what_packed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
fwrite32 (&magic32);
|
||||
|
||||
// blocksize
|
||||
fwrite16 (&fs->s_blocksize);
|
||||
|
||||
bh = bread (fs->s_dev, block, fs->s_blocksize);
|
||||
|
||||
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;
|
||||
fwrite16 (&magic16);
|
||||
|
||||
fprintf (stderr, "Packed\n\tleaves %d\n\tfull block %d\n\tcorrupted leaves %d\n",
|
||||
packed_leaves, full_blocks, bad_leaves);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
//
|
||||
// this test program has two modes: 'pack file blocknr'
|
||||
// and 'unpack file'
|
||||
// in the first mode blocknr-th 4k block of the 'file' will be packed out to stdout
|
||||
// the the second mode standart input will be converted to the reiserfs leaf on 'file'
|
||||
//
|
||||
static int do_unpack (char * file)
|
||||
{
|
||||
char * buf;
|
||||
int fd;
|
||||
|
||||
fd = open (file, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror ("open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = malloc (4096);
|
||||
if (!buf) {
|
||||
perror ("malloc failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread (buf, 4096, 1, stdin);
|
||||
if (!feof (stdin)) {
|
||||
printf ("fread returned not eof\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unpack_leaf (buf, fd);
|
||||
|
||||
free (buf);
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_pack (char * file, int block)
|
||||
{
|
||||
int fd;
|
||||
struct buffer_head * bh;
|
||||
char * buf;
|
||||
int len;
|
||||
|
||||
fprintf (stderr, "dumping block %d of the \"%s\"\n", block, file);
|
||||
|
||||
fd = open (file, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror ("open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bh = bread (fd, block, 4096);
|
||||
if (!bh) {
|
||||
fprintf (stderr, "bread failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (who_is_this (bh->b_data, bh->b_size) != THE_LEAF) {
|
||||
fprintf (stderr, "block %d is not a leaf\n", block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = pack_leaf (bh, buf);
|
||||
fwrite (buf, len, 1, stdout);
|
||||
|
||||
free (buf);
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
if (argc == 3 && !strcmp (argv[1], "unpack"))
|
||||
return do_unpack (argv[2]);
|
||||
|
||||
if (argc == 4 && !strcmp (argv[1], "pack"))
|
||||
return do_pack (argv[2], atoi (argv[3]));
|
||||
|
||||
fprintf (stderr, "Usage: \n\t%s pack filename block\nor\n"
|
||||
"\t%s unpack filename\n", argv[0], argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,558 @@
|
||||
/*
|
||||
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/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 makes unpack to save bitmap of blocks unpacked\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 unpacked, data_blocks_unpacked;
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
|
||||
|
||||
static void unpack_offset (struct packed_item * pi, struct item_head * ih)
|
||||
{
|
||||
if (pi->mask & OFFSET_BITS_64) {
|
||||
__u64 v64;
|
||||
|
||||
if (ih_key_format (ih) != KEY_FORMAT_2)
|
||||
die ("unpack_offset: key format is not set or wrong");
|
||||
fread64 (&v64);
|
||||
set_offset (KEY_FORMAT_2, &ih->ih_key, v64);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pi->mask & OFFSET_BITS_32) {
|
||||
__u32 v32;
|
||||
|
||||
fread32 (&v32);
|
||||
set_offset (ih_key_format (ih), &ih->ih_key, v32);
|
||||
return;
|
||||
}
|
||||
|
||||
// offset is 0
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void unpack_type (struct packed_item * pi, struct item_head * ih)
|
||||
{
|
||||
if (pi->mask & DIRECT_ITEM)
|
||||
set_type (ih_key_format (ih), &ih->ih_key, TYPE_DIRECT);
|
||||
else if (pi->mask & STAT_DATA_ITEM)
|
||||
set_type (ih_key_format (ih), &ih->ih_key, TYPE_STAT_DATA);
|
||||
else if (pi->mask & INDIRECT_ITEM)
|
||||
set_type (ih_key_format (ih), &ih->ih_key, TYPE_INDIRECT);
|
||||
else if (pi->mask & DIRENTRY_ITEM)
|
||||
set_type (ih_key_format (ih), &ih->ih_key, TYPE_DIRENTRY);
|
||||
else
|
||||
reiserfs_panic (0, "%h, mask 0%o\n", ih, pi->mask);
|
||||
}
|
||||
|
||||
|
||||
/* direntry item comes in the following format:
|
||||
entry count - 16 bits
|
||||
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");
|
||||
|
||||
fread16 (&entry_count);
|
||||
set_entry_count (ih, entry_count);
|
||||
|
||||
item = bh->b_data + ih_location (ih);
|
||||
deh = (struct reiserfs_de_head *)item;
|
||||
location = pi->item_len;
|
||||
for (i = 0; i < entry_count; i ++, deh ++) {
|
||||
fread8 (&mask);
|
||||
fread16 (&entry_len);
|
||||
location -= entry_len;
|
||||
deh->deh_location = 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->deh_objectid);
|
||||
if (mask & HAS_DIR_ID)
|
||||
fread32 (&deh->deh_dir_id);
|
||||
else
|
||||
deh->deh_dir_id = ih->ih_key.k_objectid;
|
||||
if (*(item + location) == '.' && namelen == 1)
|
||||
/* old or new "." */
|
||||
deh->deh_offset = DOT_OFFSET;
|
||||
else if (*(item + location) == '.' && *(item + location + 1) == '.' && namelen == 2)
|
||||
/* old or new ".." */
|
||||
deh->deh_offset = DOT_DOT_OFFSET;
|
||||
else
|
||||
deh->deh_offset = GET_HASH_VALUE (hash_func (item + location,
|
||||
namelen));
|
||||
if (mask & HAS_GEN_COUNTER) {
|
||||
fread16 (&gen_counter);
|
||||
deh->deh_offset |= gen_counter;
|
||||
}
|
||||
|
||||
if (mask & HAS_STATE)
|
||||
fread16 (&deh->deh_state);
|
||||
else
|
||||
deh->deh_state = (1 << DEH_Visible);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* struct packed_item is already unpacked */
|
||||
static void unpack_stat_data (struct packed_item * pi, struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
set_entry_count (ih, 0xffff);
|
||||
|
||||
if (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 (pi->mask & 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 (pi->mask & NLINK_BITS_32) {
|
||||
fread32 (&sd->sd_nlink);
|
||||
} else {
|
||||
__u16 nlink16;
|
||||
|
||||
fread16 (&nlink16);
|
||||
sd->sd_nlink = nlink16;
|
||||
}
|
||||
|
||||
if (pi->mask & SIZE_BITS_64) {
|
||||
fread64 (&sd->sd_size);
|
||||
} else {
|
||||
__u32 size32;
|
||||
|
||||
fread32 (&size32);
|
||||
sd->sd_size = 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;
|
||||
|
||||
v16 = 0;
|
||||
if (pi->mask & ENTRY_COUNT)
|
||||
fread16 (&v16);
|
||||
|
||||
set_entry_count (ih, v16);
|
||||
|
||||
ind_item = (__u32 *)B_I_PITEM (bh, ih);
|
||||
if (pi->mask & WHOLE_INDIRECT) {
|
||||
fread (ind_item, pi->item_len, 1, stdin);
|
||||
return;
|
||||
}
|
||||
|
||||
end = ind_item + I_UNFM_NUM (ih);
|
||||
while (ind_item < end) {
|
||||
fread32 (ind_item);
|
||||
fread16 (&v16);
|
||||
for (i = 1; i < v16; i ++) {
|
||||
if (ind_item[0])
|
||||
ind_item [i] = ind_item[0] + i;
|
||||
else
|
||||
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)
|
||||
{
|
||||
set_entry_count (ih, 0xffff);
|
||||
memset (bh->b_data + ih_location (ih), 'a', pi->item_len);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void unpack_leaf (int dev, hashf_t hash_func)
|
||||
{
|
||||
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 */
|
||||
fread32 (&v32);
|
||||
|
||||
|
||||
/* item number */
|
||||
fread16 (&v16);
|
||||
|
||||
if (verbose)
|
||||
fprintf (stderr, "leaf %d\n", v32);
|
||||
|
||||
|
||||
|
||||
bh = getblk (dev, v32, 4096);
|
||||
if (!bh)
|
||||
die ("unpack_leaf: getblk failed");
|
||||
|
||||
set_node_item_number (bh, v16);
|
||||
set_node_level (bh, DISK_LEAF_NODE_LEVEL);
|
||||
set_node_free_space (bh, bh->b_size - BLKH_SIZE);
|
||||
|
||||
|
||||
ih = B_N_PITEM_HEAD (bh, 0);
|
||||
for (i = 0; i < v16; 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 (pi.mask & DIR_ID) {
|
||||
fread32 (&v32);
|
||||
ih->ih_key.k_dir_id = v32;
|
||||
} else {
|
||||
if (!i)
|
||||
die ("unpack_leaf: dir_id is not set");
|
||||
ih->ih_key.k_dir_id = (ih - 1)->ih_key.k_dir_id;
|
||||
}
|
||||
|
||||
/* object_id - if it is there */
|
||||
if (pi.mask & OBJECT_ID) {
|
||||
fread32 (&v32);
|
||||
ih->ih_key.k_objectid = v32;
|
||||
} else {
|
||||
if (!i)
|
||||
die ("unpack_leaf: object_id is not set");
|
||||
ih->ih_key.k_objectid = (ih - 1)->ih_key.k_objectid;
|
||||
}
|
||||
|
||||
// we need to set item format before offset unpacking
|
||||
set_key_format (ih, (pi.mask & NEW_FORMAT) ? KEY_FORMAT_2 : KEY_FORMAT_1);
|
||||
|
||||
// offset
|
||||
unpack_offset (&pi, ih);
|
||||
|
||||
/* type */
|
||||
unpack_type (&pi, ih);
|
||||
|
||||
/* item length and item location */
|
||||
set_ih_item_len (ih, pi.item_len);
|
||||
set_ih_location (ih, (i ? ih_location (ih - 1) : bh->b_size) - pi.item_len);
|
||||
|
||||
// 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_node_free_space (bh, node_free_space (bh) - (IH_SIZE + 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);
|
||||
#endif
|
||||
}
|
||||
|
||||
fread16 (&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;
|
||||
|
||||
fread32 (&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;
|
||||
|
||||
blocks = rs_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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
fread16 (&bmap_num);
|
||||
fread32 (&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 dev)
|
||||
{
|
||||
__u32 magic32;
|
||||
__u16 magic16;
|
||||
__u16 blocksize;
|
||||
|
||||
fread32 (&magic32);
|
||||
if (magic32 != REISERFS_SUPER_MAGIC)
|
||||
die ("unpack_partition: reiserfs magic number not found");
|
||||
|
||||
fread16 (&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 = *(__u16 *)c;
|
||||
/*fread16 (&magic16);*/
|
||||
|
||||
switch (magic16 & 0xff) {
|
||||
case LEAF_START_MAGIC:
|
||||
unpack_leaf (dev, code2func (magic16 >> 8));
|
||||
break;
|
||||
|
||||
case FULL_BLOCK_START_MAGIC:
|
||||
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:
|
||||
break;
|
||||
|
||||
default:
|
||||
die ("unpack_partition: bad magic found - %x", magic16 & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (stderr, "Unpacked %d (%d) blocks\n", unpacked, what_unpacked ? reiserfs_bitmap_ones (what_unpacked) : 0);
|
||||
|
||||
|
||||
/* fclose (block_list);*/
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
int fd;
|
||||
int c;
|
||||
char * filename = ".bitmap";
|
||||
struct rlimit lim = {0xffffffff, 0xffffffff};
|
||||
|
||||
print_banner ("unpack");
|
||||
|
||||
/* with this 2.4.0-test9's file_write does not send SIGXFSZ */
|
||||
if (setrlimit (RLIMIT_FSIZE, &lim)) {
|
||||
fprintf (stderr, "sertlimit failed: %m\n");
|
||||
}
|
||||
|
||||
while ((c = getopt (argc, argv, "vb:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
case 'b':
|
||||
asprintf (&filename, "%s", optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optind != argc - 1)
|
||||
/* only one non-option argument is permitted */
|
||||
print_usage_and_exit();
|
||||
|
||||
if (is_mounted (argv[optind]))
|
||||
reiserfs_panic ("%s seems mounted, umount it first\n", argv[optind]);
|
||||
|
||||
fd = open (argv[optind], O_RDWR | O_LARGEFILE);
|
||||
if (fd == -1) {
|
||||
perror ("open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unpack_partition (fd);
|
||||
|
||||
if (what_unpacked && filename)
|
||||
reiserfs_bitmap_save (filename, what_unpacked);
|
||||
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user