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

📄 dir40_repair.c

📁 reiser4progs ReiserFS V4 ReiserFs官方已经关闭 这个是1.0.6 2006-02-22发布的 给需要的朋友
💻 C
字号:
/* Copyright 2001-2005 by Hans Reiser, licensing governed by   reiser4progs/COPYING.      dir40_repair.c -- reiser4 default directory file plugin repair code. */ #ifndef ENABLE_MINIMAL#include "dir40_repair.h"static errno_t dir40_dot(reiser4_object_t *dir, 			 reiser4_item_plug_t *bplug, 			 uint8_t mode) {	object_info_t *info;	entry_hint_t entry;	trans_hint_t hint;	errno_t res;		aal_assert("vpf-1242", dir != NULL);	aal_assert("vpf-1244", bplug != NULL);		/* Lookup the "." */	if ((res = dir40_reset(dir)))		return res;		if ((res = obj40_find_item(dir, &dir->position, FIND_CONV, 				   NULL, NULL, &dir->body)) < 0)	{		return res;	}	if (res == PRESENT)		return 0;		info = &dir->info;		fsck_mess("Directory [%s]: The entry \".\" is not found.%s "		  "Plugin (%s).", print_inode(obj40_core, &info->object), 		  mode != RM_CHECK ? " Insert a new one." : "", 		  reiser4_psobj(dir)->p.label);		if (mode == RM_CHECK)		return RE_FIXABLE;		/* Absent. Add a new ".". */			aal_memset(&hint, 0, sizeof(hint));	hint.count = 1;	hint.plug = bplug;	hint.shift_flags = SF_DEFAULT;		aal_memcpy(&hint.offset, &dir->position, sizeof(dir->position));	aal_memcpy(&entry.offset,  &dir->position, sizeof(dir->position));	aal_memcpy(&entry.object,  &dir->info.object, sizeof(entry.object));	aal_strncpy(entry.name, ".", 1);	hint.specific = &entry;	res = obj40_insert(dir, &dir->body, &hint, LEAF_LEVEL);	return res < 0 ? res : 0;}static errno_t dir40_entry_check(reiser4_object_t *dir,				 obj40_stat_hint_t *hint,				 place_func_t func, 				 void *data, 				 uint8_t mode){	entry_hint_t entry;	trans_hint_t trans;	reiser4_key_t key;	uint32_t units;	errno_t result;	errno_t res;	bool_t last;	pos_t *pos;	res = 0;	pos = &dir->body.pos;	units = objcall(&dir->body, balance->units);		if (pos->unit == MAX_UINT32)		pos->unit = 0;		last = 0;	for (; pos->unit < units; pos->unit++) {		last = (pos->unit == units - 1);				if (last) {			/* If we are handling the last unit, register the item 			   despite the result of handling. Any item has a 			   pointer to objectid in the key, if it is shared 			   between 2 objects, it should be already solved at 			   relocation time. */			if (func && func(&dir->body, data))				return -EINVAL;			/* Count size and bytes. */			hint->size += objcall(&dir->body, object->size);			hint->bytes += objcall(&dir->body, object->bytes);		}		if ((result = dir40_fetch(dir, &entry)) < 0)			return result;		/* Prepare the correct key for the entry. */		plugcall(entry.offset.plug, build_hashed, &key,			 reiser4_pshash(dir), reiser4_psfibre(dir),			 objcall(&dir->info.object, get_locality),			 objcall(&dir->info.object, get_objectid), entry.name);		/* If the key matches, continue. */		if (objcall(&key, compfull, &entry.offset)) {			/* Broken entry found, remove it. */			fsck_mess("Directory [%s] (%s), node [%llu], "				  "item [%u], unit [%u]: entry has wrong "				  "offset [%s]. Should be [%s].%s", 				  print_inode(obj40_core, &dir->info.object),				  reiser4_psobj(dir)->p.label, 				  place_blknr(&dir->body), 				  dir->body.pos.item, dir->body.pos.unit,				  print_key(obj40_core, &entry.offset),				  print_key(obj40_core, &key), 				  mode == RM_BUILD ? " Removed." : "");						if (mode != RM_BUILD) {				/* If not the BUILD mode, continue with the 				   entry key, not the correct one. */				aal_memcpy(&key, &entry.offset, sizeof(key));				res |= RE_FATAL;			} else {				break;			}		}		/* Either key is ok or we are in CHECK mode, take the next 		   entry. */		if (objcall(&dir->position, compfull, &key)) {			/* Key differs from the last left entry offset. */			aal_memcpy(&dir->position, &key, sizeof(key));		} else if (aal_strlen(entry.name) != 1 ||			   aal_strncmp(entry.name, ".", 1))		{			/* Key collision. */			dir->position.adjust++;		}	}		/* All entries were handled. */	if (pos->unit == units)		return res;		/* Some entry is bad and needs to be removed. */	trans.count = 1;	trans.shift_flags = SF_DEFAULT & ~SF_ALLOW_PACK;	if ((result = obj40_remove(dir, &dir->body, &trans)) < 0)		return result;		/* Adjust position to the following incrementing, needed as the entry 	   is removed. */	dir->position.adjust--;	/* Update accounting info after remove. */	if (last) {		hint->size--;		hint->bytes -= trans.bytes;	}	return 0;}static errno_t dir40_check_item(reiser4_object_t *dir, void *data) {	uint8_t mode = *(uint8_t *)data;		/* FIXME-VITALY: item of the same group but of another plugin,	   should it be converted? */	if (dir->body.plug != reiser4_psdiren(dir)) {		fsck_mess("Directory [%s] (%s), node [%llu], item"			  "[%u]: item of the illegal plugin (%s) "			  "with the key of this object found.%s",			  print_inode(obj40_core, &dir->info.object),			  reiser4_psobj(dir)->p.label, 			  place_blknr(&dir->body), dir->body.pos.item,			  dir->body.plug->p.label, mode == RM_BUILD ? 			  " Removed." : "");				return mode == RM_BUILD ? -ESTRUCT : RE_FATAL;	}		return 0;}errno_t dir40_check_struct(reiser4_object_t *dir,			   place_func_t func,			   void *data, uint8_t mode){	obj40_stat_hint_t hint;	object_info_t *info;		errno_t res;		aal_assert("vpf-1224", dir != NULL);	aal_assert("vpf-1190", dir->info.tree != NULL);	aal_assert("vpf-1197", dir->info.object.plug != NULL);		info = &dir->info;	aal_memset(&hint, 0, sizeof(hint));		if ((res = obj40_prepare_stat(dir, S_IFDIR, mode)))		return res;		/* Try to register SD as an item of this file. */	if (func && func(&info->start, data))		return -EINVAL;		/* Take care about the ".". */	/* FIXME: Probably it should be different -- find an item by the key 	   and if it is of DIR group, take its plugin as body plug, fix 	   it in SD then. */	if ((res |= dir40_dot(dir, reiser4_psdiren(dir), mode)) < 0)		return res;		while (1) {		lookup_t lookup;				lookup = obj40_check_item(dir, dir40_check_item, 					  dir40_entry_comp, &mode);				if (repair_error_fatal(lookup))			return lookup;		else if (lookup == ABSENT)			break;				/* Looks like an item of dir40. If there were some key collisions, 		   this search was performed with incremented adjust, decrement it 		   here. */		if (dir->position.adjust)			dir->position.adjust--;		if ((res |= dir40_entry_check(dir, &hint, func, 					      data, mode)) < 0)		{			return res;		}				/* Lookup for the last handled entry key with the incremented 		   adjust to get the next entry. */		dir->position.adjust++;	}		/* Fix the SD, if no fatal corruptions were found. */	if (!(res & RE_FATAL)) {		obj40_stat_ops_t ops;				aal_memset(&ops, 0, sizeof(ops));		ops.check_nlink = mode == RM_BUILD ? 0 : SKIP_METHOD;				hint.mode = S_IFDIR;		hint.nlink = 1;		res |= obj40_update_stat(dir, &ops, &hint, mode);	}		dir40_reset(dir);	return res;}errno_t dir40_check_attach(reiser4_object_t *object, 			   reiser4_object_t *parent,			   place_func_t func, 			   void *data, uint8_t mode){	entry_hint_t entry;	lookup_t lookup;	errno_t res;		aal_assert("vpf-1151", object != NULL);	aal_assert("vpf-1152", parent != NULL);		lookup = dir40_lookup(object, "..", &entry);	entry.place_func = func;	entry.data = data;		switch (lookup) {	case PRESENT:		/* If the key matches the parent -- ok. */		if (!objcall(&entry.object, compfull, &parent->info.object))			break;				/* Already attached. */		fsck_mess("Directory [%s] (%s): the object "			  "is attached already to [%s] and cannot "			  "be attached to [%s].", 			  print_inode(obj40_core, &object->info.object),			  reiser4_psobj(object)->p.label, 			  print_key(obj40_core, &entry.object),			  print_inode(obj40_core, &parent->info.object));		return RE_FATAL;	case ABSENT:		/* Not attached yet. *//*		if (plug_call(object->info.object.plug, compfull,			      &object->info.object, &parent->info.object))		{			fsck_mess("Directory [%s] (%s): the "			"object is not attached. %s [%s].",			print_inode(obj40_core, &object->info.object),			reiser4_psobj(object)->p.label, mode == RM_CHECK ? 			"Reached from" : "Attaching to",			print_inode(obj40_core, &parent->info.object));		}*/				if (mode == RM_CHECK) {			fsck_mess("Directory [%s] (%s): the object "				  "is not attached. Reached from [%s].",				  print_inode(obj40_core, &object->info.object),				  reiser4_psobj(object)->p.label,				  print_inode(obj40_core, &parent->info.object));			return RE_FIXABLE;		}				/* Adding ".." to the @object pointing to the @parent. */		aal_memcpy(&entry.object, &parent->info.object, 			   sizeof(entry.offset));		aal_strncpy(entry.name, "..", sizeof(entry.name));				if ((res = plugcall(reiser4_psobj(object), 				    add_entry, object, &entry)))		{			return res;		}		break;	default:		return lookup;	}	/* ".." matches the parent. Now do parent->nlink++ for REBUILD mode. */	if (mode != RM_BUILD)		return 0;		return plugcall(reiser4_psobj(parent), link, parent);}/* Creates the fake dir40 entity by the given @info for the futher recovery. */errno_t dir40_fake(reiser4_object_t *dir) {	aal_assert("vpf-1231", dir != NULL);		/* Positioning to the first directory unit */	dir40_reset(dir);		return 0;}#endif

⌨️ 快捷键说明

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