Files
reiserfsprogs/debugreiserfs/stat.c
T
Jeff Mahoney 47cff72748 cleanup: run indent with the Linux Kernel style across all code
Over the years, the reiserfs kernel code has been gradually cleaned up
to be more readable. This patch does the same to the progs code.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
2013-08-26 17:14:42 -04:00

263 lines
6.3 KiB
C

/*
* Copyright 2002-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#include "debugreiserfs.h"
#include <search.h>
#include <obstack.h>
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
/* try to find blocks which contain only items which are */
/* read blocks marked in debug_bitmap and collect statistic of it:
number of stat data */
struct {
unsigned long all;
unsigned long items[5];
unsigned long unique_keys; /* keys of stat datas */
unsigned long unique_entry_keys; /* keys which appear in directory entries */
unsigned long names; /* dir entries but "." and ".." */
unsigned long dir_blocks; /* block containing only one directory item */
unsigned long unique_items;
unsigned long leaves;
unsigned long blocks_to_skip;
} fs_stat;
/* store unique item heads */
struct obstack items;
/* tree sorting item heades by comp_items_1 */
void *items_tree;
static int comp_items_1(const void *p1, const void *p2)
{
int retval;
struct item_head *ih1, *ih2;
/*
if (*(int *)p1 != *(int *)p2)
retval = 1;
else
retval = 0;
*/
retval = comp_keys(p1, p2);
/*retval = comp_short_keys (p1, p2); */
if (retval)
return retval;
ih1 = (struct item_head *)p1;
ih2 = (struct item_head *)p2;
if (get_ih_item_len(ih1) < get_ih_item_len(ih2))
return -1;
if (get_ih_item_len(ih1) > get_ih_item_len(ih2))
return 1;
if (get_ih_entry_count(ih1) < get_ih_entry_count(ih2))
return -1;
if (get_ih_entry_count(ih1) > get_ih_entry_count(ih2))
return 1;
return 0;
}
/*
static void print_node (const void *nodep, VISIT value, int level)
{
int i;
if (value == leaf) {
for (i = 0; i < level; i ++)
reiserfs_warning (stdout, "\t");
reiserfs_warning (stdout, "%H\n", *(struct item_head **)nodep);
return;
}
if (value == postorder) {
for (i = 0; i < level; i ++)
reiserfs_warning (stdout, "\t");
reiserfs_warning (stdout, "%H\n", *(struct item_head **)nodep);
}
}
*/
static int is_unique_item(struct obstack *ostack, void **tree, void *ih)
{
void *res;
void *key1;
key1 = obstack_copy(ostack, ih, IH_SIZE);
res = tsearch(key1, tree, comp_items_1);
if (!res)
reiserfs_panic("Too many keys found");
/* twalk (*tree, print_node);*/
/* reiserfs_warning (stderr, "\n\n");*/
if (*(void **)res != key1) {
/* key is in tree already, remove it from obstack */
/*reiserfs_warning (stdout, "%H is skipped\n", ih);fflush (stdout); */
obstack_free(ostack, key1);
return 0;
}
/*reiserfs_warning (stdout, "%k is added\n", ih);fflush (stdout); */
return 1;
}
static void stat1_the_leaf(reiserfs_filsys_t *fs, struct buffer_head *bh)
{
int i, i_num;
struct item_head *ih;
int is_there_unique_item;
ih = B_N_PITEM_HEAD(bh, 0);
is_there_unique_item = 0;
i_num = leaf_item_number_estimate(bh);
for (i = 0; i < i_num; i++, ih++) {
/* count all items */
fs_stat.all++;
if (is_unique_item(&items, &items_tree, ih)) {
/* this is item we have not seen yet */
fs_stat.unique_items++;
is_there_unique_item++;
}
}
if (!is_there_unique_item) {
/* the node contains only items we have seen already. so we will skip
it */
fs_stat.blocks_to_skip++;
reiserfs_bitmap_clear_bit(input_bitmap(fs), bh->b_blocknr);
} else {
ih = B_N_PITEM_HEAD(bh, 0);
/* node contains at least one unique item. We will put it in, count items of each type */
for (i = 0; i < i_num; i++, ih++) {
fs_stat.items[get_type(&ih->ih_key)]++;
}
}
}
/*
static void stat2_the_leaf (struct buffer_head * bh)
{
int i;
struct item_head * ih;
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < node_item_number (bh); i ++, ih ++) {
}
}
*/
void do_stat(reiserfs_filsys_t *fs)
{
unsigned long i;
unsigned long done, total;
struct buffer_head *bh;
int type;
FILE *fp;
obstack_init(&items);
items_tree = 0;
/*
bh = bread (fs->s_dev, 8211, fs->s_blocksize);
stat1_the_leaf (fs, bh);
return;
*/
/* pass 0 of stating */
total = reiserfs_bitmap_ones(input_bitmap(fs));
done = 0;
for (i = 0; i < get_sb_block_count(fs->fs_ondisk_sb); i++) {
if (!reiserfs_bitmap_test_bit(input_bitmap(fs), i))
continue;
print_how_far(stderr, &done, total, 1, be_quiet(fs));
bh = bread(fs->fs_dev, i, fs->fs_blocksize);
if (!bh) {
printf("could not read block %lu\n", i);
continue;
}
type = who_is_this(bh->b_data, bh->b_size);
if (type != THE_LEAF && type != HAS_IH_ARRAY) {
reiserfs_bitmap_clear_bit(input_bitmap(fs), i);
brelse(bh);
continue;
}
fs_stat.leaves++;
stat1_the_leaf(fs, bh);
brelse(bh);
}
reiserfs_warning(stderr, "\nThere were found on the '%s' device:\n"
"\tleaves %lu\n"
"\ttotal number of items %lu\n"
"\tblocks containing at least one unique item %lu\n"
"\tblocks which can be skipped %lu\n"
"\t\tstat data %lu\n"
"\t\tindirect %lu\n"
"\t\tdirect %lu\n"
"\t\tdirectory items %lu\n" "\tunique items %lu\n",
/*
"\tnames there (but \".\" and \"..\") %lu\n"
"\tpointing to unique keys %lu\n"
"other items %lu\n"
"blocks containing only 1 dir item %lu\n",
*/
fs->fs_file_name,
fs_stat.leaves,
fs_stat.all,
fs_stat.leaves - fs_stat.blocks_to_skip,
fs_stat.blocks_to_skip,
fs_stat.items[TYPE_STAT_DATA],
fs_stat.items[TYPE_INDIRECT],
fs_stat.items[TYPE_DIRECT],
fs_stat.items[TYPE_DIRENTRY], fs_stat.unique_items);
/*
fs_stat.names,
fs_stat.unique_keys,
fs_stat.items [4],
fs_stat.dir_blocks);
*/
if (!input_bitmap_file_name(fs))
return;
fp = fopen(input_bitmap_file_name(fs), "w");
if (!fp) {
reiserfs_exit(1, "could not open %s to save bitmap: %m\n",
input_bitmap_file_name(fs));
}
reiserfs_warning(stderr, "Updated bitmap contains %u blocks marked\n",
reiserfs_bitmap_ones(input_bitmap(fs)));
reiserfs_bitmap_save(fp, input_bitmap(fs));
fclose(fp);
return;
/* pass 2 of stating */
reiserfs_warning(stderr,
"Looking for blocks containing only keys not pointed by any of entries\n");
total = reiserfs_bitmap_ones(input_bitmap(fs));
done = 0;
for (i = 0; i < get_sb_block_count(fs->fs_ondisk_sb); i++) {
if (!reiserfs_bitmap_test_bit(input_bitmap(fs), i))
continue;
print_how_far(stderr, &done, total, 1, be_quiet(fs));
bh = bread(fs->fs_dev, i, fs->fs_blocksize);
if (!bh) {
printf("could not read block %lu\n", i);
continue;
}
/*stat2_the_leaf (bh); */
}
}