Imported reiserfsprogs-3.6.4

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:28:37 -04:00
1 parent b69459eb80
commit 99c89460c3
52 files changed
+2263 -2407

No files matched your search

+6 -3
View File
@@ -1,13 +1,13 @@
.\" -*- nroff -*-
.\" Copyright 1996-2002 Hans Reiser.
.\"
.TH DEBUGREISERFS 8 "January 2002" "Reiserfsprogs 3.6.2"
.TH DEBUGREISERFS 8 "January 2002" "Reiserfsprogs 3.6.4"
.SH NAME
debugreiserfs
.SH SYNOPSIS
.B debugreiserfs
[
.B -dJmoqpS
.B -dDJmoqpS
] [
.B -j \fIdevice
] [
@@ -36,7 +36,10 @@ journal into archive with other metadata
print journal header.
.TP
.B -d
print formatted nodes of the filesystem
print formatted nodes of the internal tree of the filesystem
.TP
.B -D
print formatted nodes of all used blocks of the filesystem
.TP
.B -m
print contents of bitmap (not very useful)
+23 -10
View File
@@ -11,13 +11,14 @@ reiserfs_filsys_t * fs;
#define print_usage_and_exit() {\
fprintf (stderr, "Usage: %s [options] device\n\n\
Options:\n\
-d\t\tprint blocks details\n\
-d\t\tprint blocks details of the internal tree\n\
-D\t\tprint blocks details of all used blocks\n\
-m\t\tprint bitmap blocks\n\
-o\t\tprint objectid map\n\n\
-J\t\tprint journal header\n\
-j journal_device\n\t\tprint journal\n\
-p\t\tsend filesystem metadata to stdout\n\
-S\t\tgo through whole device when running -p\n\
-S\t\thandle all blocks, not only used\n\
-1 block\tblock to print\n\
-q\t\tno speed info (for -p, -s and -n)\n\n", argv[0]);\
exit (16);\
@@ -28,13 +29,14 @@ Options:\n\
-B file\textract list of badblocks\n\
Undocumented options:
-a map_file\n\tstore to the file the map of file. Is used with -n, -N, -r\n
-a map_file\n\tstore to the file the map of file. Is used with -n, -N, -r, -f\n
-f creates a file map.\n
-S\t\tgo through whole device when running -p, -s or -n\n\
-U\t\tgo through unused blocks only when running -p, -s or -n\n\
-D\t\tprint blocks details scanning the device, not the tree as -d does\n\
-b bitmap_file\n\t\trunning -p, -s or -n read blocks marked in this bitmap only\n\
-n\tscan device for specific name in reiserfs directories\n\
-N\tscan tree for specific name in reiserfs directories\n\
-N\tscan tree for specific key in reiserfs directories\n\
-s\tscan device either for specific key or for any metadata\n\
-C\tallow to change reiserfs metadata\n\
-r\tprint map file content.\n\
@@ -100,7 +102,7 @@ static void print_disk_tree (reiserfs_filsys_t * fs, unsigned long block_nr)
static void print_disk_blocks (reiserfs_filsys_t * fs)
{
int j;
int j, type;
unsigned long done = 0, total;
struct buffer_head * bh;
@@ -118,13 +120,14 @@ static void print_disk_blocks (reiserfs_filsys_t * fs)
continue;
}
if (who_is_this (bh->b_data, bh->b_size) != THE_UNKNOWN)
type = who_is_this (bh->b_data, bh->b_size);
if (type != THE_UNKNOWN)
print_block (stdout, fs, bh, PRINT_TREE_DETAILS | PRINT_DIRECT_ITEMS, -1, -1);
if (is_internal_node (bh))
if (type == THE_INTERNAL)
g_stat_info.nr_internals ++;
else if (is_leaf_node (bh))
else if (type == THE_LEAF)
g_stat_info.nr_leaves ++;
brelse (bh);
}
fprintf (stderr, "\n");
@@ -203,7 +206,7 @@ static char * parse_options (struct debugreiserfs_data * data, int argc, char *
data->scan_area = USED_BLOCKS;
data->mode = DO_DUMP;
while ((c = getopt (argc, argv, "a:b:C:SU1:psn:NrdDomj:J:qt")) != EOF) {
while ((c = getopt (argc, argv, "a:b:C:SU1:psn:Nfr:dDomj:J:qt")) != EOF) {
switch (c) {
case 'a': /* -r will read this, -n and -N will write to it */
asprintf (&data->map_file, "%s", optarg);
@@ -264,7 +267,12 @@ static char * parse_options (struct debugreiserfs_data * data, int argc, char *
data->mode = DO_LOOK_FOR_NAME;
break;
case 'f':
data->mode = DO_FILE_MAP;
break;
case 'r':
asprintf (&data->recovery_file, "%s", optarg);
data->mode = DO_RECOVER;
break;
@@ -558,6 +566,11 @@ int main (int argc, char * argv[])
do_scan (fs);
break;
case DO_FILE_MAP:
print_map(fs);
break;
case DO_RECOVER:
do_recover (fs);
break;
+16 -2
View File
@@ -40,6 +40,8 @@ extern reiserfs_filsys_t * fs;
#define DO_LOOK_FOR_NAME 10 /* -N */
#define DO_SCAN_JOURNAL 11 /* -J */
#define DO_EXTRACT_BADBLOCKS 12
#define DO_FILE_MAP 13
/*first bits are in reiserfs_fs.b*/
#define PRINT_JOURNAL 0x10
@@ -221,7 +223,8 @@ struct debugreiserfs_data {
char * pattern; /* for -n */
char * device_name;
char * journal_device_name; /* for -j */
char * map_file; /* for -n, -N and -r */
char * map_file; /* for -n, -N and -f */
char * recovery_file; /* for -r */
unsigned long options; /* -q only yet*/
int JJ;
@@ -238,7 +241,7 @@ struct debugreiserfs_data {
#define device_name(fs) (data(fs)->device_name)
#define journal_device_name(fs) (data(fs)->journal_device_name)
#define map_file(fs) (data(fs)->map_file)
#define recovery_file(fs) (data(fs)->recovery_file)
#define be_quiet(fs) (data(fs)->options & BE_QUIET)
@@ -256,3 +259,14 @@ void do_scan (reiserfs_filsys_t * fs);
/* journal.c */
void scan_journal (reiserfs_filsys_t * fs);
void print_map(reiserfs_filsys_t * fs);
struct saved_item {
struct item_head si_ih;
unsigned long si_block;
int si_item_num;
struct saved_item * si_next; /* list of items having the same key */
};
+1 -1
View File
@@ -536,7 +536,7 @@ static void send_block (reiserfs_filsys_t * fs, struct buffer_head * bh, int sen
case HAS_IH_ARRAY:
having_ih_array ++;
fprintf (stderr, "BROKEN BLOCK HEAD %lu\n", bh->b_blocknr);
// fprintf (stderr, "BROKEN BLOCK HEAD %lu\n", bh->b_blocknr);
pack_full_block (fs, bh);
break;
+161 -12
View File
@@ -130,6 +130,7 @@ void do_recover (reiserfs_filsys_t fs)
/* read a file containing map of one or more files and either recover
them or just print info */
/*
static void read_map (FILE * fp)
{
int i;
@@ -146,7 +147,7 @@ static void read_map (FILE * fp)
if (v32 != MAP_MAGIC)
reiserfs_panic ("read_map: no magic found");
/* device name length and name itself */
// device name length and name itself
fread (&v32, sizeof (v32), 1, fp);
buf = realloc (buf, v32);
if (!buf)
@@ -154,32 +155,32 @@ static void read_map (FILE * fp)
fread (buf, v32, 1, fp);
reiserfs_warning (stdout, "\"%s\": ", buf);
/* file name length and name itself*/
// file name length and name itself
fread (&v32, sizeof (v32), 1, fp);
buf = realloc (buf, v32);
if (!buf)
reiserfs_panic ("realloc failed");
fread (buf, v32, 1, fp);
/* read directory key and poined object key */
// read directory key and poined object key
fread (ids, sizeof (ids), 1, fp);
reiserfs_warning (stdout, "[%K]:\"%s\"-->[%K]\n",
&ids[0], buf, &ids[2]);
/*
do_recover = user_confirmed (stdout, "recover? (Y):", "Y\n");
if (do_recover)
reiserfs_warning (stderr, "recovering not ready\n");
*/
//do_recover = user_confirmed (stdout, "recover? (Y):", "Y\n");
//if (do_recover)
// reiserfs_warning (stderr, "recovering not ready\n");
/* how many data blocks are there */
// how many data blocks are there
fread (&v32, sizeof (v32), 1, fp);
if (v32) {
buf = realloc (buf, v32 * 4);
if (!buf)
reiserfs_panic ("realloc failed (%u)", v32);
/* read list of data block numbers */
// read list of data block numbers
fread (buf, 4, v32, fp);
if (!do_recover) {
@@ -189,10 +190,10 @@ static void read_map (FILE * fp)
}
}
/* main tail length */
// main tail length
fread (&v32, sizeof (v32), 1, fp);
if (v32) {
/* there is tail */
// there is tail
buf = realloc (buf, v32);
if (!buf)
reiserfs_panic ("realloc failed");
@@ -236,3 +237,151 @@ void do_recover (reiserfs_filsys_t * fs)
fclose (fp);
}
*/
#include <limits.h>
static long int get_answer(long int max) {
char *answer, *tmp;
size_t n = 0;
long int result = 0;
do {
printf("Which should be left?: ");
getline (&answer, &n, stdin);
result = strtol (answer, &tmp, 0);
if ((errno != ERANGE) && (result < max) && (result >= 0) &&
(answer != tmp))
break;
} while (1);
return result;
}
static void recover_items(FILE *fp, reiserfs_filsys_t * fs, FILE *target_file) {
struct buffer_head *bh, *bh_pointed;
struct item_head *ih;
struct saved_item item, *cur;
int size = sizeof(struct saved_item) - sizeof(struct saved_item *);
struct saved_item *map = NULL;
__u32 map_size = 0;
int i, start = 0, j;
__u64 offset = 0, length;
long int result = 0;
unsigned long unfm_ptr;
while (fread(&item, size, 1, fp) == 1) {
map_size += sizeof(struct saved_item);
map = realloc(map, map_size);
memcpy((void *)map + map_size - sizeof(struct saved_item), &item, size);
}
for (i = 1, cur = map + 1; i <= map_size / sizeof(struct saved_item); i++, cur++) {
bh = bread (fs->fs_dev, (cur - 1)->si_block, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
if (i == map_size / sizeof(struct saved_item)) {
if (start != -1) {
reiserfs_print_item(stdout, bh, B_N_PITEM_HEAD (bh, (cur - 1)->si_item_num));
result = get_answer((long int)i - start) + start;
} else {
result = i - 1;
}
start = -1;
} else if (is_direntry_ih(&(cur - 1)->si_ih)) {
brelse(bh);
continue;
} else {
length = get_bytes_number(&(cur - 1)->si_ih, fs->fs_blocksize);
if (offset < get_offset(&(cur - 1)->si_ih.ih_key) +
get_bytes_number(&(cur - 1)->si_ih, fs->fs_blocksize))
offset = get_offset(&(cur - 1)->si_ih.ih_key) + (length ? length - 1 : 0);
if (offset >= get_offset(&cur->si_ih.ih_key)) {
/* Problem interval */
if (start == -1)
start = i - 1;
printf("Problem item %d:\n", i - start - 1);
reiserfs_print_item(stdout, bh, B_N_PITEM_HEAD (bh, (cur - 1)->si_item_num));
} else if (start != -1) {
/* problem interval finished */
printf("Problem item %d:\n", i - start - 1);
reiserfs_print_item(stdout, bh, B_N_PITEM_HEAD (bh, (cur - 1)->si_item_num));
result = get_answer((long int)i - start) + start;
start = -1;
} else {
result = i - 1;
}
}
brelse(bh);
if (start != -1)
continue;
printf("write %ld\n", result);
bh = bread (fs->fs_dev, (map + result)->si_block, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
fseek(target_file, get_offset(&(map + result)->si_ih.ih_key) - 1, SEEK_SET);
ih = B_N_PITEM_HEAD (bh, (map + result)->si_item_num);
if (is_direct_ih(ih)) {
fwrite(B_I_PITEM(bh, ih), (map + result)->si_ih.ih2_item_len, 1, target_file);
} else if (is_indirect_ih(ih)) {
for (j = 0; j < I_UNFM_NUM (ih); j ++) {
unfm_ptr = le32_to_cpu (((__u32 *)B_I_PITEM(bh, ih))[j]);
if (!unfm_ptr) {
fseek(target_file, fs->fs_blocksize, SEEK_CUR);
continue;
}
bh_pointed = bread (fs->fs_dev, unfm_ptr, fs->fs_blocksize);
if (!bh_pointed) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
fwrite(bh_pointed->b_data, fs->fs_blocksize, 1, target_file);
brelse(bh_pointed);
}
}
brelse(bh);
}
free(map);
}
void do_recover(reiserfs_filsys_t * fs) {
FILE *fp, *recovery;
if (map_file (fs)) {
fp = fopen (map_file (fs), "r");
if (fp == 0) {
reiserfs_warning (stderr, "fopen failed: %m\n");
return;
}
} else {
reiserfs_warning (stderr, "Reading file map from stdin..\n");
fflush (stderr);
fp = stdin;
}
if (!(recovery = fopen(recovery_file(fs), "w+"))) {
reiserfs_warning (stderr, "fopen failed: %m\n");
return;
}
recover_items(fp, fs, recovery);
if (fp != stdin)
fclose (fp);
fclose(recovery);
}
+139 -89
View File
@@ -27,15 +27,6 @@ void * name_index;
regex_t pattern;
struct saved_item {
struct item_head si_ih;
unsigned long si_block;
int si_item_num;
struct saved_item * si_next; /* list of items having the same key */
};
struct saved_name {
unsigned int dirid; /* pointed object */
unsigned int objectid;
@@ -330,7 +321,7 @@ static int have_to_append (struct item_head * ih)
tail_start = (off & ~(fs->fs_blocksize - 1)) + 1;
/* find correct tail first */
// find correct tail first
for (i = 0; i < map.tail_nr; i ++) {
if (map.tails[i].offset == tail_start) {
if (map.tails[i].offset + map.tails[i].len <= off)
@@ -338,7 +329,7 @@ static int have_to_append (struct item_head * ih)
return 0;
}
}
/* there was no this tail yet */
// there was no this tail yet
return 1;
}
return 0;
@@ -366,7 +357,7 @@ static void do_append (struct item_head * ih, void * data)
int tail_start;
int skip;
/* find correct tail first */
// find correct tail first
tail_start = (off & ~(fs->fs_blocksize - 1)) + 1;
skip = (off - 1) & (fs->fs_blocksize - 1);
for (i = 0; i < map.tail_nr; i ++) {
@@ -382,7 +373,7 @@ static void do_append (struct item_head * ih, void * data)
return;
}
}
/* allocate memory for new tail */
// allocate memory for new tail
map.tails = realloc (map.tails, (map.tail_nr + 1) * sizeof (struct tail));
if (!map.tails)
reiserfs_panic ("realloc failed");
@@ -397,10 +388,10 @@ static void do_append (struct item_head * ih, void * data)
}
/* map contains */
// map contains
static void do_overwrite (struct item_head * ih, void * data)
{
int skip; /* now may bytes/pointers to skip */
int skip; // now may bytes/pointers to skip
int to_compare;
int to_append;
loff_t off = get_offset (&ih->ih_key);
@@ -430,11 +421,11 @@ static void do_overwrite (struct item_head * ih, void * data)
int tail_start;
int i;
/* find correct tail first */
// find correct tail first
tail_start = (off & ~(fs->fs_blocksize - 1)) + 1;
for (i = 0; i < map.tail_nr; i ++) {
if (map.tails[i].offset == tail_start) {
/* ih is a part of this tail */
// ih is a part of this tail
skip = (off - 1) & (fs->fs_blocksize - 1);
to_compare = (map.tails[i].len - skip > get_ih_item_len (ih) ? get_ih_item_len (ih) :
map.tails[i].len - skip);
@@ -465,7 +456,7 @@ static void map_one_item (struct saved_item * item)
struct item_head * ih;
void * data;
/* read the block containing the item */
// read the block containing the item
bh = bread (fs->fs_dev, item->si_block, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (stderr, "bread failed\n");
@@ -485,42 +476,7 @@ static void map_one_item (struct saved_item * item)
brelse (bh);
}
static void map_item_list (const void *nodep, VISIT value, int level)
{
struct saved_item * item, * longest;
int bytes, max_bytes;
if (value != leaf && value != postorder)
return;
item = *(struct saved_item **)nodep;
/* 1. find the longest item */
max_bytes = get_bytes_number (&item->si_ih, fs->fs_blocksize);
longest = item;
while (item->si_next) {
item = item->si_next;
bytes = get_bytes_number (&item->si_ih, fs->fs_blocksize);
if (bytes > max_bytes) {
longest = item;
max_bytes = bytes;
}
}
map_one_item (longest);
/* map other items */
item = *(struct saved_item **)nodep;
while (item) {
if (item != longest)
map_one_item (item);
item = item->si_next;
}
}
/* flush map which is in variable map */
// flush map which is in variable map
static void flush_map (reiserfs_filsys_t * fs,
struct key * dir,
char * name,
@@ -534,7 +490,7 @@ static void flush_map (reiserfs_filsys_t * fs,
if (!map_file (fs))
asprintf (&map_file (fs), "%s", ".map");
/*reiserfs_warning (stderr, "Saving maps into %s\n", map_file (fs));*/
//reiserfs_warning (stderr, "Saving maps into %s\n", map_file (fs));
fp = fopen (map_file (fs), "a");
if (fp == 0) {
reiserfs_warning (stderr, "flush_map: fopen failed: %m");
@@ -544,38 +500,38 @@ static void flush_map (reiserfs_filsys_t * fs,
v32 = MAP_MAGIC;
fwrite (&v32, sizeof (v32), 1, fp);
/* device name */
// device name
v32 = strlen (device_name (fs)) + 1;
fwrite (&v32, sizeof (v32), 1, fp);
fwrite (device_name (fs), v32, 1, fp);
/* name length and the name itself */
// name length and the name itself
v32 = strlen (name) + 1;
fwrite (&v32, sizeof (v32), 1, fp);
fwrite (name, v32, 1, fp);
/* short key of a directory */
// short key of a directory
fwrite (dir, SHORT_KEY_SIZE, 1, fp);
/* short key of file */
// short key of file
fwrite (key, SHORT_KEY_SIZE, 1, fp);
/* list of data block pointers */
// list of data block pointers
fwrite (&map.head_len, sizeof (map.head_len), 1, fp);
fwrite (map.head, map.head_len * 4, 1, fp);
/* find correct tail first */
// find correct tail first
for (i = 0; i < map.tail_nr; i ++) {
if (map.tails [i].offset == map.head_len * fs->fs_blocksize) {
/* tail length and the tail itself */
// tail length and the tail itself
fwrite (&map.tails [i].len, sizeof (map.tails [i].len), 1, fp);
fwrite (map.tails [i].data, map.tails [i].len, 1, fp);
break;
}
}
if (i == map.tail_nr) {
/* no tail */
// no tail
v32 = 0;
fwrite (&v32, sizeof (v32), 1, fp);
}
@@ -587,7 +543,42 @@ static void flush_map (reiserfs_filsys_t * fs,
}
/* write map of file to a map file */
// write map of file to a map file
/*
static void map_item_list (const void *nodep, VISIT value, int level)
{
struct saved_item * item, * longest;
int bytes, max_bytes;
if (value != leaf && value != postorder)
return;
item = *(struct saved_item **)nodep;
// 1. find the longest item
max_bytes = get_bytes_number (&item->si_ih, fs->fs_blocksize);
longest = item;
while (item->si_next) {
item = item->si_next;
bytes = get_bytes_number (&item->si_ih, fs->fs_blocksize);
if (bytes > max_bytes) {
longest = item;
max_bytes = bytes;
}
}
map_one_item (longest);
// map other items
item = *(struct saved_item **)nodep;
while (item) {
if (item != longest)
map_one_item (item);
item = item->si_next;
}
}
static void make_file_map (const void *nodep, VISIT value, int level)
{
struct saved_name * name;
@@ -601,13 +592,13 @@ static void make_file_map (const void *nodep, VISIT value, int level)
&name->parent_dirid, name->name);
if (name->items) {
/* initialize the map */
// initialize the map
memset (&map, 0, sizeof (struct file_map));
/* make a map of file */
// make a map of file
twalk (name->items, map_item_list);
/* write map to a file */
// write map to a file
flush_map (fs, (struct key *)&name->parent_dirid, name->name,
(struct key *)&name->dirid);
@@ -624,33 +615,92 @@ static void make_file_map (const void *nodep, VISIT value, int level)
}
}
}
*/
/* file.list will contain list of names such that it can be used as
input for -N */
static void print_name (const void *nodep, VISIT value, int level)
{
struct saved_name * name;
static FILE * fp = 0;
static void print_items(FILE *fp, reiserfs_filsys_t * fs) {
struct buffer_head *bh;
struct item_head *ih;
struct saved_item item;
int size = sizeof(struct saved_item) - sizeof(struct saved_item *);
if (fp == 0) {
fp = fopen ("file.list", "w+");
if (!fp)
reiserfs_panic ("could open file.list: %m");
}
name = *(struct saved_name **)nodep;
if (value == leaf || value == postorder) {
while (name) {
if (name->items)
/* we have found items of this file */
reiserfs_warning (fp, "%u %u %s\n",
name->parent_dirid, name->parent_objectid,
name->name);
name = name->name_next;
while (fread(&item, size, 1, fp) == 1) {
bh = bread (fs->fs_dev, item.si_block, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (fp, "bread failed\n");
continue;
}
ih = B_N_PITEM_HEAD (bh, item.si_item_num);
reiserfs_print_item(stdout, bh, ih);
brelse(bh);
}
}
void print_map(reiserfs_filsys_t * fs) {
FILE * fp;
if (map_file (fs)) {
fp = fopen (map_file (fs), "r");
if (fp == 0) {
reiserfs_warning (stderr, "fopen failed: %m\n");
return;
}
} else {
reiserfs_warning (stderr, "Reading file map from stdin..\n");
fflush (stderr);
fp = stdin;
}
print_items(fp, fs);
if (fp != stdin)
fclose (fp);
}
static FILE *fp = 0;
static void save_items(const void *nodep, VISIT value, int level) {
struct saved_item *item;
if (value != leaf && value != postorder)
return;
item = *(struct saved_item **)nodep;
while (item) {
fwrite(item, sizeof(struct saved_item) - sizeof(struct saved_item *), 1, fp);
item = item->si_next;
}
}
static void make_map(const void *nodep, VISIT value, int level) {
struct saved_name * name;
char *file_name = 0;
static int nr = 0;
name = *(struct saved_name **)nodep;
if (value == leaf || value == postorder) {
while (name) {
asprintf(&file_name, "%s.%d", map_file(fs), ++nr);
reiserfs_warning (stdout, "%d - (%d): [%K]:\"%s\": stored in the %s\n",
nr, name->count, &name->parent_dirid, name->name, file_name);
if (fp == 0) {
fp = fopen (file_name, "w+");
if (!fp)
reiserfs_panic ("could open %s: %m", file_name);
}
if (name->items)
twalk (name->items, save_items);
name = name->name_next;
fclose(fp);
free(file_name);
}
}
}
/* store map if it is a regular file */
static void locate_file (reiserfs_filsys_t * fs, struct key * key)
@@ -932,10 +982,10 @@ void do_scan (reiserfs_filsys_t * fs)
/*twalk (name_index, print_file);*/
/* create map for every file in */
twalk (name_index, make_file_map);
twalk (name_index, make_map);
/* print names of files we have map of in a file 'file.list' */
twalk (name_index, print_name);
/*twalk (name_index, print_name);*/
}