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

📄 dir40.c

📁 reiser4progs ReiserFS V4 ReiserFs官方已经关闭 这个是1.0.6 2006-02-22发布的 给需要的朋友
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2001-2005 by Hans Reiser, licensing governed by   reiser4progs/COPYING.      dir40.c -- reiser4 directory object plugin. */#ifndef ENABLE_MINIMAL#  include <unistd.h>#endif#include "dir40.h"#include "dir40_repair.h"/* Return current position in directory into passed @offset. */static errno_t dir40_telldir(reiser4_object_t *dir,			     reiser4_key_t *position){	aal_assert("umka-1985", dir != NULL);	aal_assert("umka-1986", position != NULL);	/* Getting current dir key and adjust. */	aal_memcpy(position, &dir->position, sizeof(*position));#ifndef ENABLE_MINIMAL	/* Adjust is offset inside collided keys arrays and needed for	   positioning right in such a case. In normal case it is zero. */	position->adjust = dir->position.adjust;#endif		return 0;}/* Positioning inside directory by passed @position key. Normally, user should use   key got from telldir() function. But, this is possible to generate directory   key by himself and pass here. */static errno_t dir40_seekdir(reiser4_object_t *dir,			     reiser4_key_t *position){	aal_assert("umka-1983", dir != NULL);	aal_assert("umka-1984", position != NULL);	/* Set directory position to the given one. */	aal_memcpy(&dir->position, position, sizeof(*position));	return 0;}/* Resets current direntry position to zero. */errno_t dir40_reset(reiser4_object_t *dir) {	aal_assert("umka-864", dir != NULL);		/* Preparing key of the first entry in directory and set directory	   adjust to zero. */#ifndef ENABLE_MINIMAL	dir->position.adjust = 0;#endif	/* Building key itself. */	plugcall(dir->info.object.plug, build_hashed, &dir->position,		  reiser4_pshash(dir), reiser4_psfibre(dir), 		  objcall(&dir->info.object, get_locality),		  objcall(&dir->info.object, get_objectid), ".");	return 0;}/* Fetches current unit to passed @entry */errno_t dir40_fetch(reiser4_object_t *dir, entry_hint_t *entry) {	trans_hint_t hint;	aal_memset(&hint, 0, sizeof(hint));	hint.count = 1;	hint.specific = entry;	hint.shift_flags = SF_DEFAULT;	/* Reading entry to passed @entry */	if (objcall(&dir->body, object->fetch_units, &hint) != 1)		return -EIO;		/* Copying entry place. */	aal_memcpy(&entry->place, &dir->body,		   sizeof(reiser4_place_t));	return 0;}#ifndef ENABLE_MINIMALstatic void dir40_entry_type(entry_hint_t *entry) {	entry->type = ET_NAME;	if (aal_strlen(entry->name) == 1 &&	    !aal_strncmp(entry->name, ".", 1))	{		entry->type = ET_SPCL;	}	if (aal_strlen(entry->name) == 2 &&	    !aal_strncmp(entry->name, "..",2))	{		entry->type = ET_SPCL;	}}#else#define dir40_entry_type(entry) do{;} while(0)#endiferrno_t dir40_entry_comp(reiser4_object_t *dir, void *data) {	entry_hint_t entry;	reiser4_key_t *key;	aal_assert("vpf-1834", dir != NULL);	if (!dir->body.plug)		return -EINVAL;#ifndef EINVAL		if (dir->body.plug->id.group != DIR_ITEM)		return -ESTRUCT;#endif	if (dir40_fetch(dir, &entry))		return -EIO;	if (!data) {		key = &dir->position;	} else {		key = (reiser4_key_t *)data;	}		/* If greater key is reached, return PRESENT. */	return objcall(&entry.offset, compfull, key) ? 1 : 0;}/* Reads one current directory entry to passed @entry hint. Returns count of   read entries, zero for the case directory is over and nagtive values fopr   errors. */static int32_t dir40_readdir(reiser4_object_t *dir, 			     entry_hint_t *entry){	uint32_t units;	errno_t res;	aal_assert("umka-845", entry != NULL);	aal_assert("umka-844", dir != NULL);	/* Getting place of current unit */	if ((res = obj40_update_body(dir, dir40_entry_comp)) != PRESENT)		return res == ABSENT ? 0 : res;	/* Reading next entry */	if ((res = dir40_fetch(dir, entry)))		return res;	/* Setting up the entry type. It is essential for fsck to know what is	   the NAME -- that needs to be traversed semantically to be recovered	   completely -- and what is not -- that needs some other special	   actions, e.g. check_attach for ".." (and even "..." if it is needed	   one day), etc. */	dir40_entry_type(entry);	units = objcall(&dir->body, balance->units);	/* Getting next entry in odrer to set up @dir->position correctly. */	if (++dir->body.pos.unit >= units) {		/* Switching to the next directory item */		if ((res = obj40_next_item(dir)) < 0)			return res;		if (res == ABSENT) {			uint64_t offset;						/* Set offset to non-existent value. */			offset = objcall(&dir->position, get_offset);			objcall(&dir->position, set_offset, offset + 1);		}	} else {		/* There is no need to switch */		res = 1;	}	if (res == 1) {		entry_hint_t temp;				if ((res = dir40_fetch(dir, &temp)))			return res;#ifndef ENABLE_MINIMAL		/* Taking care about adjust */		if (!objcall(&temp.offset, compfull, &dir->position))			temp.offset.adjust = dir->position.adjust + 1;		else			temp.offset.adjust = 0;#endif		dir40_seekdir(dir, &temp.offset);	}		return 1;}/* Makes lookup inside directory. This is needed to be used in add_entry() for   two reasons: for make sure, that passed entry does not exists and to use   lookup result for consequent insert. */static lookup_t dir40_search(reiser4_object_t *dir, char *name,			     lookup_bias_t bias, entry_hint_t *entry){	lookup_t res;#ifndef ENABLE_MINIMAL	coll_hint_t hint;	coll_func_t func;#endif	aal_assert("umka-1118", name != NULL);	aal_assert("umka-1117", dir != NULL);	/* Preparing key to be used for lookup. It is generating from the	   directory oid, locality and name by menas of using hash plugin. */	plugcall(dir->info.object.plug, build_hashed, &dir->body.key,		 reiser4_pshash(dir), reiser4_psfibre(dir),		 objcall(&dir->info.object, get_locality),		 objcall(&dir->info.object, get_objectid), name);#ifndef ENABLE_MINIMAL	hint.specific = name;	hint.type = DIR_ITEM;	func = obj40_core->tree_ops.collision;#endif		if ((res = obj40_find_item(dir, &dir->body.key, bias, #ifndef ENABLE_MINIMAL				   func, &hint,#else				   NULL, NULL,#endif				   &dir->body)) < 0)	{		return res;	}	if (entry) {		aal_memset(entry, 0, sizeof(*entry));				aal_memcpy(&entry->place, &dir->body,			   sizeof(reiser4_place_t));		aal_memcpy(&entry->offset, &dir->body.key,			   sizeof(reiser4_key_t));		if (res == PRESENT) {			if (dir40_fetch(dir, entry))				return -EIO;			dir40_entry_type(entry);		}	}	return res;}/* Makes lookup inside @dir by passed @name. Saves found entry in passed   @entry hint. */lookup_t dir40_lookup(reiser4_object_t *dir,		      char *name, entry_hint_t *entry) {	return dir40_search(dir, name, FIND_EXACT, entry);}#ifndef ENABLE_MINIMAL/* Creates dir40 instance. Creates its stat data item, and body item with one   "." unit. Yet another unit ".." will be inserted latter, then directiry will   be attached to a parent object. */static errno_t dir40_create(reiser4_object_t *dir, object_hint_t *hint) {	trans_hint_t body_hint;	entry_hint_t entry;	reiser4_key_t *key;	uint32_t mode;	errno_t res;    	aal_assert("vpf-1816",  dir != NULL);	aal_assert("vpf-1095",  dir->info.tree != NULL);	aal_memset(&body_hint, 0, sizeof(body_hint));		/* Initializing direntry item hint. This should be done before the stat	   data item hint, because we will need size of direntry item during	   stat data initialization. */   	body_hint.count = 1;	body_hint.plug = reiser4_psdiren(dir);		key = &dir->info.object;	plugcall(key->plug, build_hashed, &body_hint.offset, 		 reiser4_pshash(dir), reiser4_psfibre(dir),		 objcall(&dir->info.object, get_locality),		 objcall(&dir->info.object, get_objectid), ".");	/* Preparing hint for the empty directory. It consists only "." for	   unlinked directories. */	aal_strncpy(entry.name, ".", 1);	/* Initializing entry stat data key. */	aal_memcpy(&entry.object, key, sizeof(*key));	/* Initializing entry hash key. */	aal_memcpy(&entry.offset, &body_hint.offset, sizeof(entry.offset));	body_hint.specific = &entry;	body_hint.shift_flags = SF_DEFAULT;		dir40_reset(dir);	        /* Looking for place to insert directory body */	switch (obj40_find_item(dir, &body_hint.offset,				FIND_CONV, NULL, NULL, &dir->body))	{	case ABSENT:		/* Inserting the direntry body item into the tree. */		if ((res = obj40_insert(dir, &dir->body,					&body_hint, LEAF_LEVEL)) < 0)		{			return res;		}				break;	default:		return -EIO;	}		mode = (hint ? hint->mode : 0) | S_IFDIR | 0755;		/* Create stat data item. */	if ((res = obj40_create_stat(dir, 1, body_hint.len, 				     0, 1, mode, NULL))) 

⌨️ 快捷键说明

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