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

📄 extent40.c

📁 reiser4progs ReiserFS V4 ReiserFs官方已经关闭 这个是1.0.6 2006-02-22发布的 给需要的朋友
💻 C
📖 第 1 页 / 共 3 页
字号:
			/* Updating read offset and blk next read will			   be performed from. */			read_offset += size;			if ((read_offset % blksize) == 0)				blk++;		}		res = extent40_core->tree_ops.mpressure(place->node->tree);		if (res) return res;				rel_offset = 0;	}		return read - count;}#else/* Reads @count bytes of extent data from the extent item at passed @pos into   specified @buff. This function is used in minimal mode. It does not use   data cache and reads data by 512 bytes chunks. This is needed because of   GRUB, which has ugly mechanism of getting real block numbers data lie in. */static int64_t extent40_read_units(reiser4_place_t *place, trans_hint_t *hint) {	void *buff;	uint32_t i;	uint32_t read;	uint32_t count;	uint32_t blksize;	uint32_t secsize;	reiser4_key_t key;	uint64_t rel_offset;	uint64_t read_offset;	aal_assert("umka-1421", place != NULL);	buff = hint->specific;	count = (uint32_t)hint->count;		if (place->pos.unit == MAX_UINT32)		place->pos.unit = 0;		extent40_fetch_key(place, &key);		blksize = place_blksize(place);	secsize = extent40_secsize(place);	read_offset = objcall(&hint->offset, get_offset);	rel_offset = read_offset - objcall(&key, get_offset);		read = count;	for (i = place->pos.unit;	     i < extent40_units(place) && count > 0; i++, rel_offset = 0)	{		uint32_t blkchunk;		uint64_t blk, start;		/* Calculating start block for read. */		start = et40_get_start(extent40_body(place) + i);		blk = start + aal_div64(rel_offset, blksize, NULL);		/* Loop though the extent blocks */		while (blk < start + et40_get_width(extent40_body(place) + i) &&		       count > 0)		{			blk_t sec;			uint32_t blklocal;			blklocal = aal_mod64(rel_offset, blksize);						if ((blkchunk = blksize - blklocal) > count)				blkchunk = count;			sec = (blk * (blksize / secsize)) +				(blklocal / secsize);			/* Loop though one block (4096) */			while (blkchunk > 0) {				uint32_t secchunk;				uint32_t seclocal;				aal_block_t *block;				/* Calculating data chunk to be copied */				seclocal = (blklocal % secsize);								if ((secchunk = secsize - seclocal) > blkchunk)					secchunk = blkchunk;				/* Reading one sector */				if (!(block = aal_block_load(extent40_device(place),							     secsize, sec)))				{					return -EIO;				}				/* Copy data to passed buffer */				aal_memcpy(buff, block->data + seclocal,					   secchunk);								aal_block_free(block);				if ((seclocal + secchunk) % secsize == 0)					sec++;									buff += secchunk;				count -= secchunk;				rel_offset += secchunk;				blkchunk -= secchunk;				blklocal += secchunk;			}			if (blklocal % blksize == 0)				blk++;		}		rel_offset = 0;	}		return (uint64_t)read - count;}#endif/* Updates extent unit at @place by @data */static int64_t extent40_fetch_units(reiser4_place_t *place, trans_hint_t *hint) {	uint32_t i, pos;	extent40_t *extent;	ptr_hint_t *ptr_hint;		aal_assert("umka-2435", hint != NULL);	aal_assert("umka-2434", place != NULL);		pos = place->pos.unit == MAX_UINT32 ? 0 : place->pos.unit;	extent = extent40_body(place) + pos;	ptr_hint = (ptr_hint_t *)hint->specific;	for (i = pos; i < pos + hint->count;	     i++, ptr_hint++, extent++)	{		ptr_hint->start = et40_get_start(extent);		ptr_hint->width = et40_get_width(extent);	}	return hint->count;}#ifndef ENABLE_MINIMAL/* Checks if two extent items are mergeable */static int extent40_mergeable(reiser4_place_t *place1,			      reiser4_place_t *place2){	aal_assert("umka-2199", place1 != NULL);	aal_assert("umka-2200", place2 != NULL);	return body40_mergeable(place1, place2);}uint32_t extent40_expand(reiser4_place_t *place,			 uint32_t pos, uint32_t count){	/* Preparing space in @dst_place */	if (pos < extent40_units(place)) {		uint32_t size;		void *src, *dst;		src = (extent40_t *)place->body + pos;		dst = src + (count * sizeof(extent40_t));		size = (extent40_units(place) - pos - count) *			sizeof(extent40_t);		aal_memmove(dst, src, size);		place_mkdirty(place);	}	return 0;}uint32_t extent40_shrink(reiser4_place_t *place,			 uint32_t pos, uint32_t count){	/* Srinking @dst_place. */	if (pos < extent40_units(place)) {		uint32_t size;		void *src, *dst;		dst = (extent40_t *)place->body + pos;		src = dst + (count * sizeof(extent40_t));		size = (extent40_units(place) - pos) *			sizeof(extent40_t);		aal_memmove(dst, src, size);		place_mkdirty(place);	}	return 0;}/* Makes copy of units from @src_place to @dst_place */static errno_t extent40_copy(reiser4_place_t *dst_place, uint32_t dst_pos,			     reiser4_place_t *src_place, uint32_t src_pos,			     uint32_t count){	/* Copying units from @src_place to @dst_place */	if (count > 0) {		uint32_t size;		void *src, *dst;		size = count * sizeof(extent40_t);		src = (extent40_t *)src_place->body + src_pos;		dst = (extent40_t *)dst_place->body + dst_pos;				aal_memmove(dst, src, size);		place_mkdirty(dst_place);	}		return 0;}/* Updates extent unit at @place by @data */static int64_t extent40_update_units(reiser4_place_t *place,				     trans_hint_t *hint){	uint32_t i, pos;	extent40_t *extent;	ptr_hint_t *ptr_hint;		aal_assert("umka-2431", hint != NULL);	aal_assert("umka-2430", place != NULL);		pos = place->pos.unit == MAX_UINT32 ? 0 : place->pos.unit;		extent = extent40_body(place) + pos;	ptr_hint = (ptr_hint_t *)hint->specific;	for (i = pos; i < pos + hint->count;	     i++, ptr_hint++, extent++)	{		et40_set_start(extent, ptr_hint->start);		et40_set_width(extent, ptr_hint->width);	}	place_mkdirty(place);	return hint->count;}/* Estmates how many bytes is needed to insert @hint->count extent units to   passed @place. */static errno_t extent40_prep_insert(reiser4_place_t *place,				    trans_hint_t *hint){	aal_assert("umka-2426", place != NULL);	aal_assert("umka-2427", hint != NULL);	hint->len = hint->count * sizeof(extent40_t);	return 0;}/* Inserts one or more extent units to @place */static int64_t extent40_insert_units(reiser4_place_t *place,				     trans_hint_t *hint){	aal_assert("umka-2429", hint != NULL);	aal_assert("umka-2428", place != NULL);	if (place->pos.unit == MAX_UINT32)		place->pos.unit = 0;	/* Expanding extent item at @place */	extent40_expand(place, place->pos.unit,			hint->count);		/* Updating @count units at @place */	return extent40_update_units(place, hint);}static int64_t extent40_alloc_block(reiser4_place_t *place,				    aal_hash_table_t *blocks,				    uint64_t ins_offset, 				    uint64_t count) {	reiser4_key_t *ins_key, key;	aal_device_t *device;	aal_block_t *block;	uint64_t offset, bytes;	uint32_t blksize;	errno_t res;	device = extent40_device(place);	blksize = place_blksize(place);	/* Get offset aligned to the blksize. */	offset = (ins_offset - (ins_offset & (blksize - 1)));	count = (ins_offset + count + blksize - 1) / blksize * blksize - offset;	/* Prepare the key of the new allocated block. */	aal_memcpy(&key, &place->key, sizeof(key));	bytes = count;		if ((res = extent40_core->tree_ops.dec_free(place->node->tree, 						    count / blksize)))	{		return res;	}		for (; count > 0; count -= blksize, offset += blksize) {		/* Update @key offset. */		objcall(&key, set_offset, offset);				/* Calculating size to be written this time. */		if (!(block = aal_block_alloc(device, blksize, 0)))			return -ENOMEM;		if (!(ins_key = aal_calloc(sizeof(*ins_key), 0)))			return -ENOMEM;		aal_memcpy(ins_key, &key, sizeof(key));		aal_hash_table_insert(blocks, ins_key, block);	}			return bytes;}/* Obtain the block from the block hash table by the @key. */static aal_block_t *extent40_load_block(reiser4_place_t *place,					aal_hash_table_t *blocks,					reiser4_key_t *key,					blk_t start, blk_t off){	reiser4_key_t *ins_key;	aal_device_t *device;	aal_block_t *block;	uint32_t blksize;		device = extent40_device(place);	blksize = place_blksize(place);	/* Obtain the block from the block hash table. */	if ((block = aal_hash_table_lookup(blocks, key)))		return block;	if (start == EXTENT_UNALLOC_UNIT) {		aal_error("Block (%llu), item (%u): "			  "Unallocated extent unit without attached "			  "block detected.", place_blknr(place), 			  place->pos.item);		return NULL;	}		/* Loading data block. */	if (!(block = aal_block_load(device, blksize, start + off))) {		aal_error("Can't read block %llu. %s.", 			  start + off, device->error);		return NULL;	}	if (!(ins_key = aal_calloc(sizeof(*ins_key), 0)))		goto error_free_block;	aal_memcpy(ins_key, key, sizeof(*key));	/* Updating block in data cache. */	aal_hash_table_insert(blocks, ins_key, block);	return block;	 error_free_block:	aal_block_free(block);	return NULL;}/* Estimates extent write operation */static errno_t extent40_prep_write(reiser4_place_t *place, trans_hint_t *hint) {	reiser4_key_t key;	extent40_t *extent;	uint64_t unit_size;	uint64_t uni_off;	uint64_t ins_off;	uint64_t max_off;	uint64_t start;	int64_t count;	int64_t size;	uint32_t unit_pos;	uint32_t blksize;	uint32_t units;	aal_assert("umka-1836", hint != NULL);	aal_assert("umka-2425", place != NULL);	hint->len = 0;	hint->overhead = 0;	hint->insert_flags = 0;	unit_pos = place->pos.unit;	units = place->pos.unit == MAX_UINT32 ? 0 : extent40_units(place);	/* Set maxkey as the start key of the operation. The amount of bytes 	   handled will be added later. */	aal_memcpy(&hint->maxkey, &hint->offset, sizeof(hint->maxkey));	if (place->pos.unit == MAX_UINT32 || unit_pos == units) {		/* Inserting a new item or appending units. */		/* Set maxkey as the limit of the operation. */		max_off = objcall(&hint->maxkey, get_offset);		max_off += hint->count;		objcall(&hint->maxkey, set_offset, max_off);		if (place->pos.unit != MAX_UINT32) {			uint64_t width;			/* If new data could be attached to the end of existent,			   no new unit is needed. It is possible if we write data 			   over not allocated unit or hole over the hole. */			extent = extent40_body(place) + units - 1;			start = et40_get_start(extent);			width = et40_get_width(extent);						if ((start == EXTENT_UNALLOC_UNIT && hint->specific) ||			    (start == EXTENT_HOLE_UNIT && !hint->specific))			{				/* New unit is merged with the last one. */				hint->insert_flags |= ET40_JOIN;			} else {				/* Cannot merge with the last unit. */				hint->len += sizeof(extent40_t);			}		} else {			/* New item, 1 unit is allocated. */			hint->len += sizeof(extent40_t);		}	} else {		/* Writing inside item. */		extent40_fetch_key(place, &key);		blksize = place_blksize(place);		/* Getting maximal real key, it limits the amount of 		   data being written at once. */		uni_off = objcall(&key, get_offset);		ins_off = objcall(&hint->offset, get_offset);				aal_assert("vpf-1697", uni_off <= ins_off);		extent = extent40_body(place) + unit_pos;		/* This loop checks if we insert some data inside extent and we		   should take into account possible holes. */		for (count = hint->count; count > 0 && unit_pos < units;		     count -= size, unit_pos++, extent++,		     ins_off += size, uni_off += unit_size)		{			/* If some space is already required for the previous 			   units, handle only it, unit to avoid problems with 			   splitting units on tree expand. */			if (hint->len)				break;			start = et40_get_start(extent);			unit_size = et40_get_width(extent) * blksize;			size = unit_size - (ins_off - uni_off);			if (size > count)				size = count;			/* New unit needs to be allocated if data are written			   to a hole and not the whole hole is overwritten, in 			   other words it needs to be splitted, */			if (start == EXTENT_HOLE_UNIT && hint->specific) {				/* At least one block is left in the hole. */				if (ins_off >= uni_off + blksize)					hint->len += sizeof(extent40_t);				/* At least one block is left in the hole. */				if (ins_off + size + blksize <= 				    uni_off + unit_size)				{					hint->len += sizeof(extent40_t);				}				/* If we already overwrite some units, do 				   not require space, just overwrite them 				   -- tree_expand may split this unit off */				if (hint->len && unit_pos != place->pos.unit) {					hint->len = 0;					break;				}			}		}		objcall(&hint->maxkey, set_offset, ins_off);		hint->insert_flags |= ET40_OVERWRITE;	}	return 0;}/* Writes data to extent. */static int64_t extent40_write_units(reiser4_place_t *place, trans_hint_t *hint) {	aal_device_t *device;	aal_block_t *block;	extent40_t *extent;

⌨️ 快捷键说明

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