blob: faf31f689fe8e353bdfddd0ec4b9b1a0c9ef195d [file]
/*
* Copyright 1996-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "fsck.h"
#include "misc/malloc.h"
#include "util/device.h"
#include "util/misc.h"
#include <time.h>
/* on pass2 we take leaves which could not be inserted into tree
during pass1 and insert each item separately. It is possible that
items of different objects with the same key can be found. We treat
that in the following way: we put it into tree with new key and
link it into /lost+found directory with name made of dir,oid. When
coming item is a directory - we delete object from the tree, put it
back with different key, link it to /lost+found directory and
insert directory as it is */
static void fsck_pass2_save_result (reiserfs_filsys_t * fs) {
FILE * file;
int retval;
file = util_file_open("temp_fsck_file.deleteme", "w+");
if (!file)
return;
/* to be able to restart from semantic we do not need to save
anything here, but two magic values */
fsck_stage_start_put (file, TREE_IS_BUILT);
fsck_stage_end_put (file);
fclose (file);
retval = rename ("temp_fsck_file.deleteme", state_dump_file (fs));
if (retval != 0)
fsck_progress ("%s: Could not rename the temporary file "
"temp_fsck_file.deleteme to %s",
__FUNCTION__, state_dump_file (fs));
}
/* we have nothing to load from a state file, but we have to fetch
on-disk bitmap, copy it to allocable bitmap, and fetch objectid
map */
void fsck_pass2_load_result (reiserfs_filsys_t * fs) {
fsck_new_bitmap (fs) =
reiserfs_bitmap_create (reiserfs_sb_get_blocks (fs->fs_ondisk_sb));
reiserfs_bitmap_copy (fsck_new_bitmap (fs), fs->fs_bitmap2);
fsck_allocable_bitmap (fs) =
reiserfs_bitmap_create (reiserfs_sb_get_blocks (fs->fs_ondisk_sb));
reiserfs_bitmap_copy (fsck_allocable_bitmap (fs), fs->fs_bitmap2);
fs->block_allocator = reiserfsck_new_blocknrs;
fs->block_deallocator = reiserfsck_free_block;
/* we need objectid map on semantic pass to be able to relocate files */
proper_id_map (fs) = id_map_init();
fetch_objectid_map (proper_id_map (fs), fs);
}
#include <unistd.h>
/* uninsertable blocks are marked by 0s in uninsertable_leaf_bitmap
during the pass 1. They must be not in the tree */
static void do_pass_2 (reiserfs_filsys_t * fs) {
reiserfs_bh_t * bh;
reiserfs_ih_t * ih;
unsigned long total;
unsigned long done;
unsigned long b;
int i, n, ntype;
done = 0;
if (!(total = reiserfs_bitmap_zeros(fsck_uninsertables(fs)) * 2))
return;
fsck_progress ("Pass 2:\n");
/* 2 loops for SD items and others. */
for (n = 0; n < 2; n++) {
b = 0;
while ((b < fsck_uninsertables(fs)->bm_bit_size) &&
reiserfs_bitmap_find_zero_bit(fsck_uninsertables(fs), &b) == 0)
{
bh = reiserfs_buffer_read (fs->fs_dev, b, fs->fs_blocksize);
if (bh == 0) {
fsck_log ("pass_2: Reading of the block (%lu) failed on "
"the device 0x%x\n", b, fs->fs_dev);
goto cont;
}
if (is_block_used (bh->b_blocknr) &&
!(reiserfs_journal_block (fs, bh->b_blocknr) &&
fsck_data(fs)->rebuild.use_journal_area))
{
fsck_log("%s: The block (%lu) is in the tree already. "
"Should not happen.\n", __FUNCTION__, bh->b_blocknr);
goto cont;
}
/* this must be leaf */
ntype = reiserfs_node_type (bh);
if (ntype != NT_LEAF) { // || B_IS_KEYS_LEVEL(bh)) {
fsck_log ("%s: The block (%b), marked as a leaf on "
"the first two passes, is not a leaf! Will "
"be skipped.\n", __FUNCTION__, bh);
goto cont;
}
/* Item-by-item loop. */
for (i = 0, ih = reiserfs_ih_at (bh, 0);
i < reiserfs_node_items (bh); i ++, ih ++)
{
/* Only SD items are inserted initially. */
if (n == 0 && !reiserfs_ih_stat (ih))
continue;
/* All other items are inserted later. */
if (n && reiserfs_ih_stat (ih))
continue;
if (fsck_leaf_item_check (bh, ih, reiserfs_item_by_ih (bh, ih)))
continue;
fsck_tree_insert_item (ih, reiserfs_item_by_ih (bh, ih), 1);
}
if (n) {
pass_2_stat (fs)->leaves ++;
make_allocable (b);
}
if (!fsck_quiet(fs)) {
util_misc_progress (fsck_progress_file (fs),
&done, total, 1, 0);
}
cont:
reiserfs_buffer_close (bh);
b++;
}
}
if (!fsck_quiet(fs))
fsck_progress ("\n");
}
static void fsck_pass2_fini (reiserfs_filsys_t * fs) {
time_t t;
/* we can now flush new_bitmap on disk as tree is built and
contains all data, which were found on dik at start in
used bitmaps */
reiserfs_bitmap_copy (fs->fs_bitmap2, fsck_new_bitmap (fs));
/* we should copy new_bitmap to allocable bitmap, becuase evth what is
used for now (marked as used in new_bitmap) should not be allocable;
and what is not in tree for now should be allocable.
these bitmaps differ because on pass2 we skip those blocks, whose
SD's are not in the tree, and therefore extent items of such bad
leaves points to not used and not allocable blocks. */
/* DEBUG only
if (reiserfs_bitmap_compare (fsck_allocable_bitmap (fs),
fsck_new_bitmap(fs)))
{
fsck_log ("Allocable bitmap differs from the new bitmap after pass2\n");
reiserfs_bitmap_copy (fsck_allocable_bitmap(fs), fsck_new_bitmap (fs));
} */
/* update super block: objectid map, fsck state */
reiserfs_sb_set_state (fs->fs_ondisk_sb, TREE_IS_BUILT);
reiserfs_buffer_mkdirty (fs->fs_super_bh);
/* write all dirty blocks */
fsck_progress ("Flushing..");
id_map_flush(proper_id_map (fs), fs);
fs->fs_dirt = 1;
reiserfs_bitmap_flush (fs->fs_bitmap2, fs);
reiserfs_fs_flush (fs);
fsck_progress ("finished\n");
/* fixme: should be optional */
/* fsck_progress ("Tree is built. Checking it - ");
reiserfsck_check_pass1 ();
fsck_progress ("finished\n");*/
fsck_stage_report (FS_PASS2, fs);
/* free what we do not need anymore */
reiserfs_bitmap_delete (fsck_uninsertables (fs));
if (!fsck_run_one_step (fs)) {
if (fsck_info_ask (fs, "Continue? (Yes):", "Yes\n", 1))
/* reiserfsck continues */
return;
} else
fsck_pass2_save_result (fs);
id_map_free(proper_id_map (fs));
proper_id_map (fs) = 0;
reiserfs_bitmap_delete (fsck_new_bitmap (fs));
reiserfs_bitmap_delete (fsck_allocable_bitmap (fs));
time (&t);
fsck_progress ("###########\n"
"reiserfsck finished pass 2 at %s"
"###########\n", ctime (&t));
fs->fs_dirt = 1;
reiserfs_fs_close (fs);
exit(0);
}
void fsck_pass2 (reiserfs_filsys_t * fs) {
if (fsck_log_file (fs) != stderr)
fsck_log ("####### Pass 2 #######\n");
/* take blocks which were not inserted into tree yet and put each
item separately */
do_pass_2 (fs);
fsck_pass2_fini (fs);
if (reiserfs_sb_get_root (fs->fs_ondisk_sb) == ~(__u32)0 ||
reiserfs_sb_get_root (fs->fs_ondisk_sb) == 0)
misc_die ( "\nNo reiserfs metadata found. If you are sure that you had the reiserfs\n"
"on this partition, then the start of the partition might be changed\n"
"or all data were wiped out. The start of the partition may get changed\n"
"by a partitioner if you have used one. Then you probably rebuilt the\n"
"superblock as there was no one. Zero the block at 64K offset from the\n"
"start of the partition (a new super block you have just built) and try\n"
"to move the start of the partition a few cylinders aside and check if\n"
"debugreiserfs /dev/xxx detects a reiserfs super block. If it does this\n"
"is likely to be the right super block version. \n"
"If this makes you nervous, try www.namesys.com/support.html, and for\n"
"$25 the author of fsck, or a colleague if he is out, will step you\n"
"through it all.\n");
}