Beispiel #1
0
static int
is_leaf(char *buf, int blocksize, struct buf *bp)
{
	struct item_head *ih;
	struct block_head *blkh;
	int used_space, prev_location, i, nr;

	blkh = (struct block_head *)buf;
	if (blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
		reiserfs_log(LOG_WARNING, "this should be caught earlier");
		return (0);
	}

	nr = blkh_nr_item(blkh);
	if (nr < 1 || nr >
	    ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
		/* Item number is too big or too small */
		reiserfs_log(LOG_WARNING, "nr_item seems wrong\n");
		return (0);
	}

	ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
	used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location(ih));
	if (used_space != blocksize - blkh_free_space(blkh)) {
		/*
		 * Free space does not match to calculated amount of
		 * use space
		 */
		reiserfs_log(LOG_WARNING, "free space seems wrong\n");
		return (0);
	}

	/* FIXME: it is_leaf will hit performance too much - we may have
	 * return 1 here */

	/* Check tables of item heads */
	ih = (struct item_head *)(buf + BLKH_SIZE);
	prev_location = blocksize;
	for (i = 0; i < nr; i++, ih++) {
		if (le_ih_k_type(ih) == TYPE_ANY) {
			reiserfs_log(LOG_WARNING,
			    "wrong item type for item\n");
			return (0);
		}
		if (ih_location(ih) >= blocksize ||
		    ih_location(ih) < IH_SIZE * nr) {
			reiserfs_log(LOG_WARNING,
			    "item location seems wrong\n");
			return (0);
		}
		if (ih_item_len(ih) < 1 ||
		    ih_item_len(ih) > MAX_ITEM_LEN(blocksize)) {
			reiserfs_log(LOG_WARNING, "item length seems wrong\n");
			return (0);
		}
		if (prev_location - ih_location(ih) != ih_item_len(ih)) {
			reiserfs_log(LOG_WARNING,
			    "item location seems wrong (second one)\n");
			return (0);
		}
		prev_location = ih_location(ih);
	}

	/* One may imagine much more checks */
	return 1;
}
Beispiel #2
0
static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
{
	struct block_head *blkh;
	struct item_head *ih;
	int used_space;
	int prev_location;
	int i;
	int nr;

	blkh = (struct block_head *)buf;
	if (blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
		reiserfs_warning(NULL, "reiserfs-5080",
				 "this should be caught earlier");
		return 0;
	}

	nr = blkh_nr_item(blkh);
	if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
		/* item number is too big or too small */
		reiserfs_warning(NULL, "reiserfs-5081",
				 "nr_item seems wrong: %z", bh);
		return 0;
	}
	ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
	used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location(ih));
	if (used_space != blocksize - blkh_free_space(blkh)) {
		/* free space does not match to calculated amount of use space */
		reiserfs_warning(NULL, "reiserfs-5082",
				 "free space seems wrong: %z", bh);
		return 0;
	}
	// return 1 here

	/* check tables of item heads */
	ih = (struct item_head *)(buf + BLKH_SIZE);
	prev_location = blocksize;
	for (i = 0; i < nr; i++, ih++) {
		if (le_ih_k_type(ih) == TYPE_ANY) {
			reiserfs_warning(NULL, "reiserfs-5083",
					 "wrong item type for item %h",
					 ih);
			return 0;
		}
		if (ih_location(ih) >= blocksize
		    || ih_location(ih) < IH_SIZE * nr) {
			reiserfs_warning(NULL, "reiserfs-5084",
					 "item location seems wrong: %h",
					 ih);
			return 0;
		}
		if (ih_item_len(ih) < 1
		    || ih_item_len(ih) > MAX_ITEM_LEN(blocksize)) {
			reiserfs_warning(NULL, "reiserfs-5085",
					 "item length seems wrong: %h",
					 ih);
			return 0;
		}
		if (prev_location - ih_location(ih) != ih_item_len(ih)) {
			reiserfs_warning(NULL, "reiserfs-5086",
					 "item location seems wrong "
					 "(second one): %h", ih);
			return 0;
		}
		prev_location = ih_location(ih);
	}

	// one may imagine much more checks
	return 1;
}