/*
 * Copyright 1996-2004 by Hans Reiser, licensing governed by 
 * reiserfsprogs/README 
 */

#include "fsck.h"

reiserfs_bitmap_t * bad_unfm_in_tree_once_bitmap;


//int step = 0; // 0 - find stat_data or any item ; 1 - find item ; 2 - already found


/* allocates buffer head and copy buffer content */
struct buffer_head * make_buffer (int dev, unsigned long blocknr, int size, char * data)
{
    struct buffer_head * bh;
    
    bh = getblk (dev, blocknr, size);
    if (buffer_uptodate (bh))
	return bh;
//    die ("make_buffer: uptodate buffer found");
    memcpy (bh->b_data, data, size);
    misc_set_bit (BH_Uptodate, (char *)&bh->b_state);
    return bh;
}


int find_not_of_one_file(struct key * to_find, struct key * key) {
    if ((get_key_objectid (to_find) != ~(__u32)0) &&
        (get_key_objectid (to_find) != get_key_objectid (key)))
        return 1;
    if ((get_key_dirid (to_find) != ~(__u32)0) &&
        (get_key_dirid (to_find) != get_key_dirid (key)))
        return 1;
    return 0;
}


int is_item_reachable (struct item_head * ih)
{
    return ih_reachable (ih) ? 1 : 0;
}


void mark_item_unreachable (struct item_head * ih)
{
    clean_ih_flags (ih);
    mark_ih_unreachable (ih);

    if (is_indirect_ih (ih))
	set_ih_free_space (ih, 0);
}


void mark_item_reachable (struct item_head * ih, struct buffer_head * bh)
{
    mark_ih_reachable (ih);
    mark_buffer_dirty (bh);
}

static void stat_data_in_tree (struct buffer_head *bh,
			       struct item_head * ih)
{
#if 0
    __u32 objectid;
    
    objectid = get_key_objectid (&ih->ih_key);
    
    if (mark_objectid_really_used (proper_id_map (fs), objectid)) {
	stat_shared_objectid_found (fs);
	mark_objectid_really_used (shared_id_map (fs), objectid);
    }
#endif
    
    zero_nlink (ih, B_I_PITEM (bh, ih));
}

static char *still_bad_unfm_ptr_to_string (int val) {
    switch (val) {
	case 1:
	    return "a leaf";
	case 2:
	    return "shared between a few files";
	case 3:
	    return "not a data block";
	case 4:
	    return "not used in on-disk bitmap";
	case 5:
	    return "out of partition boundary";
    }
    return "";
}

/* this just marks blocks pointed by an indirect item as used in the
   new bitmap */
static void indirect_in_tree (struct buffer_head * bh,
			      struct item_head * ih)
{
    unsigned int i;
    __u32 * unp;
    __u32 unfm_ptr;
    int ret;

    unp = (__u32 *)B_I_PITEM (bh, ih);
    
    for (i = 0; i < I_UNFM_NUM (ih); i ++) {
	unfm_ptr = d32_get (unp, i);
	if (unfm_ptr == 0)
	    continue;
	if ((ret = still_bad_unfm_ptr_1 (unfm_ptr)))
	    reiserfs_panic ("%s: block %lu: The file %k points to the block (%u) which is %s", 
		__FUNCTION__, bh->b_blocknr, &ih->ih_key, unfm_ptr, still_bad_unfm_ptr_to_string(ret));

	mark_block_used (unfm_ptr, 1);
    }
}


static void leaf_is_in_tree_now (struct buffer_head * bh)
{
    item_action_t actions[] = {stat_data_in_tree, indirect_in_tree, 0, 0};

    mark_block_used ((bh)->b_blocknr, 1);

    for_every_item (bh, mark_item_unreachable, actions);

    pass_1_stat (fs)->inserted_leaves ++;

    mark_buffer_dirty (bh);
}


static void insert_pointer (struct buffer_head * bh, struct path * path)
{
    struct item_head * ih;
    char * body;
    int retval;
    struct tree_balance tb;
    
    init_tb_struct (&tb, fs, path, 0x7fff);

    /* fix_nodes & do_balance must work for internal nodes only */
    ih = 0;

    retval = fix_nodes (/*tb.transaction_handle,*/ M_INTERNAL, &tb, ih);
    if (retval != CARRY_ON)
	die ("insert_pointer: fix_nodes failed with retval == %d", retval);
    
    /* child_pos: we insert after position child_pos: this feature of the insert_child */
    /* there is special case: we insert pointer after
       (-1)-st key (before 0-th key) in the parent */
    if (PATH_LAST_POSITION (path) == 0 && path->pos_in_item == 0)
	PATH_H_B_ITEM_ORDER (path, 0) = -1;
    else {
	if (PATH_H_PPARENT (path, 0) == 0)
	    PATH_H_B_ITEM_ORDER (path, 0) = 0;
/*    PATH_H_B_ITEM_ORDER (path, 0) = PATH_H_PPARENT (path, 0) ? PATH_H_B_ITEM_ORDER (path, 0) : 0;*/
    }
    
    ih = 0;
    body = (char *)bh;
    //memmode = 0;

    do_balance (&tb, ih, body, M_INTERNAL, 0);

    leaf_is_in_tree_now (bh);
}


/* return 1 if left and right can be joined. 0 otherwise */
int balance_condition_fails (struct buffer_head * left, struct buffer_head * right)
{
    if (B_FREE_SPACE (left) >= B_CHILD_SIZE (right) -
	(are_items_mergeable (B_N_PITEM_HEAD (left, B_NR_ITEMS (left) - 1), B_N_PITEM_HEAD (right, 0), left->b_size) ? IH_SIZE : 0))
	return 1;
    return 0;
}


/* return 1 if new can be joined with last node on the path or with
   its right neighbor, 0 otherwise */
int balance_condition_2_fails (struct buffer_head * new, struct path * path)
{
    struct buffer_head * bh;
    struct key * right_dkey;
    int pos, used_space;
    
    bh = PATH_PLAST_BUFFER (path);
    

    if (balance_condition_fails (bh, new))
	/* new node can be joined with last buffer on the path */
	return 1;
    
    /* new node can not be joined with its left neighbor */
    
    right_dkey = uget_rkey (path);
    if (right_dkey == 0)
	/* there is no right neighbor */
	return 0;
    
    pos = PATH_H_POSITION (path, 1);
    if (pos == B_NR_ITEMS (bh = PATH_H_PBUFFER (path, 1))) {
	/* we have to read parent of right neighbor. For simplicity we
	   call search_by_key, which will read right neighbor as well */
	INITIALIZE_PATH(path_to_right_neighbor);
	
	if (reiserfs_search_by_key_4 (fs, right_dkey, &path_to_right_neighbor) != ITEM_FOUND)
	    reiserfs_panic ("%s: block %lu, pointer %d: The left delimiting key %k of the block (%lu) is wrong,"
		"the item cannot be found", __FUNCTION__, PATH_H_PBUFFER(path, 1)->b_blocknr, pos, 
		right_dkey, get_dc_child_blocknr(B_N_CHILD (bh, pos + 1)));

	used_space =  B_CHILD_SIZE (PATH_PLAST_BUFFER (&path_to_right_neighbor));
	pathrelse (&path_to_right_neighbor);
    }
    else
	used_space = get_dc_child_size (B_N_CHILD (bh, pos + 1));
    
    if (B_FREE_SPACE (new) >= used_space -
	(are_items_mergeable (B_N_PITEM_HEAD (new, B_NR_ITEMS (new) - 1), (struct item_head *)right_dkey, new->b_size) ? IH_SIZE : 0))
	return 1;

    return 0;
}


static void get_max_buffer_key (struct buffer_head * bh, struct key * key)
{
    struct item_head * ih;

    ih = B_N_PITEM_HEAD (bh, B_NR_ITEMS (bh) - 1);
    copy_key (key, &(ih->ih_key));

    if (is_direntry_key (key)) {
	/* copy deh_offset 3-rd and 4-th key components of the last entry */
	set_offset (KEY_FORMAT_1, key, 
		    get_deh_offset (B_I_DEH (bh, ih) + get_ih_entry_count (ih) - 1));

    } else if (!is_stat_data_key (key))
	/* get key of the last byte, which is contained in the item */
	set_offset (key_format (key), key, get_offset (key) + get_bytes_number (ih, bh->b_size) - 1);
}


int tree_is_empty (void)
{
    return (get_sb_root_block (fs->fs_ondisk_sb) == ~(__u32)0 || 
	    get_sb_root_block (fs->fs_ondisk_sb) == 0) ? 1 : 0;
}


void make_single_leaf_tree (struct buffer_head * bh)
{
    /* tree is empty, make tree root */
    set_sb_root_block (fs->fs_ondisk_sb, bh->b_blocknr);
    set_sb_tree_height (fs->fs_ondisk_sb, 2);
    mark_buffer_dirty (fs->fs_super_bh);
    leaf_is_in_tree_now (bh);
}


/* inserts pointer to leaf into tree if possible. If not, marks node as
   uninsertable in special bitmap */
static void try_to_insert_pointer_to_leaf (struct buffer_head * new_bh)
{
    INITIALIZE_PATH (path);
    struct buffer_head * bh;			/* last path buffer */
    struct key * first_bh_key, last_bh_key;	/* first and last keys of new buffer */
    struct key last_path_buffer_last_key, * right_dkey;
    int ret_value;

    if (tree_is_empty () == 1) {
	make_single_leaf_tree (new_bh);
	return;
    }

    first_bh_key = B_N_PKEY (new_bh, 0);
    
    /* try to find place in the tree for the first key of the coming node */
    ret_value = reiserfs_search_by_key_4 (fs, first_bh_key, &path);
    if (ret_value == ITEM_FOUND)
	goto cannot_insert;

    /* get max key in the new node */
    get_max_buffer_key (new_bh, &last_bh_key);

    bh = PATH_PLAST_BUFFER (&path);
    if (comp_keys (B_N_PKEY (bh, 0), &last_bh_key) == 1/* first is greater*/) {
	/* new buffer falls before the leftmost leaf */
	if (balance_condition_fails (new_bh, bh))
	    goto cannot_insert;
	
	if (uget_lkey (&path) != 0 || PATH_LAST_POSITION (&path) != 0)
	    die ("try_to_insert_pointer_to_leaf: bad search result");
	
	path.pos_in_item = 0;
	goto insert;
    }
    
    /* get max key of buffer, that is in tree */
    get_max_buffer_key (bh, &last_path_buffer_last_key);
    if (comp_keys (&last_path_buffer_last_key, first_bh_key) != -1/* second is greater */)
	/* first key of new buffer falls in the middle of node that is in tree */
	goto cannot_insert;
    
    right_dkey = uget_rkey (&path);
    if (right_dkey && comp_keys (right_dkey, &last_bh_key) != 1 /* first is greater */)
	goto cannot_insert;
    
    if (balance_condition_2_fails (new_bh, &path))
	goto cannot_insert;


 insert:
    insert_pointer (new_bh, &path);
    goto out;
    
 cannot_insert:
    /* statistic */

    mark_block_uninsertable (new_bh->b_blocknr);
    
 out:
    pathrelse (&path);
    return;
}



/* everything should be correct already in the leaf but contents of indirect
   items. So we only
   1. zero slots pointing to a leaf
   2. zero pointers to blocks which are pointed already
   3. what we should do with directory entries hashed by another hash?
   they are deleted for now
*/
static void pass1_correct_leaf (reiserfs_filsys_t * fs,
				struct buffer_head * bh)
{
    unsigned int i, j;
    struct item_head * ih;
    __u32 * ind_item;
    __u32 unfm_ptr;
    int dirty = 0;


    ih = B_N_PITEM_HEAD (bh, 0);
    for (i = 0; i < B_NR_ITEMS (bh); i ++, ih ++) {
	if (is_direntry_ih (ih)) {
	    struct reiserfs_de_head * deh;
	    __u32 offset;
	    char * name;
	    int name_len;
	    unsigned int hash_code;

	    deh = B_I_DEH (bh, ih);
	    offset = 0;
	    for (j = 0; j < get_ih_entry_count (ih); j ++) {
		name = name_in_entry (deh + j, j);
		name_len = name_in_entry_length (ih, deh + j, j);

		if ((j == 0 && is_dot (name, name_len)) ||
		    (j == 1 && is_dot_dot (name, name_len))) {
		    continue;
		}

		hash_code = find_hash_in_use (name, name_len, get_deh_offset (deh + j),
					      get_sb_hash_code (fs->fs_ondisk_sb));
		if (hash_code != get_sb_hash_code (fs->fs_ondisk_sb)) {
		    fsck_log ("pass1: block %lu, item %d, entry %d: The entry \"%.*s\" of the %k is hashed with %s "
			"whereas proper hash is %s", bh->b_blocknr, i, j, name_len, name, &ih->ih_key,
			      code2name (hash_code), code2name (get_sb_hash_code (fs->fs_ondisk_sb)));
		    if (get_ih_entry_count (ih) == 1) {
			delete_item (fs, bh, i);
			fsck_log(" - the only entry - item was deleted\n");
			i --;
			ih --;
			break;
		    } else {
			cut_entry (fs, bh, i, j, 1);
			fsck_log(" - deleted\n");
			j --;
			deh = B_I_DEH (bh, ih);
			continue;
		    }
		}

		if (j && offset >= get_deh_offset (deh + j)) {
		    fsck_log ("pass1: block %lu, item %d, entry %d: The entry "
			      "\"%.*s\" of the %k has hash offset %lu not "
			      "larger smaller than the previous one %lu. The "
			      "entry is deleted.\n", bh->b_blocknr, 
			      i, j, name_len, name, &ih->ih_key, 
			      get_deh_offset(deh + j), offset);
		    cut_entry (fs, bh, i, j, 1);
		    j --;
		    deh = B_I_DEH (bh, ih);
		    continue;
		}

		offset = get_deh_offset (deh + j);
	    }
	    continue;
	}


	if (!is_indirect_ih (ih))
	    continue;

	/* correct indirect items */
	ind_item = (__u32 *)B_I_PITEM (bh, ih);

	for (j = 0; j < I_UNFM_NUM (ih); j ++) {
	    unfm_ptr = d32_get (ind_item, j);

	    if (!unfm_ptr)
		continue;

	    /* this corruption of indirect item had to be fixed in pass0 */
	    if (not_data_block (fs, unfm_ptr) || unfm_ptr >= get_sb_block_count (fs->fs_ondisk_sb))
		/*!was_block_used (unfm_ptr))*/
		reiserfs_panic ("%s: block %lu, item %d, pointer %d: The wrong pointer (%u) in the file %K. "
		    "Must be fixed on pass0.",  __FUNCTION__, bh->b_blocknr, i, j, unfm_ptr, &ih->ih_key);

	    /* 1. zero slots pointing to a leaf */
	    if (is_used_leaf (unfm_ptr)) {
		dirty ++;
		d32_put (ind_item, j, 0);
		pass_1_stat (fs)->pointed_leaves ++;
		continue;
	    }

	    /* 2. zero pointers to blocks which are pointed already */
	    if (is_bad_unformatted (unfm_ptr)) {
		/* this unformatted pointed more than once. Did we see it already? */
		if (!is_bad_unfm_in_tree_once (unfm_ptr))
		    /* keep first reference to it and mark about that in
                       special bitmap */
		    mark_bad_unfm_in_tree_once (unfm_ptr);
		else {
		    /* Yes, we have seen this pointer already, zero other pointers to it. */
		    dirty ++;
		    d32_put (ind_item, j, 0);
		    pass_1_stat (fs)->non_unique_pointers ++;
		    continue;
		}
	    } else
		pass_1_stat (fs)->correct_pointers ++;
	}
    }

    if (dirty)
	mark_buffer_dirty (bh);
}

struct si * remove_saved_item (struct si * si)
{
    struct si * tmp = si->si_next;
    
    freemem (si->si_dnm_data);
    freemem (si);
    return tmp;
}

/* fsck starts creating of this bitmap on pass 1. It will then become
   on-disk bitmap */
static void init_new_bitmap (reiserfs_filsys_t * fs)
{
    unsigned int i;
    unsigned long block;
    unsigned long reserved;
    

    fsck_new_bitmap (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb));

    /* mark_block_used skips 0, set the bit explicitly */
    reiserfs_bitmap_set_bit (fsck_new_bitmap (fs), 0);

    /* mark other skipped blocks and super block used */
    for (i = 1; i <= fs->fs_super_bh->b_blocknr; i ++)
	mark_block_used (i, 1);

    /* mark bitmap blocks as used */
    block = fs->fs_super_bh->b_blocknr + 1;
    for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
	mark_block_used (block, 1);
	if (spread_bitmaps (fs))
	    block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8);
	else
	    block ++;
    }

    reserved = get_size_of_journal_or_reserved_area (fs->fs_ondisk_sb);
    /* where does journal area (or reserved journal area) start from */

    if (!is_new_sb_location (fs->fs_super_bh->b_blocknr, fs->fs_blocksize) &&
    	!is_old_sb_location (fs->fs_super_bh->b_blocknr, fs->fs_blocksize))
	die ("init_new_bitmap: Wrong super block location, you must run --rebuild-sb.");

    block = get_journal_start_must (fs);

    for (i = block; i < reserved + block; i ++)
	mark_block_used (i, 1);
	

    if (fs->fs_badblocks_bm)
    	for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) {
	    if (reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) {
	    	if (reiserfs_bitmap_test_bit (fsck_new_bitmap (fs), i))
	    	    reiserfs_panic ("%s: The block pointer to not data area, must be fixed on the pass0.\n",
	    	    	__FUNCTION__);	    	
		reiserfs_bitmap_set_bit (fsck_new_bitmap (fs), i);
	    }
    	}

#if 0
    /* mark journal area as used if journal is standard or it is non standard
       and initialy has been created on a main device */
    reserved = 0;
    if (!is_reiserfs_jr_magic_string (fs->fs_ondisk_sb))
	reserved = get_jp_journal_size (sb_jp (fs->fs_ondisk_sb));
    if (get_sb_reserved_for_journal (fs->fs_ondisk_sb))
	reserved = get_sb_reserved_for_journal (fs->fs_ondisk_sb);
    if (reserved) {
	for (i = 0; i <= reserved; i ++)
	    mark_block_used (i + get_jp_journal_1st_block (sb_jp
							   (fs->fs_ondisk_sb)));
    }
#endif
}


/* this makes a map of blocks which can be allocated when fsck will
   continue */
static void find_allocable_blocks (reiserfs_filsys_t * fs)
{
    unsigned long i;

    fsck_progress ("Looking for allocable blocks .. ");

    fsck_allocable_bitmap (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb));
    reiserfs_bitmap_fill (fsck_allocable_bitmap (fs));


    /* find how many leaves are not pointed by any indirect items */
    for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) {
	if (not_data_block (fs, i))
	    /* journal (or reserved for it area), bitmaps, super block and
	       blocks before it */
	    continue;

	if (is_good_unformatted (i) && is_bad_unformatted (i))
	    die ("find_allocable_blocks: The block (%lu) is masr as good and as bad at once.", i);

	if (is_good_unformatted (i) || is_bad_unformatted (i)) {
	    /* blocks which were pointed once or more thn onec from indirect
	       items - they will not be allocated */
	    continue;
	}

	/* make allocable not leaves, not bad blocks */
	if (!is_used_leaf (i) && (!fs->fs_badblocks_bm || 
				  !reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i))) 
	{
	    /* this is not leaf and it is not pointed by found indirect items,
               so it does not contains anything valuable */
	    make_allocable (i);
	    pass_1_stat (fs)->allocable_blocks ++;
	}
    }
    fsck_progress ("finished\n");

    fs->block_allocator = reiserfsck_reiserfs_new_blocknrs;
    fs->block_deallocator = reiserfsck_reiserfs_free_block;
}


static void before_pass_1 (reiserfs_filsys_t * fs)
{
    /* this will become an on-disk bitmap */
    init_new_bitmap (fs);

    /* bitmap of leaves which could not be inserted on pass 1. FIXME:
       no need to have 1 bit per block */
    fsck_uninsertables (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb));
    reiserfs_bitmap_fill (fsck_uninsertables (fs));
    
    /* find blocks which can be allocated */
    find_allocable_blocks (fs);

    /* bitmap of bad unformatted nodes which are in the tree already */
    bad_unfm_in_tree_once_bitmap = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb));

    /* pass 1 does not deal with objectid */
}


static void save_pass_1_result (reiserfs_filsys_t * fs)
{
    FILE * file;
    int retval;

    file = open_file("temp_fsck_file.deleteme", "w+");
    if (!file)
	return;

    /* to be able to get a new bitmap on pass2 we should flush it on disk
       new_bitmap should not be flushed on disk if run without -d option, as
       if fsck fails on pass1 we get wrong bitmap on the next fsck start */
    reiserfs_flush_to_ondisk_bitmap (fsck_new_bitmap (fs), fs);
    
    /* to be able to restart with pass 2 we need bitmap of
       uninsertable blocks and bitmap of alocable blocks */
    reiserfs_begin_stage_info_save(file, PASS_1_DONE);
    reiserfs_bitmap_save (file,  fsck_uninsertables (fs));
    reiserfs_bitmap_save (file,  fsck_allocable_bitmap(fs));
    reiserfs_end_stage_info_save (file);
    close_file (file);
    retval = rename ("temp_fsck_file.deleteme", state_dump_file (fs));
    if (retval != 0)
	fsck_progress ("pass 1: Could not rename the temporary file temp_fsck_file.deleteme to %s",
		       state_dump_file (fs));
}


void load_pass_1_result (FILE * fp, reiserfs_filsys_t * fs)
{
    fsck_new_bitmap (fs) = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb));
    reiserfs_bitmap_copy (fsck_new_bitmap (fs), fs->fs_bitmap2);
    
    fsck_uninsertables (fs) = reiserfs_bitmap_load (fp);
    fsck_allocable_bitmap (fs) = reiserfs_bitmap_load (fp);
    
    fs->block_allocator = reiserfsck_reiserfs_new_blocknrs;
    fs->block_deallocator = reiserfsck_reiserfs_free_block;

    if (!fsck_new_bitmap (fs) || !fsck_allocable_bitmap (fs) ||
	!fsck_allocable_bitmap (fs))
	fsck_exit ("State dump file seems corrupted. Run without -d");


    /* we need objectid map on pass 2 to be able to relocate files */
    proper_id_map (fs) = id_map_init();
    /* Not implemented yet.
    fetch_objectid_map (proper_id_map (fs), fs);
    */

    fsck_progress ("Pass 1 result loaded. %u blocks used, %u allocable, "
		   "still to be inserted %u\n",
		   reiserfs_bitmap_ones (fsck_new_bitmap (fs)),
		   reiserfs_bitmap_zeros (fsck_allocable_bitmap (fs)),
		   reiserfs_bitmap_zeros (fsck_uninsertables (fs)));
}


extern reiserfs_bitmap_t * leaves_bitmap;

/* reads blocks marked in leaves_bitmap and tries to insert them into
   tree */
static void do_pass_1 (reiserfs_filsys_t * fs)
{
    struct buffer_head * bh;
    unsigned long i; 
    int what_node;
    unsigned long done = 0, total;


    /* on pass0 we have found that amount of leaves */
    total = reiserfs_bitmap_ones (leaves_bitmap);

    /* read all leaves found on the pass 0 */
    for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) {
	if (!is_used_leaf (i))
	    continue;

	print_how_far (fsck_progress_file (fs), &done, total, 1, fsck_quiet (fs));

	/* at least one of nr_to_read blocks is to be checked */
	bh = bread (fs->fs_dev, i, fs->fs_blocksize);
	if (!bh) {
	    /* we were reading one block at time, and failed, so mark
	       block bad */
	    fsck_progress ("pass1: Reading of the block %lu failed\n", i);
	    continue;
	}

	what_node = who_is_this (bh->b_data, bh->b_size);
	if ( what_node != THE_LEAF ) {
	    check_memory_msg();
	    die ("build_the_tree: Nothing but leaves are expected. Block %lu - %s\n", 
		i, which_block(what_node));
	}
	
	if (is_block_used (i) && !(block_of_journal (fs, i) &&
				   fsck_data(fs)->rebuild.use_journal_area))
	    /* block is in new tree already */
	    die ("build_the_tree: The leaf (%lu) is in the tree already\n", i);
		    
	/* fprintf (block_list, "leaf %d\n", i + j);*/
	pass_1_stat (fs)->leaves ++;

	/* the leaf may still contain indirect items with wrong
	   slots. Fix that */
	pass1_correct_leaf (fs, bh);

	if (get_blkh_nr_items (B_BLK_HEAD (bh)) == 0) {
	    /* all items were deleted on pass 0 or pass 1 */
	    mark_buffer_clean (bh);
	    brelse (bh);
	    continue;
	}

	if (is_leaf_bad (bh)) {
	    /* FIXME: will die */
	    fsck_log ("is_leaf_bad: WARNING: The leaf (%lu) is formatted badly. Will be handled on the the pass2.\n", 
		bh->b_blocknr);
	    mark_block_uninsertable (bh->b_blocknr);
	    brelse (bh);
	    continue;
	}
	
	if (block_of_journal (fs, i) && fsck_data(fs)->rebuild.use_journal_area) {
	    /* FIXME: temporary thing */
	    if (tree_is_empty ()) {
		/* we insert inot tree only first leaf of journal */
		unsigned long block;
		struct buffer_head * new_bh;
		
		block = alloc_block ();
		if (!block)
		    die ("could not allocate block");
		new_bh = getblk (bh->b_dev, block, bh->b_size);
		memcpy (new_bh->b_data, bh->b_data, bh->b_size);
		mark_buffer_uptodate (new_bh, 1);
		mark_buffer_dirty (new_bh);
		make_single_leaf_tree (new_bh);
		brelse (new_bh);
		brelse (bh);
		continue;
	    }

	    /* other blocks of journal will be inserted in pass 2 */
	    mark_block_uninsertable (bh->b_blocknr);
	    brelse (bh);
	    continue;
	}
	
	try_to_insert_pointer_to_leaf (bh);
	brelse (bh);
    }

    fsck_progress ("\n");

}


static void after_pass_1 (reiserfs_filsys_t * fs)
{
    time_t t;

    /* update fsck_state */
    
    /* we  should not flush bitmaps on disk after pass1, because
       new_bitmap contains only those blocks which are good leaves or 
       just allocated internal blocks. */
       
    set_sb_fs_state (fs->fs_ondisk_sb, PASS_1_DONE);
    mark_buffer_dirty (fs->fs_super_bh);

    /* write all dirty blocks */
    fsck_progress ("Flushing..");
    fs->fs_dirt = 1;
    reiserfs_flush (fs);
    fsck_progress ("finished\n");

    stage_report (1, fs);

    /* we do not need this anymore */
    delete_aux_bitmaps ();
    reiserfs_delete_bitmap (bad_unfm_in_tree_once_bitmap);

    if (!fsck_run_one_step (fs)) {
	if (fsck_user_confirmed (fs, "Continue? (Yes):", "Yes\n", 1))
	    /* reiserfsck continues */
	    return;
    } else
	save_pass_1_result (fs);

    if (proper_id_map (fs)) {
	/* when we run pass 1 only - we do not have proper_id_map */
	id_map_free(proper_id_map (fs));
	proper_id_map (fs) = 0;
    }
    
    time (&t);
    fsck_progress ("###########\n"
		   "reiserfsck finished pass 1 at %s"
		   "###########\n", ctime (&t));
    fs->fs_dirt = 1;
    reiserfs_close (fs);
    exit(0);
}


void pass_1 (reiserfs_filsys_t * fs)
{
    fsck_progress ("\nPass 1 (will try to insert %lu leaves):\n",
		   reiserfs_bitmap_ones (fsck_source_bitmap (fs)));
    if (fsck_log_file (fs) != stderr)
	fsck_log ("####### Pass 1 #######\n");


    before_pass_1 (fs);

    /* try to insert leaves found during pass 0 */
    do_pass_1 (fs);

    after_pass_1 (fs);
}

