⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 node40_repair.c

📁 reiser4progs ReiserFS V4 ReiserFs官方已经关闭 这个是1.0.6 2006-02-22发布的 给需要的朋友
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2001-2005 by Hans Reiser, licensing governed by   reiser4progs/COPYING.      node40_repair.c -- reiser4 node with short keys. */#ifndef ENABLE_MINIMAL#include "node40.h"#include <repair/plugin.h>#define MIN_ITEM_LEN	1static void node40_set_offset_at(reiser4_node_t *node, int pos,				 uint16_t offset){	if (pos > nh_get_num_items(node))		return;    	if (nh_get_num_items(node) == pos) {		nh_set_free_space_start(node, offset);	} else {		ih_set_offset(node40_ih_at(node, pos),			      offset, node->keypol);	}}static errno_t node40_region_delete(reiser4_node_t *node,				    uint16_t start_pos, 				    uint16_t end_pos) {	uint32_t count;	uint32_t len;	pos_t pos;	uint16_t i;	void *ih;     	aal_assert("vpf-201", node != NULL);	aal_assert("vpf-202", node->block != NULL);	aal_assert("vpf-213", start_pos <= end_pos);	aal_assert("vpf-214", end_pos <= nh_get_num_items(node));    	ih = node40_ih_at(node, start_pos);	for (i = start_pos; i < end_pos; i++) {		ih_set_offset(ih, ih_get_offset(ih + ih_size(node->keypol),						node->keypol) + 1, 			      node->keypol);				ih -= ih_size(node->keypol);	}    	pos.unit = MAX_UINT32;	pos.item = start_pos - 1;	count = end_pos - pos.item;	len = node40_size(node, &pos, count);	return node40_shrink((reiser4_node_t *)node, &pos, len, count);}/* Count is valid if:   free_space_start + free_space == block_size - count * ih size */static int node40_count_valid(reiser4_node_t *node) {	uint32_t count;		count = nh_get_num_items(node);		if (count > node->block->size / ih_size(node->keypol))		return 0;		if (nh_get_free_space_start(node) > node->block->size)		return 0;		if (nh_get_free_space(node) > node->block->size)		return 0;	return (nh_get_free_space_start(node) + nh_get_free_space(node) + 		count * ih_size(node->keypol) == node->block->size);}/* Look through ih array looking for the last valid item location. This will    be the last valid item. */static uint32_t node40_estimate_count(reiser4_node_t *node) {	uint32_t offset, left, right;	uint32_t count, last, i;		count = nh_get_num_items(node);		left = sizeof(node40_header_t);	right = node->block->size - ih_size(node->keypol) - MIN_ITEM_LEN;	last = 0;	for (i = 0 ; ; i++, left += MIN_ITEM_LEN, 	     right -= ih_size(node->keypol)) 	{		if (left > right)			break;				offset = ih_get_offset(node40_ih_at(node, i), node->keypol);				if (offset >= left && offset <= right) {			last = i;			left = offset;		}	}	return last + 1;}static errno_t node40_space_check(reiser4_node_t *node, 				  uint32_t offset, uint8_t mode){	errno_t res = 0;	uint32_t space;	space = nh_get_free_space_start(node);		/* Last relable position is not free space spart. Correct it. */	if (offset != space) {		/* There is left region with broken offsets, remove it. */		fsck_mess("Node (%llu): Free space start (%u) is wrong. "			  "Should be (%u). %s", node->block->nr, space, 			  offset, mode == RM_BUILD ? "Fixed." : "");				if (mode == RM_BUILD) {			nh_set_free_space(node, nh_get_free_space(node) +					  space - offset);						nh_set_free_space_start(node, offset);			node40_mkdirty(node);		} else {			res |= RE_FATAL;		}	}		space = node->block->size - nh_get_free_space_start(node) - 		ih_size(node->keypol) * nh_get_num_items(node);		if (space != nh_get_free_space(node)) {		/* Free space is wrong. */		fsck_mess("Node (%llu): the free space (%u) is wrong. "			  "Should be (%u). %s", node->block->nr, 			  nh_get_free_space(node), space, 			  mode == RM_CHECK ? "" : "Fixed.");				if (mode == RM_CHECK) {			res |= RE_FIXABLE;		} else {			nh_set_free_space(node, space);			node40_mkdirty(node);		}	}	return res;}/* Count of items is correct. Free space fields and item locations should be  * checked/recovered if broken. */static errno_t node40_ih_array_check(reiser4_node_t *node, uint8_t mode) {	uint32_t right, left, offset;	uint32_t last_pos, count, i;	errno_t res = 0;	bool_t relable;	blk_t blk;		aal_assert("vpf-208", node != NULL);	aal_assert("vpf-209", node->block != NULL);	blk = node->block->nr;		offset = 0;	last_pos = 0;	count = nh_get_num_items(node);		left = sizeof(node40_header_t);	right = node->block->size - count * ih_size(node->keypol);		for(i = 0; i <= count; i++, left += MIN_ITEM_LEN) {		offset = (i == count) ? nh_get_free_space_start(node) : 			ih_get_offset(node40_ih_at(node, i), node->keypol);				if (i == 0) {			if (offset == left)				continue;						fsck_mess("Node (%llu), item (0): Offset (%u) is "				  "wrong. Should be (%u). %s", blk, offset, 				  left, mode == RM_BUILD ? "Fixed." : "");			if (mode != RM_BUILD) {				res |= RE_FATAL;				continue;			}						ih_set_offset(node40_ih_at(node, 0), 				      left, node->keypol);			node40_mkdirty(node);			continue;		}				relable = offset >= left && 			offset + (count - i) * MIN_ITEM_LEN <= right;				if (!relable) {			/* fsck_mess("Node (%llu), item (%u): Offset (%u) "				  "is wrong.", blk, i, offset); */						res |= (mode == RM_BUILD ? 0 : RE_FATAL);						if (count != i)				continue;		}		/* i-th offset is ok or i == count. Removed broken items. */		if ((last_pos != i - 1) || !relable) {			uint32_t delta;			fsck_mess("Node (%llu): Region of items [%d-%d] with "				  "wrong offsets %s removed.", blk, last_pos, 				  i - 1, mode == RM_BUILD ? "is" : "should be");			if (mode == RM_BUILD) {				delta = i - last_pos;				count -= delta;				right += delta * ih_size(node->keypol);				if (node40_region_delete(node, last_pos + 1, i))					return -EINVAL;				i = last_pos;			}						/* DO not correct the left limit in the CHECK mode,leave			   it the same last_relable_offset + n * MIN_ITEM_SIZE. 			   However, correct it for the i == count to check free 			   space correctly. */			if (mode == RM_BUILD || !relable) {				left = ih_get_offset(node40_ih_at(node, last_pos), 						     node->keypol);			}		} else {			/* Set the last correct offset and the keft limit. */			last_pos = i;			left = (i == count) ? nh_get_free_space_start(node) : 				ih_get_offset(node40_ih_at(node, i), 					      node->keypol);		}	}	left -= (i - last_pos) * MIN_ITEM_LEN;		res |= node40_space_check(node, left, mode);	return res;}/* Checks the count of items written in node_header. If it is wrong, it tries   to estimate it on the base of free_space fields and recover if REBUILD mode.   Returns FATAL otherwise. */static errno_t node40_count_check(reiser4_node_t *node, uint8_t mode) {	uint32_t num, count;	blk_t blk;		aal_assert("vpf-802", node != NULL);	aal_assert("vpf-803", node->block != NULL);		blk = node->block->nr;		/* Check the count of items. */	if (node40_count_valid(node)) 		return 0;		/* Count is probably is not valid. Estimate the count. */	num = node40_estimate_count(node);	count = nh_get_num_items(node);		if (num >= count)		return 0;		fsck_mess("Node (%llu): Count of items (%u) is wrong. "		  "Only (%u) items found.%s", blk, count, num, 		  mode == RM_BUILD ? " Fixed." : "");	/* Recover is impossible. */	if (mode != RM_BUILD)		return RE_FATAL;	nh_set_num_items(node, num);	node40_mkdirty(node);	return 0;}static errno_t node40_iplug_check(reiser4_node_t *node, uint8_t mode) {	uint32_t count, len;	uint16_t pid;	errno_t res;	pos_t pos;	void *ih;		count = nh_get_num_items(node);	ih = node40_ih_at(node, 0);	pos.unit = MAX_UINT32;	res = 0;	for (pos.item = 0; pos.item < count; pos.item++, 	     ih -= ih_size(node->keypol)) 	{		pid = ih_get_pid(ih, node->keypol);				if (!node40_core->factory_ops.ifind(ITEM_PLUG_TYPE, pid)) {			fsck_mess("Node (%llu), item (%u): the item of unknown "				  "plugin id (0x%x) is found.%s", node->block->nr,				  pos.item, pid, mode == RM_BUILD ? " Removed." :				  "");						if (mode != RM_BUILD) {				res |= RE_FATAL;				continue;			}						/* Item plugin cannot be found, remove it. */			len = node40_size(node, &pos, 1);						if ((res = node40_shrink(node, &pos, len, 1)))				return res;		}	}	return res;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -