예제 #1
0
static struct key * _get_rkey (struct path * path)
{
    int pos, offset = path->path_length;
    struct buffer_head * bh;

    if (offset < FIRST_PATH_ELEMENT_OFFSET)
	die ("_get_rkey: illegal offset in the path (%d)", offset);

    while (offset-- > FIRST_PATH_ELEMENT_OFFSET) {
	if (! buffer_uptodate (PATH_OFFSET_PBUFFER (path, offset)))
	    die ("_get_rkey: parent is not uptodate");

	/* Parent at the path is not in the tree now. */
	if (! B_IS_IN_TREE (bh = PATH_OFFSET_PBUFFER (path, offset)))
	    die ("_get_rkey: buffer on the path is not in tree");

	/* Check whether position in the parrent is correct. */
	if ((pos = PATH_OFFSET_POSITION (path, offset)) > B_NR_ITEMS (bh))
	    die ("_get_rkey: invalid position (%d) in the path", pos);

	/* Check whether parent at the path really points to the child. */
	if (B_N_CHILD_NUM (bh, pos) != PATH_OFFSET_PBUFFER (path, offset + 1)->b_blocknr)
	    die ("_get_rkey: invalid block number (%d). Must be %d",
		 B_N_CHILD_NUM (bh, pos), PATH_OFFSET_PBUFFER (path, offset + 1)->b_blocknr);
	
	/* Return delimiting key if position in the parent is not the last one. */
	if (pos != B_NR_ITEMS (bh))
	    return B_N_PDELIM_KEY (bh, pos);
    }
    
    /* there is no right delimiting key */
    return 0;
}
예제 #2
0
/* this can be invoked both to shift from S to L and from R to S */
static void internal_shift_left(int mode,	/* INTERNAL_FROM_S_TO_L | INTERNAL_FROM_R_TO_S */
				struct tree_balance *tb,
				int h, int pointer_amount)
{
	struct buffer_info dest_bi, src_bi;
	struct buffer_head *cf;
	int d_key_position;

	internal_define_dest_src_infos(mode, tb, h, &dest_bi, &src_bi,
				       &d_key_position, &cf);

	/*printk("pointer_amount = %d\n",pointer_amount); */

	if (pointer_amount) {
		/* insert delimiting key from common father of dest and src to node dest into position B_NR_ITEM(dest) */
		internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf,
				    d_key_position);

		if (B_NR_ITEMS(src_bi.bi_bh) == pointer_amount - 1) {
			if (src_bi.bi_position /*src->b_item_order */  == 0)
				replace_key(tb, cf, d_key_position,
					    src_bi.
					    bi_parent /*src->b_parent */ , 0);
		} else
			replace_key(tb, cf, d_key_position, src_bi.bi_bh,
				    pointer_amount - 1);
	}
	/* last parameter is del_parameter */
	internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST,
				     pointer_amount, 0);

}
예제 #3
0
파일: prints.c 프로젝트: 7799/linux
/* this prints internal nodes (4 keys/items in line) (dc_number,
   dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
   dc_size)...*/
static int print_internal(struct buffer_head *bh, int first, int last)
{
	struct reiserfs_key *key;
	struct disk_child *dc;
	int i;
	int from, to;

	if (!B_IS_KEYS_LEVEL(bh))
		return 1;

	check_internal(bh);

	if (first == -1) {
		from = 0;
		to = B_NR_ITEMS(bh);
	} else {
		from = first;
		to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
	}

	reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);

	dc = B_N_CHILD(bh, from);
	reiserfs_printk("PTR %d: %y ", from, dc);

	for (i = from, key = B_N_PDELIM_KEY(bh, from), dc++; i < to;
	     i++, key++, dc++) {
		reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
		if (i && i % 4 == 0)
			printk("\n");
	}
	printk("\n");
	return 0;
}
예제 #4
0
/* Replace delimiting key of buffers S[h] and R[h] by the given key.*/
static void replace_rkey(struct tree_balance *tb, int h, struct item_head *key)
{
	RFALSE(tb->R[h] == NULL || tb->CFR[h] == NULL,
	       "R[h](%p) and CFR[h](%p) must exist in replace_rkey",
	       tb->R[h], tb->CFR[h]);
	RFALSE(B_NR_ITEMS(tb->R[h]) == 0,
	       "R[h] can not be empty if it exists (item number=%d)",
	       B_NR_ITEMS(tb->R[h]));

	memcpy(B_N_PDELIM_KEY(tb->CFR[h], tb->rkey[h]), key, KEY_SIZE);

	do_balance_mark_internal_dirty(tb, tb->CFR[h], 0);
}
예제 #5
0
파일: ibalance.c 프로젝트: 020gzh/linux
/* Insert n_src'th key of buffer src before n_dest'th key of buffer dest. */
static void internal_insert_key(struct buffer_info *dest_bi,
				/* insert key before key with n_dest number */
				int dest_position_before,
				struct buffer_head *src, int src_position)
{
	struct buffer_head *dest = dest_bi->bi_bh;
	int nr;
	struct block_head *blkh;
	struct reiserfs_key *key;

	RFALSE(dest == NULL || src == NULL,
	       "source(%p) or dest(%p) buffer is 0", src, dest);
	RFALSE(dest_position_before < 0 || src_position < 0,
	       "source(%d) or dest(%d) key number less than 0",
	       src_position, dest_position_before);
	RFALSE(dest_position_before > B_NR_ITEMS(dest) ||
	       src_position >= B_NR_ITEMS(src),
	       "invalid position in dest (%d (key number %d)) or in src (%d (key number %d))",
	       dest_position_before, B_NR_ITEMS(dest),
	       src_position, B_NR_ITEMS(src));
	RFALSE(B_FREE_SPACE(dest) < KEY_SIZE,
	       "no enough free space (%d) in dest buffer", B_FREE_SPACE(dest));

	blkh = B_BLK_HEAD(dest);
	nr = blkh_nr_item(blkh);

	/* prepare space for inserting key */
	key = internal_key(dest, dest_position_before);
	memmove(key + 1, key,
		(nr - dest_position_before) * KEY_SIZE + (nr + 1) * DC_SIZE);

	/* insert key */
	memcpy(key, internal_key(src, src_position), KEY_SIZE);

	/* Change dirt, free space, item number fields. */

	set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
	set_blkh_free_space(blkh, blkh_free_space(blkh) - KEY_SIZE);

	do_balance_mark_internal_dirty(dest_bi->tb, dest, 0);

	if (dest_bi->bi_parent) {
		struct disk_child *t_dc;
		t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
		put_dc_size(t_dc, dc_size(t_dc) + KEY_SIZE);

		do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
					       0);
	}
}
예제 #6
0
void print_path (struct tree_balance * tb, struct path * path)
{
    int h = 0;
    struct buffer_head * bh;
    
    if (tb) {
	while (tb->insert_size[h]) {
	    bh = PATH_H_PBUFFER (path, h);
	    printk ("block %lu (level=%d), position %d\n", bh ? bh->b_blocknr : 0,
		    bh ? B_LEVEL (bh) : 0, PATH_H_POSITION (path, h));
	    h ++;
	}
  } else {
      int offset = path->path_length;
      struct buffer_head * bh;
      printk ("Offset    Bh     (b_blocknr, b_count) Position Nr_item\n");
      while ( offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
	  bh = PATH_OFFSET_PBUFFER (path, offset);
	  printk ("%6d %10p (%9lu, %7d) %8d %7d\n", offset, 
		  bh, bh ? bh->b_blocknr : 0, bh ? atomic_read (&(bh->b_count)) : 0,
		  PATH_OFFSET_POSITION (path, offset), bh ? B_NR_ITEMS (bh) : -1);
	  
	  offset --;
      }
  }

}
예제 #7
0
int is_leaf_bad (struct buffer_head * bh)
{
    int i;
    struct item_head * ih;
    int bad = 0;

    assert (is_leaf_node (bh));

    for (i = 0, ih = B_N_PITEM_HEAD (bh,  0); i < B_NR_ITEMS (bh); i ++, ih ++) {
	if (is_bad_item (bh, ih, B_I_PITEM (bh, ih))) {
	    fsck_log ("is_leaf_bad: block %lu: %d-th item (%H) is bad\n",
		      bh->b_blocknr, i, ih);
	    bad = 1;
	    continue;
	}

	if (i && bad_pair (fs, bh, i)) {
	    fsck_log ("is_leaf_bad: block %luL %d-th item (%H) and "
		      "the next one (%H) are in wrong order\n",
		     bh->b_blocknr, i - 1, ih - 1, ih);
	    bad = 1;
	}
    }

    return bad;
}
예제 #8
0
static void compare_neighboring_leaves_after_all (void)
{
    struct item_head * left = B_N_PITEM_HEAD(g_left, B_NR_ITEMS (g_left) - 1);
    struct item_head * right = B_N_PITEM_HEAD(g_right, 0);
    /*  struct key * left = B_N_PKEY (g_left, B_NR_ITEMS (g_left) - 1);
	struct key * right = B_N_PKEY (g_right, 0);*/
    
    /*
      if (comp_keys (&left->ih_key, B_PRIGHT_DELIM_KEY (g_left)) != SECOND_GREATER)
      die ("compare_neighboring_leaves_after_all: invalid right delimiting key");
    */
    if (comp_keys (&left->ih_key, B_N_PKEY (g_right, 0)) != -1/*SECOND_GREATER*/)
	die ("compare_neighboring_leaves_after_all: left key is greater than the right one");
    
    if (//comp_le_keys (B_PRIGHT_DELIM_KEY (g_left), g_dkey) != KEYS_IDENTICAL ||
	comp_keys (g_dkey, B_N_PKEY (g_right, 0))) {
	reiserfs_panic (0, "compare_neighboring_leaves_after all: invalid delimiting keys from left to right (%k %k)",
			g_dkey, B_N_PKEY (g_right, 0));
    }
    
    if (!not_of_one_file (&left->ih_key, &right->ih_key)) {
	// items of one file: check offset correctness
	if (is_direct_ih (left) || is_indirect_ih (left))
	    //if (get_offset(&right->ih_key) != get_offset(&left->ih_key) + get_bytes_number (g_left, left /*B_NR_ITEMS (g_left) - 1*/, 0, CHECK_FREE_BYTES))
	    if (get_offset(&right->ih_key) != get_offset(&left->ih_key) + get_bytes_number (left, g_left->b_size))
		die ("compare_neighboring_leaves_after all: hole between items or items are overlapped");
    }
    is_there_unaccessed_items (g_left);
    
}
예제 #9
0
static void check_internal_block_head (struct buffer_head * bh)
{
    struct block_head * blkh;
    
    blkh = B_BLK_HEAD (bh);
    if (!(B_LEVEL (bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL (bh) <= MAX_HEIGHT))
	reiserfs_panic (0, "vs-6025: check_internal_block_head: invalid level %z", bh);

    if (B_NR_ITEMS (bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
	reiserfs_panic (0, "vs-6030: check_internal_block_head: invalid item number %z", bh);

    if (B_FREE_SPACE (bh) != 
	bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS (bh) - DC_SIZE * (B_NR_ITEMS (bh) + 1))
	reiserfs_panic (0, "vs-6040: check_internal_block_head: invalid free space %z", bh);

}
예제 #10
0
static void compare_neighboring_leaves_in_pass1 (void)
{
    struct key * left = B_N_PKEY (g_left, B_NR_ITEMS (g_left) - 1);

    if (comp_keys (left, B_N_PKEY (g_right, 0)) != -1/*SECOND_GREATER*/)
	die ("compare_neighboring_leaves_in_pass1: left key is greater, that the right one");
    
    if (/*comp_keys (B_PRIGHT_DELIM_KEY (g_left), g_dkey) == FIRST_GREATER ||*/
	comp_keys (g_dkey, B_N_PKEY (g_right, 0))) {
	reiserfs_panic (0, "compare_neighboring_leaves_in_pass1: dkey %k, first key in right %k",
			g_dkey, B_N_PKEY (g_right, 0));
    }
    
    check_items (g_left);
    
    /*&&&&&&&&&&&&&&&&&&&&&&&&&&
      for (i = 0, ih = B_N_PITEM_HEAD (g_left, i); i < B_NR_ITEMS (g_left); i ++, ih ++)
      if (is_item_accessed (ih) == YES)
      die ("compare_neighboring_leaves_in_pass1: item marked as accessed in g_left");
      for (i = 0, ih = B_N_PITEM_HEAD (g_right, i); i < B_NR_ITEMS (g_right); i ++, ih ++)
      if (is_item_accessed (ih) == YES)
      die ("compare_neighboring_leaves_in_pass1: item marked as accessed in g_right");
      &&&&&&&&&&&&&&&&&&&&&&&&&&&*/
    
}
예제 #11
0
int is_internal_bad (struct buffer_head * bh)
{
    struct key * key;

    int i;
  
    if (!is_internal_node(bh))
	return 0;
    for (i = 0; i < B_NR_ITEMS (bh); i ++) {
	key = B_N_PDELIM_KEY (bh, i);
	if (//key->k_dir_id >= key->k_objectid ||
	    le32_to_cpu(key->u.k_offset_v1.k_uniqueness) != V1_DIRENTRY_UNIQUENESS &&
            le32_to_cpu(key->u.k_offset_v1.k_uniqueness) != V1_DIRECT_UNIQUENESS &&
	    le32_to_cpu(key->u.k_offset_v1.k_uniqueness) != V1_INDIRECT_UNIQUENESS &&
            le32_to_cpu(key->u.k_offset_v1.k_uniqueness) != V1_SD_UNIQUENESS &&
	    offset_v2_k_type( &(key->u.k_offset_v2) ) != TYPE_DIRENTRY &&
            offset_v2_k_type( &(key->u.k_offset_v2) ) != TYPE_DIRECT &&
	    offset_v2_k_type( &(key->u.k_offset_v2) ) != TYPE_INDIRECT &&
            offset_v2_k_type( &(key->u.k_offset_v2) ) != TYPE_STAT_DATA //&&
	    //	key->u.k_offset_v1.k_uniqueness != V1_ANY_UNIQUENESS && key->u.k_offset_v2.k_type != TYPE_ANY	
	    )
	    return 1;
    }
    return 0;
}
예제 #12
0
/* Copy cpy_num node pointers and cpy_num - 1 items from buffer src to buffer dest.
 * Delete cpy_num - del_par items and node pointers from buffer src.
 * last_first == FIRST_TO_LAST means, that we copy/delete first items from src.
 * last_first == LAST_TO_FIRST means, that we copy/delete last items from src.
 */
static void internal_move_pointers_items(struct buffer_info *dest_bi,
					 struct buffer_info *src_bi,
					 int last_first, int cpy_num,
					 int del_par)
{
	int first_pointer;
	int first_item;

	internal_copy_pointers_items(dest_bi, src_bi->bi_bh, last_first,
				     cpy_num);

	if (last_first == FIRST_TO_LAST) {	/* shift_left occurs */
		first_pointer = 0;
		first_item = 0;
		/* delete cpy_num - del_par pointers and keys starting for pointers with first_pointer,
		   for key - with first_item */
		internal_delete_pointers_items(src_bi, first_pointer,
					       first_item, cpy_num - del_par);
	} else {		/* shift_right occurs */
		int i, j;

		i = (cpy_num - del_par ==
		     (j =
		      B_NR_ITEMS(src_bi->bi_bh)) + 1) ? 0 : j - cpy_num +
		    del_par;

		internal_delete_pointers_items(src_bi,
					       j + 1 - cpy_num + del_par, i,
					       cpy_num - del_par);
	}
}
예제 #13
0
/* Insert d_key'th (delimiting) key from buffer cfr to head of dest.
 * Copy n node pointers and n - 1 items from buffer src to buffer dest.
 * Replace  d_key'th key in buffer cfr.
 * Delete n items and node pointers from buffer src.
 */
static void internal_shift_right(int mode,	/* INTERNAL_FROM_S_TO_R | INTERNAL_FROM_L_TO_S */
				 struct tree_balance *tb,
				 int h, int pointer_amount)
{
	struct buffer_info dest_bi, src_bi;
	struct buffer_head *cf;
	int d_key_position;
	int nr;

	internal_define_dest_src_infos(mode, tb, h, &dest_bi, &src_bi,
				       &d_key_position, &cf);

	nr = B_NR_ITEMS(src_bi.bi_bh);

	if (pointer_amount > 0) {
		/* insert delimiting key from common father of dest and src to dest node into position 0 */
		internal_insert_key(&dest_bi, 0, cf, d_key_position);
		if (nr == pointer_amount - 1) {
			RFALSE(src_bi.bi_bh != PATH_H_PBUFFER(tb->tb_path, h) /*tb->S[h] */ ||
			       dest_bi.bi_bh != tb->R[h],
			       "src (%p) must be == tb->S[h](%p) when it disappears",
			       src_bi.bi_bh, PATH_H_PBUFFER(tb->tb_path, h));
			/* when S[h] disappers replace left delemiting key as well */
			if (tb->CFL[h])
				replace_key(tb, cf, d_key_position, tb->CFL[h],
					    tb->lkey[h]);
		} else
			replace_key(tb, cf, d_key_position, src_bi.bi_bh,
				    nr - pointer_amount);
	}

	/* last parameter is del_parameter */
	internal_move_pointers_items(&dest_bi, &src_bi, LAST_TO_FIRST,
				     pointer_amount, 0);
}
예제 #14
0
static void
sprintf_block_head(char *buf, struct buf *bp)
{

	sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
	    B_LEVEL(bp), B_NR_ITEMS(bp), B_FREE_SPACE(bp));
}
예제 #15
0
void print_disk_tree (int block_nr)
{
    struct buffer_head * bh;

    bh = bread (g_sb.s_dev, block_nr, g_sb.s_blocksize);
    if (B_IS_KEYS_LEVEL (bh)) {
	int i;
	struct disk_child * dc;

	g_stat_info.nr_internals ++;
	print_block (bh, print_mode (), -1, -1);
      
	dc = B_N_CHILD (bh, 0);
	for (i = 0; i <= B_NR_ITEMS (bh); i ++, dc ++)
	    print_disk_tree (dc->dc_block_number);

    } else if (B_IS_ITEMS_LEVEL (bh)) {
	g_stat_info.nr_leaves ++;
	print_block (bh, print_mode (), -1, -1);
    } else {
	print_block (bh, print_mode (), -1, -1);
	die ("print_disk_tree: bad block type");
    }
    brelse (bh);
}
예제 #16
0
static int _search_by_key (reiserfs_filsys_t fs, struct key * key, struct path * path)
{
    struct buffer_head * bh;
    unsigned long block = SB_ROOT_BLOCK (fs);
    struct path_element * curr;
    int retval;
    
    path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
    while (1) {
	curr = PATH_OFFSET_PELEMENT (path, ++ path->path_length);
	bh = curr->pe_buffer = bread (fs->s_dev, block, fs->s_blocksize);
        if (bh == 0) {
	    path->path_length --;
	    pathrelse (path);
	    return ITEM_NOT_FOUND;
	}
	retval = _bin_search (key, B_N_PKEY (bh, 0), B_NR_ITEMS (bh),
			      is_leaf_node (bh) ? IH_SIZE : KEY_SIZE, &(curr->pe_position), comp_keys);
	if (retval == ITEM_FOUND) {
	    /* key found, return if this is leaf level */
	    if (is_leaf_node (bh)) {
		path->pos_in_item = 0;
		return ITEM_FOUND;
	    }
	    curr->pe_position ++;
	} else {
	    /* key not found in the node */
	    if (is_leaf_node (bh))
		return ITEM_NOT_FOUND;
	}
	block = B_N_CHILD_NUM (bh, curr->pe_position);
    }
    printf ("search_by_key: you can not get here\n");
    return ITEM_NOT_FOUND;
}
예제 #17
0
/* Get delimiting key of the buffer at the path and its right neighbor. */
const struct key *
get_rkey(const struct path *p_s_chk_path,
    const struct reiserfs_sb_info *p_s_sbi)
{
	struct buf *p_s_parent;
	int n_position, n_path_offset = p_s_chk_path->path_length;

	while (n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET) {
		/* Parent at the path is not in the tree now. */
		if (!B_IS_IN_TREE(p_s_parent =
		    PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)))
			return (&MIN_KEY);

		/* Check whether position in the parent is correct. */
		if ((n_position = PATH_OFFSET_POSITION(p_s_chk_path,
		    n_path_offset)) >
		    B_NR_ITEMS(p_s_parent))
			return (&MIN_KEY);

		/*
		 * Check whether parent at the path really points to the
		 * child.
		 */
		if (B_N_CHILD_NUM(p_s_parent, n_position) !=
		    (PATH_OFFSET_PBUFFER(p_s_chk_path,
					 n_path_offset + 1)->b_blkno
		     / btodb(p_s_sbi->s_blocksize)))
			return (&MIN_KEY);

		/*
		 * Return delimiting key if position in the parent is not
		 * the last one.
		 */
		if (n_position != B_NR_ITEMS(p_s_parent))
			return (B_N_PDELIM_KEY(p_s_parent, n_position));
	}

	/* Return MAX_KEY if we are in the root of the buffer tree. */
	if ((PATH_OFFSET_PBUFFER(p_s_chk_path,
	    FIRST_PATH_ELEMENT_OFFSET)->b_blkno
	    / btodb(p_s_sbi->s_blocksize)) == SB_ROOT_BLOCK(p_s_sbi))
		return (&MAX_KEY);

	return (&MIN_KEY);
}
예제 #18
0
파일: prints.c 프로젝트: 7799/linux
void check_leaf(struct buffer_head *bh)
{
	int i;
	struct item_head *ih;

	if (!bh)
		return;
	check_leaf_block_head(bh);
	for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
		op_check_item(ih, B_I_PITEM(bh, ih));
}
예제 #19
0
/* Get delimiting key of the buffer at the path and its right neighbor. */
inline const struct reiserfs_key *get_rkey(const struct treepath *chk_path,
					   const struct super_block *sb)
{
	int position, path_offset = chk_path->path_length;
	struct buffer_head *parent;

	RFALSE(path_offset < FIRST_PATH_ELEMENT_OFFSET,
	       "PAP-5030: invalid offset in the path");

	while (path_offset-- > FIRST_PATH_ELEMENT_OFFSET) {

		RFALSE(!buffer_uptodate
		       (PATH_OFFSET_PBUFFER(chk_path, path_offset)),
		       "PAP-5040: parent is not uptodate");

		/* Parent at the path is not in the tree now. */
		if (!B_IS_IN_TREE
		    (parent =
		     PATH_OFFSET_PBUFFER(chk_path, path_offset)))
			return &MIN_KEY;
		/* Check whether position in the parent is correct. */
		if ((position =
		     PATH_OFFSET_POSITION(chk_path,
					  path_offset)) >
		    B_NR_ITEMS(parent))
			return &MIN_KEY;
		/* Check whether parent at the path really points to the child. */
		if (B_N_CHILD_NUM(parent, position) !=
		    PATH_OFFSET_PBUFFER(chk_path,
					path_offset + 1)->b_blocknr)
			return &MIN_KEY;
		/* Return delimiting key if position in the parent is not the last one. */
		if (position != B_NR_ITEMS(parent))
			return B_N_PDELIM_KEY(parent, position);
	}
	/* Return MAX_KEY if we are in the root of the buffer tree. */
	if (PATH_OFFSET_PBUFFER(chk_path, FIRST_PATH_ELEMENT_OFFSET)->
	    b_blocknr == SB_ROOT_BLOCK(sb))
		return &MAX_KEY;
	return &MIN_KEY;
}
예제 #20
0
/* Get delimiting key of the buffer at the path and its right neighbor. */
inline	struct  key * get_rkey  (
    struct path         * p_s_chk_path,
    struct super_block  * p_s_sb
    ) {
    int                   n_position,
	n_path_offset = p_s_chk_path->path_length;
    struct buffer_head  * p_s_parent;

#ifdef CONFIG_REISERFS_CHECK
    if ( n_path_offset < FIRST_PATH_ELEMENT_OFFSET )
	reiserfs_panic(p_s_sb,"PAP-5030: get_rkey: illegal offset in the path");
#endif

    while ( n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET ) {

#ifdef CONFIG_REISERFS_CHECK
	if ( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
	    reiserfs_panic(p_s_sb, "PAP-5040: get_rkey: parent is not uptodate");
#endif

	/* Parent at the path is not in the tree now. */
	if ( ! B_IS_IN_TREE(p_s_parent = PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
	    return &MIN_KEY;
	/* Check whether position in the parrent is correct. */
	if ( (n_position = PATH_OFFSET_POSITION(p_s_chk_path, n_path_offset)) > B_NR_ITEMS(p_s_parent) )
	    return &MIN_KEY;
	/* Check whether parent at the path really points to the child. */
	if ( B_N_CHILD_NUM(p_s_parent, n_position) !=
	     PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset + 1)->b_blocknr )
	    return &MIN_KEY;
	/* Return delimiting key if position in the parent is not the last one. */
	if ( n_position != B_NR_ITEMS(p_s_parent) )
	    return B_N_PDELIM_KEY(p_s_parent, n_position);
    }
    /* Return MAX_KEY if we are in the root of the buffer tree. */
    if ( PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
	 SB_ROOT_BLOCK (p_s_sb) )
	return &MAX_KEY;
    return  &MIN_KEY;
}
예제 #21
0
/* only directory item can be fatally bad */
static int is_leaf_bad_xx (struct buffer_head * bh)
{
    int i;
    struct item_head * ih;

    if (!is_leaf_node (bh))
	return 0;
    for (i = 0, ih = B_N_PITEM_HEAD (bh,  0); i < B_NR_ITEMS (bh); i ++, ih ++)
	if (is_bad_item (bh, ih, B_I_PITEM (bh, ih))) {
	    return 1;
	}
    return 0;
}
예제 #22
0
/* Replace delimiting key of buffers L[h] and S[h] by the given key.*/
static void replace_lkey(struct tree_balance *tb, int h, struct item_head *key)
{
	RFALSE(tb->L[h] == NULL || tb->CFL[h] == NULL,
	       "L[h](%p) and CFL[h](%p) must exist in replace_lkey",
	       tb->L[h], tb->CFL[h]);

	if (B_NR_ITEMS(PATH_H_PBUFFER(tb->tb_path, h)) == 0)
		return;

	memcpy(B_N_PDELIM_KEY(tb->CFL[h], tb->lkey[h]), key, KEY_SIZE);

	do_balance_mark_internal_dirty(tb, tb->CFL[h], 0);
}
예제 #23
0
/* 'upper' item is correct if 'upper + 2' exists and its key is greater than
   key of 'upper' */
static int upper_correct (struct buffer_head * bh, struct item_head * upper,
			  int upper_item_num)
{
    if (upper_item_num + 2 < B_NR_ITEMS (bh)) {
	if (comp_keys (&upper->ih_key, &(upper + 2)->ih_key) != -1)
	    /* item-num's item is out of order of order */
	    return 0;
	return 1;
    }
    
    /* there is no item above the "bad pair" */
    return 2;
}
예제 #24
0
/* %z */
static int print_block_head (FILE * stream,
			     const struct printf_info *info,
			     const void *const *args)
{
    const struct buffer_head * bh;
    char * buffer;
    int len;

    bh = *((const struct buffer_head **)(args[0]));
    len = asprintf (&buffer, "level=%d, nr_items=%d, free_space=%d rdkey",
		    B_LEVEL (bh), B_NR_ITEMS (bh), node_free_space (bh));
    FPRINTF;
}
예제 #25
0
static void reiserfsck_check_tree (int dev, int block, int size, check_function_t comp_func)
{
    struct buffer_head * bh;
    int what_node;
    
    bh = bread (dev, block, size);
    if (bh == 0)
        reiserfs_panic("reiserfsck_check_tree: unable to read %lu block on device 0x%x\n",
                block, dev);

    if (!B_IS_IN_TREE (bh)) {
	reiserfs_panic (0, "reiserfsck_check_tree: buffer (%b %z) not in tree", bh, bh);
    }
    
    what_node = who_is_this (bh->b_data, bh->b_size);
    if (what_node != THE_LEAF && what_node != THE_INTERNAL)
	die ("Not formatted node");

    if (!is_block_used (bh->b_blocknr))
	die ("Not marked as used");

    if (is_leaf_node (bh) && is_leaf_bad_xx (bh))
	die ("Bad leaf");

    if (is_internal_node(bh) && is_internal_bad (bh))
	die ("bad internal");
    
    if (is_internal_node (bh)) {
	int i;
	struct disk_child * dc;
	
	dc = B_N_CHILD (bh, 0);
	for (i = 0; i <= B_NR_ITEMS (bh); i ++, dc ++) {
	    reiserfsck_check_tree (dev, dc_block_number(dc), size, comp_func);
	    g_dkey = B_N_PDELIM_KEY (bh, i);
	}
    } else if (is_leaf_node (bh)) {
	g_right = bh;
	if (g_left != 0 && g_dkey != 0) {
	    comp_func ();
	    brelse (g_left);
	}
	g_left = g_right;
	return;
    } else {
	reiserfs_panic ("reiserfsck_check_tree: block %lu has bad block type (%b)",
			bh->b_blocknr, bh);
    }
    brelse (bh);
}
예제 #26
0
static void check_items (struct buffer_head * bh)
{
    int i;
    struct item_head * ih;

    for (i = 0; i < B_NR_ITEMS (bh); i++)
    {
	ih = B_N_PITEM_HEAD (bh, i);
	
	if (is_direntry_ih (ih))
	    check_directory_item (ih, bh);
	
    }
}
예제 #27
0
void print_path (struct tree_balance * tb, struct path * path)
{
    int offset = path->path_length;
    struct buffer_head * bh;

    printf ("Offset    Bh     (b_blocknr, b_count) Position Nr_item\n");
    while ( offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
	bh = PATH_OFFSET_PBUFFER (path, offset);
	printf ("%6d %10p (%9lu, %7d) %8d %7d\n", offset, 
		bh, bh ? bh->b_blocknr : 0, bh ? bh->b_count : 0,
		PATH_OFFSET_POSITION (path, offset), bh ? B_NR_ITEMS (bh) : -1);
	
	offset --;
    }
}
예제 #28
0
static void is_there_unaccessed_items (struct buffer_head * bh)
{
    int i;
    struct item_head * ih;
    
    ih = B_N_PITEM_HEAD (bh, 0);
    for (i = 0; i < B_NR_ITEMS (bh); i ++, ih ++) {
	if (is_objectid_used (fs, ih->ih_key.k_objectid) == 0)
	    die ("is_there_unaccessed_items: %lu is not marked as used", ih->ih_key.k_objectid);
	
	if (!is_item_reachable (ih)) {
	    die ("is_there_unaccessed_items: block %lu - unaccessed item found",
		 bh->b_blocknr);
	}
    }
}
예제 #29
0
파일: ibalance.c 프로젝트: 020gzh/linux
/* it always shifts from S[h] to L[h] */
static void internal_shift1_left(struct tree_balance *tb,
				 int h, int pointer_amount)
{
	struct buffer_info dest_bi, src_bi;
	struct buffer_head *cf;
	int d_key_position;

	internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
				       &dest_bi, &src_bi, &d_key_position, &cf);

	/* insert lkey[h]-th key  from CFL[h] to left neighbor L[h] */
	if (pointer_amount > 0)
		internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf,
				    d_key_position);

	/* last parameter is del_parameter */
	internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST,
				     pointer_amount, 1);
}
예제 #30
0
static void reiserfsck_check_cached_tree (int dev, int block, int size)
{
    struct buffer_head * bh;
    int what_node;

    bh =  find_buffer(dev, block, size);
    if (bh == 0)
	return;
    if (!buffer_uptodate (bh)) {
	die ("reiserfsck_check_cached_tree: found notuptodate buffer");
    }

    bh->b_count ++;
    
    if (!B_IS_IN_TREE (bh)) {
	die ("reiserfsck_check_cached_tree: buffer (%b %z) not in tree", bh, bh);
    }

    what_node = who_is_this (bh->b_data, bh->b_size);
    if ((what_node != THE_LEAF && what_node != THE_INTERNAL) ||
	!is_block_used (bh->b_blocknr) ||
	(is_leaf_node (bh) && is_leaf_bad (bh)) ||
	(is_internal_node(bh) && is_internal_bad (bh)))
	die ("reiserfsck_check_cached_tree: bad node in the tree");
    if (is_internal_node (bh)) {
	int i;
	struct disk_child * dc;
	
	dc = B_N_CHILD (bh, 0);
	for (i = 0; i <= B_NR_ITEMS (bh); i ++, dc ++) {
	    reiserfsck_check_cached_tree (dev, dc_block_number(dc), size);
	    g_dkey = B_N_PDELIM_KEY (bh, i);
	}
    } else if (is_leaf_node (bh)) {
	brelse (bh);
	return;
    } else {
	reiserfs_panic ("reiserfsck_check_cached_tree: block %lu has bad block type (%b)",
			bh->b_blocknr, bh);
    }
    brelse (bh);
}