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

📄 extent40_repair.c

📁 reiser4progs ReiserFS V4 ReiserFs官方已经关闭 这个是1.0.6 2006-02-22发布的 给需要的朋友
💻 C
字号:
/* Copyright 2001-2005 by Hans Reiser, licensing governed by   reiser4progs/COPYING.      extent40_repare.c -- repair dafault extent plugin methods. */#ifndef ENABLE_MINIMAL#include "extent40.h"#include <repair/plugin.h>static int extent40_join_units(reiser4_place_t *place, int fix) {	uint32_t i, count, joint;	extent40_t *extent;	extent = extent40_body(place);	count = extent40_units(place);	joint = 0;		for (i = 0; i < count; i++, extent++) {		bool_t join = 0;		/* width == 0. */		if (!et40_get_width(extent))			goto shrink;		if (i == 0) continue;			join = (et40_get_start(extent - 1) == 0 &&			et40_get_start(extent) == 0);		join = (et40_get_start(extent - 1) + et40_get_width(extent - 1)			== et40_get_start(extent)) || join;				if (!join) continue;			shrink:		joint++;			if (!fix) continue;				if (i) {			et40_set_width(extent - 1, et40_get_width(extent - 1)				       + et40_get_width(extent));		}				extent40_shrink(place, i, 1);		count--;		extent--;		i--;	}	return joint;}errno_t extent40_check_layout(reiser4_place_t *place, 			      repair_hint_t *hint, 			      region_func_t func, 			      void *data){	extent40_t *extent;	uint32_t i, units;	errno_t result = 0;		aal_assert("vpf-724", place != NULL);	aal_assert("vpf-725", func != NULL);	extent = extent40_body(place);	units = extent40_units(place);				for (i = 0; i < units; i++, extent++) {		uint64_t start, width;		errno_t res;		start = et40_get_start(extent);		width = et40_get_width(extent);				if (start == EXTENT_HOLE_UNIT || 		    start == EXTENT_UNALLOC_UNIT || 		    width == 0)		{			continue;		}		if ((res = func(start, width, data)) < 0)			return res;				if (!res) continue;				/* Zero the problem region. */		fsck_mess("Node (%llu), item (%u), unit (%u), [%s]: "			  "points %s region [%llu..%llu].%s", 			  place_blknr(place), place->pos.item, i, 			  print_key(extent40_core, &place->key),			  res == RE_FATAL? "out of the fs," : 			  "to the already used blocks, ", start,			  start + width - 1, hint->mode != RM_CHECK ? 			  " Zeroed." : "");		if (hint->mode != RM_CHECK) {			et40_set_start(extent, 0);			place_mkdirty(place);		} else			result = RE_FIXABLE;	}		if (hint->mode != RM_CHECK) {		if ((units = extent40_join_units(place, 1))) {			fsck_mess("Node (%llu), item (%u): %u mergable units "				  "were found in the extent40 unit.%s", 				  place_blknr(place), place->pos.item, units, 				  hint->mode == RM_CHECK ? "" : " Merged.");						hint->len += (units * sizeof(extent40_t));		}	}		return result;}errno_t extent40_check_struct(reiser4_place_t *place, repair_hint_t *hint) {	extent40_t *extent;	uint32_t i, units;	errno_t res = 0;		aal_assert("vpf-750", place != NULL);		/* Length must be divisible by the extent40 unit length. */	if (place->len % sizeof(extent40_t)) {		fsck_mess("Node (%llu), item (%u), [%s]: extent40 "			  "item of not valid length found.", 			  place_blknr(place), place->pos.item,			  print_key(extent40_core, &place->key));		return RE_FATAL;	}		/* Offset must be divisible by block size. */	if (objcall(&place->key, get_offset) % place_blksize(place)) {		fsck_mess("Node (%llu), item (%u), [%s]: extent40 "			  "item with not valid key offset found.",			  place_blknr(place), place->pos.item,			  print_key(extent40_core, &place->key));		return RE_FATAL;	}		extent = extent40_body(place);	units = extent40_units(place);		if (!units) {		fsck_mess("Node (%llu), item (%u): empty extent40 item "			  "found.", place_blknr(place), place->pos.item);		return RE_FATAL;	}		/* Zero all unallocated units if any found. */	for (i = 0; i < units; i++, extent++) {		uint64_t start;		if (!(start = et40_get_start(extent)))			continue;				if (start != EXTENT_UNALLOC_UNIT)			continue;		fsck_mess("Node (%llu), item (%u), unit (%u), "			  "[%s]: unallocated unit is found.%s", 			  place_blknr(place), place->pos.item, i,			  print_key(extent40_core, &place->key),			  hint->mode == RM_CHECK ? "" : "Zeroed.");				if (hint->mode != RM_CHECK) {			et40_set_start(extent, 0);			place_mkdirty(place);		} else 			res |= RE_FIXABLE;	}		if (hint->mode != RM_CHECK) {		if ((units = extent40_join_units(place, 1))) {			fsck_mess("Node (%llu), item (%u): %u mergable units "				  "were found in the extent40 unit.%s", 				  place_blknr(place), place->pos.item, units, 				  hint->mode == RM_CHECK ? "" : " Merged.");						hint->len += (units * sizeof(extent40_t));		}	}		return res;}static uint32_t extent40_head(reiser4_place_t *place, 			      uint32_t pos, 			      reiser4_key_t *key) {	uint64_t koffset, offset, doffset;	koffset = objcall(key, get_offset);	offset  = objcall(&place->key, get_offset);	aal_assert("vpf-1381", koffset >= offset);		offset = koffset - offset;	doffset = extent40_offset(place, pos);		aal_assert("vpf-1787", offset >= doffset);		return (offset - doffset) / place_blksize(place);}errno_t extent40_prep_insert_raw(reiser4_place_t *place, trans_hint_t *hint) {	extent40_t *sextent, *dextent;	int32_t send, sunits;	reiser4_place_t *src;	uint64_t offset;		aal_assert("vpf-1372", place != NULL);	aal_assert("vpf-1373", hint != NULL);	aal_assert("vpf-1382", hint->specific != NULL);	src = (reiser4_place_t *)hint->specific;	sextent = extent40_body(src);	dextent = extent40_body(place);		/* Get the offset of the dst item key. */	offset = objcall(&place->key, get_offset);		/* Probably all units will be inserted. */	send = src->pos.unit - 1;	sunits = extent40_units(src);		/* Get the head within the first @src unit. Head should be calculated 	   here because we may try to insert not from the beginning of the @src	   in any case. */	hint->head = extent40_head(src, src->pos.unit, &hint->offset);	hint->tail = 0;	hint->insert_flags = 0;	if (place->pos.unit == MAX_UINT32 ||	    place->pos.unit == extent40_units(place))	{		/* The whole item to be inserted. */		send = sunits - 1;	} else if (objcall(&hint->offset, compfull, &place->key) < 0) {		/* Get the @src end unit and the tail within it. */		offset -= objcall(&src->key, get_offset);				send = extent40_unit(src, offset - 1);				hint->tail = et40_get_width(sextent + send) - 			extent40_head(src, send, &place->key);	} else if (!et40_get_start(dextent + place->pos.unit) && 		   et40_get_start(sextent + src->pos.unit)) 	{		/* Estimate the overwrite. */		hint->insert_flags |= ET40_OVERWRITE;		/* Overwrite through the next dst unit key. */		offset += extent40_offset(place, place->pos.unit + 1);				/* Get the end position. */		offset -= objcall(&src->key, get_offset);		send = extent40_unit(src, offset - 1);				if (send < sunits) {			hint->tail = (extent40_offset(src, send + 1) - offset)				/ place_blksize(src);		} else {			/* The src item finished earlier then dst item by key 			   offset, then some part of the dst item will not be			   overwritten, set TAIL falg here. */			send = sunits - 1;			hint->tail = 0;			hint->insert_flags |= ET40_TAIL;		}				if (extent40_head(place, place->pos.unit, &hint->offset))			hint->insert_flags |= ET40_HEAD;	} 		hint->overhead = 0;	hint->bytes = 0;		hint->count = send + 1 - src->pos.unit;	hint->len = hint->count;		if (hint->insert_flags & ET40_OVERWRITE) {		/* If this is an overrite, the current dst unit can be used 		   instead of adding another one (if there is no head in dst)		   and one more unit should be inserted (if there is a tail). */		hint->len += (hint->insert_flags & ET40_TAIL ? 1 : 0)			- (hint->insert_flags & ET40_HEAD ? 0 : 1);	}		hint->len *= sizeof(extent40_t);		return 0;}int64_t extent40_insert_raw(reiser4_place_t *place, trans_hint_t *hint) {	uint32_t i, sstart, dstart, count;	extent40_t *sextent, *dextent;	uint64_t head, tail, offset;	reiser4_place_t *src;	errno_t res;		aal_assert("vpf-1383", place != NULL);	aal_assert("vpf-1384", hint != NULL);	aal_assert("vpf-1385", hint->specific != NULL);	src = (reiser4_place_t *)hint->specific;	sextent = extent40_body(src);	dextent = extent40_body(place);	if (place->pos.unit == MAX_UINT32)		place->pos.unit = 0;		/* @head & @tail were calculated for the start unit, but 	   if ET40_HEAD flag is set, data should be inserted to 	   the next unit. */	dstart = place->pos.unit + 		(hint->insert_flags & ET40_HEAD ? 1 : 0);		sstart = src->pos.unit == MAX_UINT32 ? 0 : src->pos.unit;	/* Set the maxkey of the passed operation. */	aal_memcpy(&hint->maxkey, &hint->offset, sizeof(hint->maxkey));		if (!hint->count) {		/* If there is nothing to be done, skip as much as possible. */		if (et40_get_start(dextent + dstart)) {			/* Skip all not zero pointers in @dst. */			count = extent40_units(place);					while (dstart < count && 			       et40_get_start(dextent + dstart)) 			{				dstart++;			}			/* Get the offset for the maxkey. */			offset = objcall(&place->key, get_offset);			offset += extent40_offset(place, dstart);		} else {			uint32_t scount;						/* Skip all zero pointers in @src. */			scount = extent40_units(src);						while (sstart < scount && 			       !et40_get_start(sextent + sstart)) 			{				sstart++;			}						/* Get the offset for the maxkey. */			offset = objcall(&src->key, get_offset);			offset += extent40_offset(src, sstart);		}				objcall(&hint->maxkey, set_offset, offset);		return 0;	}	count = hint->count;	if (hint->insert_flags & ET40_OVERWRITE) {		count += hint->insert_flags & ET40_TAIL ? 1 : 0;		count -= hint->insert_flags & ET40_HEAD ? 0 : 1;	}	/* Set the maxkey offset correctly. */	offset = objcall(&src->key, get_offset);	offset += extent40_offset(src, sstart + hint->count);	offset -= hint->tail * place_blksize(src);	objcall(&hint->maxkey, set_offset, offset);	tail = head = 0;		if (hint->insert_flags & ET40_TAIL) {		/* Get the amount of blocks to be left in the head. */		tail = extent40_head(place, place->pos.unit, &hint->maxkey);	} 		if (hint->insert_flags & ET40_HEAD) {		/* Get the amount of blocks to be left in the tail. */		head = extent40_head(place, place->pos.unit, &hint->offset);	} 	/* Expanding extent item at @place */	extent40_expand(place, dstart, count);	/* If some tail should be cut off the current dst unit, set the 	   correct width there. */	if (hint->insert_flags & ET40_TAIL) {		uint64_t width;				/* Set the correct width. Start is 0 because allocated 		   units are not overwritten. */		et40_set_start(dextent + place->pos.unit + count, 0);		width = et40_get_width(dextent + place->pos.unit) - tail;		et40_set_width(dextent + place->pos.unit + count, width);		/* Fix the current dst unit after cutting. */		et40_set_width(dextent + place->pos.unit, tail);	}	/* If some head should be left in the current dst unit, set the 	   correct width there. */	if (hint->insert_flags & ET40_HEAD) {		/* Get the amount of blocks to be left. */		/* Fix the current dst unit. */		et40_set_width(dextent + place->pos.unit, head);	}	dextent += dstart;	sextent += sstart;			aal_memcpy(dextent, sextent, 		   hint->count * sizeof(extent40_t));		if (hint->head) {		/* Cut head blocks of the first unit copied from src, 		   if it was not the hole (==0). */		if ((dstart = et40_get_start(dextent)))			et40_set_start(dextent, dstart + hint->head);				et40_set_width(dextent, et40_get_width(dextent) - 			       hint->head);	}		/* Fix the tail unit. */	dextent += hint->count - 1;	if (hint->tail) {		et40_set_width(dextent, et40_get_width(dextent) -			       hint->tail);	}		/* Call region_func for all inserted regions. */	if (hint->region_func) {		uint64_t dwidth;				dextent -= (hint->count - 1);				for (i = 0; i < hint->count; i++, dextent++) {			dstart = et40_get_start(dextent);			dwidth = et40_get_width(dextent);						if (dstart == EXTENT_UNALLOC_UNIT || 			    dstart == EXTENT_HOLE_UNIT)			{				continue;			}						if ((res = hint->region_func(dstart, dwidth,						     hint->data)))			{				return res;			}		}	}		/* Update the item key. */	if (objcall(&hint->offset, compfull, &place->key) < 0)		aal_memcpy(&place->key, &hint->offset, sizeof(place->key));		place_mkdirty(place);		return 0;}/* Prints extent item into specified @stream */void extent40_print(reiser4_place_t *place, aal_stream_t *stream,		    uint16_t options){	uint32_t i, count;	extent40_t *extent;    	aal_assert("umka-1205", place != NULL);	aal_assert("umka-1206", stream != NULL);	extent = extent40_body(place);	count = extent40_units(place);	aal_stream_format(stream, "\nUNITS=%u [", count);			for (i = 0; i < count; i++) {		aal_stream_format(stream, "%llu(%llu)%s",				  et40_get_start(extent + i),				  et40_get_width(extent + i),				  (i < count - 1 ? " " : ""));	}		aal_stream_format(stream, "]\n");}#endif

⌨️ 快捷键说明

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