Initial commit -- seeded with reiserfsprogs 3.x.0j

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:26:22 -04:00
commit e7102bdb66
77 files changed
+33513

No files matched your search

+10
View File
@@ -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
+339
View File
@@ -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:
+68
View File
@@ -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
+135
View File
@@ -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;
+765
View File
@@ -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
+558
View File
@@ -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;
}