blob: a2bf6c8e26ec7f1aa055e8c35c1b0459d0fcafe7 [file] [log] [blame]
/*
* Copyright 2002 Hans Reiser
*/
#include "debugreiserfs.h"
extern unsigned long * badblocks;
extern int badblocks_nr;
#if 0
static void look_in_transaction (reiserfs_filsys_t * fs,
reiserfs_trans_t * trans)
{
struct buffer_head * d_bh, * c_bh, * logged, * in_place;
struct reiserfs_journal_desc * desc;
struct reiserfs_journal_commit * commit;
int i, j;
int who;
d_bh = bread (fs->fs_dev, trans->desc_blocknr, fs->fs_blocksize);
if (!d_bh) {
reiserfs_warning (stdout, "reading descriptor block %lu failed\n",
trans->desc_blocknr);
return;
}
c_bh = bread (fs->fs_dev, trans->commit_blocknr, fs->fs_blocksize);
if (!c_bh) {
reiserfs_warning (stdout, "reading commit block %lu failed\n",
trans->commit_blocknr);
brelse (d_bh);
return;
}
// desc = (struct reiserfs_journal_desc *)(d_bh->b_data);
// commit = (struct reiserfs_journal_commit *)(c_bh->b_data);
reiserfs_warning (stdout, "Transaction %lu\n", trans->trans_id);
for (i = 0; i < badblocks_nr; i ++) {
for (j = 0; j < get_jd_len (d_bh); j ++) {
if ((j < JOURNAL_TRANS_HALF && badblocks [i] == le32_to_cpu (desc->j2_realblock[j])) ||
(j >= JOURNAL_TRANS_HALF && badblocks [i] == le32_to_cpu (commit->j3_realblock[j - JOURNAL_TRANS_HALF]))) {
reiserfs_warning (stdout,
"\tblock %lu is logged in it (block of journal area %lu - ",
badblocks [i], d_bh->b_blocknr + j + 1);
logged = 0;
in_place = 0;
logged = bread (fs->fs_dev, d_bh->b_blocknr + j + 1, fs->fs_blocksize);
in_place = bread (fs->fs_dev, badblocks [i], fs->fs_blocksize);
if (!logged || !in_place) {
reiserfs_warning (stdout, "Could not read blocks\n");
brelse (logged);
brelse (in_place);
continue;
}
who = who_is_this (logged->b_data, logged->b_size);
if (who != THE_LEAF && who != HAS_IH_ARRAY) {
brelse (logged);
brelse (in_place);
continue;
}
reiserfs_warning (stdout, "%s\n", which_block (who));
if (data (fs)->JJ > 1) {
/* overwrite in-place block with a logged version */
if (who_is_this (in_place->b_data, in_place->b_size) == THE_LEAF)
reiserfs_warning (stderr, "Block %d is leaf already, skip it\n",
in_place->b_blocknr);
else {
memcpy (in_place->b_data, logged->b_data, fs->fs_blocksize);
mark_buffer_dirty (in_place);
bwrite (in_place);
if (input_bitmap (fs))
reiserfs_bitmap_set_bit (input_bitmap (fs), in_place->b_blocknr);
}
}
brelse (logged);
brelse (in_place);
}
}
}
brelse (d_bh);
brelse (c_bh);
}
/* go through all transactions in the journal to check whether block is there */
static void find_in_journal (reiserfs_filsys_t * fs)
{
for_each_transaction (fs, look_in_transaction);
}
#endif
#define BLOCK_IN_Q 12762
static void check_block_9555 (reiserfs_filsys_t * fs, reiserfs_trans_t * trans,
int index,
unsigned long in_journal, unsigned long in_place)
{
struct buffer_head * bh;
if (in_place == 17) {
/* read block of journal which contains block 17 abd check whether bit
BLOCK_IN_Q is set */
bh = bread (fs->fs_journal_dev, in_journal, fs->fs_blocksize);
if (!bh) {
reiserfs_warning (stderr, "could not read block %lu (of journal area)\n",
in_journal);
return;
}
if (test_bit (BLOCK_IN_Q, bh->b_data))
reiserfs_warning (stdout, "trans %lu, pos %d - block 17: block %d is marked used in it\n",
trans->trans_id, index, BLOCK_IN_Q);
else
reiserfs_warning (stdout, "trans %lu, pos %d - block 17: block %d is marked free in it\n",
trans->trans_id, index, BLOCK_IN_Q);
brelse (bh);
}
if (in_place == BLOCK_IN_Q) {
reiserfs_warning (stdout, "trans %lu, block %d is logged at pos %d\n",
trans->trans_id, BLOCK_IN_Q, index);
}
}
/* remove when the problem is found */
static void check_transaction (reiserfs_filsys_t * fs, reiserfs_trans_t * trans)
{
for_each_block (fs, trans, check_block_9555);
}
void scan_journal (reiserfs_filsys_t * fs)
{
for_each_transaction (fs, check_transaction);
}
#if 0
/* read block numbers from stdin, look for them in the journal, and (if -JJ is
given) write then "in-place" amd mark overwritten blocks used in the bitmap
specified with -b */
void scan_journal (reiserfs_filsys_t * fs)
{
char * str = 0;
size_t n = 0;
/* store all blocks which come from stdin */
while (1) {
if (getline (&str, &n, stdin) == -1)
break;
if (!strcmp (str, "\n"))
break;
str [strlen (str) - 1] = 0;
badblocks = realloc (badblocks, (badblocks_nr + 1) * 4);
if (!badblocks)
reiserfs_panic ("realloc failed");
badblocks [badblocks_nr ++] = atol (str);
free (str);
str = 0;
n = 0;
}
if (data (fs)->JJ > 1)
reiserfs_reopen (fs, O_RDWR);
reiserfs_warning (stdout, "%d blocks given\n", badblocks_nr); fflush (stdout);
find_in_journal (fs);
if (data (fs)->JJ > 1 && input_bitmap (fs)) {
FILE * fp;
fp = fopen (input_bitmap_file_name (fs), "w+");
if (!fp) {
reiserfs_warning (stderr, "reiserfs_bitmap_save: could not save bitmap in %s: %m",
input_bitmap_file_name (fs));
return;
}
reiserfs_bitmap_save (fp, input_bitmap (fs));
fclose (fp);
}
}
#endif