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

📄 extent40.c

📁 reiser4progs ReiserFS V4 ReiserFs官方已经关闭 这个是1.0.6 2006-02-22发布的 给需要的朋友
💻 C
📖 第 1 页 / 共 3 页
字号:
	reiser4_key_t key;	uint64_t unit_size;	uint64_t max_off;	uint64_t ins_off;	uint64_t uni_off;	uint64_t blk_off;	uint64_t total;	uint64_t start;	int64_t count;	int64_t bytes;	int64_t size;	uint32_t unit_pos;	uint32_t blksize;	uint32_t width;	uint32_t units;	errno_t res;	char *buff;	aal_assert("umka-2357", hint != NULL);	aal_assert("umka-2356", place != NULL);	/* Correcting insert point, as it may point to -1 (create new item) and	   behind last unit (adding data at the end of item). */	if (place->pos.unit == MAX_UINT32)		place->pos.unit = 0;	hint->bytes = 0;	buff = hint->specific;	unit_pos = place->pos.unit;	units = extent40_units(place);	device = extent40_device(place);	blksize = place_blksize(place);	/* Get the offset range being handled: ins_off, max_off. */	ins_off = objcall(&hint->offset, get_offset);	max_off = objcall(&hint->maxkey, get_offset);	total = max_off - ins_off;	count = total;	if (hint->insert_flags & ET40_OVERWRITE) {		/* If overwrite requires space, split the unit correctly. */		extent = extent40_body(place) + unit_pos;		uni_off = extent40_offset(place, unit_pos);		/* This loop checks if we insert some data inside extent and we		   should take into account possible holes. */		for ( ; count > 0 && unit_pos < units;		      count -= size, unit_pos++, extent++,		      ins_off += size, uni_off += unit_size)		{			start = et40_get_start(extent);			width = et40_get_width(extent);			unit_size = width * blksize;			size = unit_size - (ins_off - uni_off);			if (size > count)				size = count;			if (start != EXTENT_HOLE_UNIT || !buff) 				continue;			/* Overwrite the hole with the data.			   (1) the whole hole gets overwritten;			   (2) a part of it, needs to be splitted;			   (3) a middle part, 2 splits are needed. */						aal_assert("vpf-1700", ins_off >= uni_off);			if (ins_off >= uni_off + blksize) {				/* Overwrite the tail. */				/* Add the unit after the current one. */				extent40_expand(place, unit_pos + 1, 1);				/* Get the size of the current. */				unit_size = ins_off - uni_off;				unit_size /= blksize;				aal_assert("vpf-1699", width > unit_size);				/* Reset widths of the current and the next. */				et40_set_width(extent, unit_size);				et40_set_width(extent + 1, width - unit_size);				et40_set_start(extent + 1, EXTENT_HOLE_UNIT);				/* Recalc the unit size values. */				unit_size *= blksize;				size = 0;			}			if (ins_off + size + blksize <= uni_off + unit_size) {				/* Overwrite the head. */				/* Add the unit after the current one. */				extent40_expand(place, unit_pos + 1, 1);				/* Get the size of the next. */				unit_size = ins_off + size - uni_off;				unit_size = (unit_size + blksize - 1) / blksize;				aal_assert("vpf-1701", width > unit_size);				/* Reset widths of the current and the next. */				et40_set_width(extent, unit_size);				et40_set_width(extent + 1, width - unit_size);				et40_set_start(extent + 1, EXTENT_HOLE_UNIT);				/* Recalc the unit size values. */				unit_size *= blksize;			}			if (!size) continue; 						et40_set_start(extent, EXTENT_UNALLOC_UNIT);			/* Size bytes are to be written to this unit. */			bytes = extent40_alloc_block(place, hint->blocks,						     ins_off, size);			if (bytes < 0) 				return bytes;			hint->bytes += bytes;			aal_assert("vpf-1703", bytes == width * blksize);		}	} else {		int allocate = 0;				/* Calculating width in blocks of new unit to be inserted. */		width = max_off - ins_off;		width = (width + blksize - 1) / blksize;		if (unit_pos && (hint->insert_flags & ET40_JOIN)) {			/* Some units exist and new get merged with the last. */			/* Increment the width of the last unit. */			place->pos.unit--;			unit_pos--;			extent = extent40_body(place) + unit_pos;			start = et40_get_start(extent);			et40_inc_width(extent, width);			allocate = (start == EXTENT_UNALLOC_UNIT);		} else {			/* First unit or cannot merge with the last one. */			extent = extent40_body(place) + unit_pos;			/* If some data are being inserted, allocate some 			   blocks for them later. */			if (buff) {				et40_set_start(extent, EXTENT_UNALLOC_UNIT);				allocate = 1;			} else {				et40_set_start(extent, EXTENT_HOLE_UNIT);			}			et40_set_width(extent, width);		}		if (allocate) {			if ((bytes = extent40_alloc_block(place, hint->blocks,							  ins_off, count)) < 0)			{				return bytes;			}			hint->bytes += bytes;			aal_assert("vpf-1703", bytes == width * blksize);		}	}	/* Updating @key by unit key as it is changed. */	extent40_fetch_key(place, &key);	extent = extent40_body(place) + place->pos.unit;	uni_off = objcall(&key, get_offset);	ins_off = objcall(&hint->offset, get_offset);		count = total;	/* Second stage -- writing data to allocated blocks. */	for ( ; count > 0; count -= size, ins_off += size) {		blk_t blk;				/* Calculating size to be written this time. */		size = blksize - (ins_off & (blksize - 1));		/* Block offset we will insert in. */		blk_off = ins_off - (ins_off & (blksize - 1));		if (size > count)			size = count;		/* Preparing key for getting data by it. */		objcall(&key, set_offset, blk_off);		/* Checking if we write data inside item. */		aal_assert("vpf-1705", blk_off + size <= max_off);		start = et40_get_start(extent);		width = et40_get_width(extent);		/* Nothing to be done if hole gets overwritten with hole. */		if (start == EXTENT_HOLE_UNIT && !buff)			continue;		/* Blocks must be allocated already. */		aal_assert("vpf-1706", start != EXTENT_HOLE_UNIT);		blk = (blk_off - uni_off) / blksize;		if (!(block = extent40_load_block(place, hint->blocks, 						  &key, start, blk)))		{			return -EINVAL;		}		/* Writting data to @block. */		if (buff) {			aal_memcpy(block->data + ins_off - blk_off, buff, size);			buff += size;		} else {			/* Writting a hole. */			aal_memset(block->data + ins_off - blk_off, 0, size);		}		block->dirty = 1;		if (blk == width) {			extent++;			uni_off += (width * blksize);		}	}		if ((res = extent40_core->tree_ops.mpressure(place->node->tree)))		return res;		place_mkdirty(place);	return total;}/* Calls @region_func for each block number extent points to. It is needed for   calculating fragmentation, etc. */static errno_t extent40_layout(reiser4_place_t *place,			       region_func_t region_func,			       void *data){	extent40_t *extent;	uint32_t i, units;	errno_t res = 0;		aal_assert("umka-1747", place != NULL);	aal_assert("umka-1748", region_func != NULL);	extent = extent40_body(place);	units = extent40_units(place);	for (i = 0; i < units; i++, extent++) {		uint64_t start;		uint64_t width;		start = et40_get_start(extent);		if (start == EXTENT_UNALLOC_UNIT || start == EXTENT_HOLE_UNIT)			continue;				width = et40_get_width(extent);				if ((res = region_func(start, width, data)))			return res;	}				return 0;}/* Estimates how many bytes may be shifted into neighbour item */static errno_t extent40_prep_shift(reiser4_place_t *src_place,				   reiser4_place_t *dst_place,				   shift_hint_t *hint){	int check_point;	uint32_t units;		aal_assert("umka-1705", hint != NULL);	aal_assert("umka-1704", src_place != NULL);	hint->units_number = 0;	check_point = (src_place->pos.item == hint->pos.item &&		       hint->pos.unit != MAX_UINT32);			if (hint->control & SF_ALLOW_LEFT) {		uint32_t left;		/* If we have to take into account insert point. */		if (hint->control & SF_UPDATE_POINT && check_point) {			left = hint->pos.unit * sizeof(extent40_t);					if (hint->control & SF_HOLD_POS &&			    hint->control & SF_MOVE_POINT)			{				units = extent40_units(src_place);				if (units > hint->pos.unit)					left += sizeof(extent40_t);			}						if (hint->units_bytes > left)				hint->units_bytes = left;			/* Units to be moved. */			units = hint->units_bytes / sizeof(extent40_t);						if (hint->pos.unit <= units &&			    (hint->control & SF_MOVE_POINT))			{				hint->result |= SF_MOVE_POINT;				hint->pos.unit = dst_place ? dst_place->len : 0;				hint->pos.unit += hint->units_bytes;				hint->pos.unit /= sizeof(extent40_t);				if (hint->control & SF_HOLD_POS)					hint->pos.unit--;			} else {				hint->pos.unit -= hint->units_bytes /					sizeof(extent40_t);			}		} else {			if (hint->units_bytes > src_place->len)				hint->units_bytes = src_place->len;		}	} else {		uint32_t right;		/* The same check as abowe, but for right shift */		if (hint->control & SF_UPDATE_POINT && check_point) {			units = extent40_units(src_place);						/* Check is it is possible to move something into right			   neighbour item. */			if (hint->pos.unit < units) {				units -= hint->pos.unit;				units *= sizeof(extent40_t);				right = units;					if (hint->control & SF_HOLD_POS &&				    !(hint->control & SF_MOVE_POINT))				{					right -= sizeof(extent40_t);				}				if (hint->units_bytes > right)					hint->units_bytes = right;				if ((hint->control & SF_MOVE_POINT) &&				    hint->units_bytes == units)				{					hint->result |= SF_MOVE_POINT;					hint->pos.unit = 0;				} 			} else {				/* There is noning to move, update insert point,				   flags and out. */				if (hint->control & SF_MOVE_POINT) {					hint->result |= SF_MOVE_POINT;					hint->pos.unit = 0;				}				hint->units_bytes = 0;			}		} else {			if (hint->units_bytes > src_place->len)				hint->units_bytes = src_place->len;		}	}	hint->units_bytes -= hint->units_bytes % sizeof(extent40_t);	hint->units_number = hint->units_bytes / sizeof(extent40_t);		return 0;}static errno_t extent40_shift_units(reiser4_place_t *src_place,				    reiser4_place_t *dst_place,				    shift_hint_t *hint){	uint32_t pos;		aal_assert("umka-1708", hint != NULL);	aal_assert("umka-1706", src_place != NULL);	aal_assert("umka-1707", dst_place != NULL);	if (hint->control & SF_ALLOW_LEFT) {		pos = extent40_units(dst_place) - hint->units_number;					/* Preparing space in @dst_place. */		extent40_expand(dst_place, pos, hint->units_number);		/* Copying data from the @src_place to @dst_place. */		extent40_copy(dst_place, pos, src_place, 0,			      hint->units_number);		/* Updating item's key by the first unit key. */		body40_get_key(src_place, hint->units_number,			       &src_place->key, extent40_offset);		/* Removing units in @src_place. */		extent40_shrink(src_place, 0, hint->units_number);	} else {		/* Preparing space in @dst_place */		extent40_expand(dst_place, 0, hint->units_number);		/* Copying data from the @src_place to @dst_place. */		pos = extent40_units(src_place) - hint->units_number;				extent40_copy(dst_place, 0, src_place, pos,			      hint->units_number);				/* Updating item's key by the first unit key. */		body40_get_key(src_place, pos, &dst_place->key,			       extent40_offset);		/* Removing units in @src_place. */		extent40_shrink(src_place, pos, hint->units_number);	}		return 0;}#endifstatic item_balance_ops_t balance_ops = {#ifndef ENABLE_MINIMAL	.merge		  = NULL,	.update_key	  = NULL,	.mergeable	  = extent40_mergeable,	.prep_shift	  = extent40_prep_shift,	.shift_units	  = extent40_shift_units,	.maxreal_key	  = extent40_maxreal_key,	.collision	  = NULL,	.overhead	  = NULL,#endif	.init		  = NULL,	.units		  = extent40_units,	.lookup		  = extent40_lookup,	.fetch_key	  = extent40_fetch_key,	.maxposs_key      = extent40_maxposs_key};static item_object_ops_t object_ops = {#ifndef ENABLE_MINIMAL	.remove_units	  = extent40_remove_units,	.update_units	  = extent40_update_units,	.prep_insert	  = extent40_prep_insert,	.insert_units	  = extent40_insert_units,	.prep_write	  = extent40_prep_write,	.write_units	  = extent40_write_units,	.trunc_units	  = extent40_trunc_units,	.layout		  = extent40_layout,	.size		  = extent40_size,	.bytes		  = extent40_bytes,#endif	.read_units	  = extent40_read_units,	.fetch_units	  = extent40_fetch_units};#ifndef ENABLE_MINIMALstatic item_repair_ops_t repair_ops = {	.check_layout	  = extent40_check_layout,	.check_struct	  = extent40_check_struct,		.prep_insert_raw  = extent40_prep_insert_raw,	.insert_raw	  = extent40_insert_raw,	.pack		  = NULL,	.unpack		  = NULL};static item_debug_ops_t debug_ops = {	.print		  = extent40_print,};#endifreiser4_item_plug_t extent40_plug = {	.p = {		.id	= {ITEM_EXTENT40_ID, EXTENT_ITEM, ITEM_PLUG_TYPE},#ifndef ENABLE_MINIMAL		.label = "extent40",		.desc  = "Extent file body item plugin.",#endif	},		.object		  = &object_ops,	.balance	  = &balance_ops,#ifndef ENABLE_MINIMAL	.repair		  = &repair_ops,	.debug		  = &debug_ops,#endif};

⌨️ 快捷键说明

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