Imported reiserfsprogs-3.6.4
This commit is contained in:
1 parent
b69459eb80
commit
99c89460c3
52 files changed
+2263
-2407
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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);*/
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user