/* * 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