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

📄 item_ops.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (le32_to_cpu(key->u.k_offset_v1.k_offset) == DOT_OFFSET)		return 0;	return 1;}static void direntry_print_item(struct item_head *ih, char *item){	int i;	int namelen;	struct reiserfs_de_head *deh;	char *name;	static char namebuf[80];	printk("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name",	       "Key of pointed object", "Hash", "Gen number", "Status");	deh = (struct reiserfs_de_head *)item;	for (i = 0; i < I_ENTRY_COUNT(ih); i++, deh++) {		namelen =		    (i ? (deh_location(deh - 1)) : ih_item_len(ih)) -		    deh_location(deh);		name = item + deh_location(deh);		if (name[namelen - 1] == 0)			namelen = strlen(name);		namebuf[0] = '"';		if (namelen > sizeof(namebuf) - 3) {			strncpy(namebuf + 1, name, sizeof(namebuf) - 3);			namebuf[sizeof(namebuf) - 2] = '"';			namebuf[sizeof(namebuf) - 1] = 0;		} else {			memcpy(namebuf + 1, name, namelen);			namebuf[namelen + 1] = '"';			namebuf[namelen + 2] = 0;		}		printk("%d:  %-15s%-15d%-15d%-15Ld%-15Ld(%s)\n",		       i, namebuf,		       deh_dir_id(deh), deh_objectid(deh),		       GET_HASH_VALUE(deh_offset(deh)),		       GET_GENERATION_NUMBER((deh_offset(deh))),		       (de_hidden(deh)) ? "HIDDEN" : "VISIBLE");	}}static void direntry_check_item(struct item_head *ih, char *item){	int i;	struct reiserfs_de_head *deh;	// FIXME: type something here!	deh = (struct reiserfs_de_head *)item;	for (i = 0; i < I_ENTRY_COUNT(ih); i++, deh++) {		;	}}#define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1/* * function returns old entry number in directory item in real node * using new entry number in virtual item in virtual node */static inline int old_entry_num(int is_affected, int virtual_entry_num,				int pos_in_item, int mode){	if (mode == M_INSERT || mode == M_DELETE)		return virtual_entry_num;	if (!is_affected)		/* cut or paste is applied to another item */		return virtual_entry_num;	if (virtual_entry_num < pos_in_item)		return virtual_entry_num;	if (mode == M_CUT)		return virtual_entry_num + 1;	RFALSE(mode != M_PASTE || virtual_entry_num == 0,	       "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'",	       mode);	return virtual_entry_num - 1;}/* Create an array of sizes of directory entries for virtual   item. Return space used by an item. FIXME: no control over   consuming of space used by this item handler */static int direntry_create_vi(struct virtual_node *vn,			      struct virtual_item *vi,			      int is_affected, int insert_size){	struct direntry_uarea *dir_u = vi->vi_uarea;	int i, j;	int size = sizeof(struct direntry_uarea);	struct reiserfs_de_head *deh;	vi->vi_index = TYPE_DIRENTRY;	BUG_ON(!(vi->vi_ih) || !vi->vi_item);	dir_u->flags = 0;	if (le_ih_k_offset(vi->vi_ih) == DOT_OFFSET)		dir_u->flags |= DIRENTRY_VI_FIRST_DIRENTRY_ITEM;	deh = (struct reiserfs_de_head *)(vi->vi_item);	/* virtual directory item have this amount of entry after */	dir_u->entry_count = ih_entry_count(vi->vi_ih) +	    ((is_affected) ? ((vn->vn_mode == M_CUT) ? -1 :			      (vn->vn_mode == M_PASTE ? 1 : 0)) : 0);	for (i = 0; i < dir_u->entry_count; i++) {		j = old_entry_num(is_affected, i, vn->vn_pos_in_item,				  vn->vn_mode);		dir_u->entry_sizes[i] =		    (j ? deh_location(&(deh[j - 1])) : ih_item_len(vi->vi_ih)) -		    deh_location(&(deh[j])) + DEH_SIZE;	}	size += (dir_u->entry_count * sizeof(short));	/* set size of pasted entry */	if (is_affected && vn->vn_mode == M_PASTE)		dir_u->entry_sizes[vn->vn_pos_in_item] = insert_size;#ifdef CONFIG_REISERFS_CHECK	/* compare total size of entries with item length */	{		int k, l;		l = 0;		for (k = 0; k < dir_u->entry_count; k++)			l += dir_u->entry_sizes[k];		if (l + IH_SIZE != vi->vi_item_len +		    ((is_affected		      && (vn->vn_mode == M_PASTE			  || vn->vn_mode == M_CUT)) ? insert_size : 0)) {			reiserfs_panic(NULL,				       "vs-8025: set_entry_sizes: (mode==%c, insert_size==%d), invalid length of directory item",				       vn->vn_mode, insert_size);		}	}#endif	return size;}//// return number of entries which may fit into specified amount of// free space, or -1 if free space is not enough even for 1 entry//static int direntry_check_left(struct virtual_item *vi, int free,			       int start_skip, int end_skip){	int i;	int entries = 0;	struct direntry_uarea *dir_u = vi->vi_uarea;	for (i = start_skip; i < dir_u->entry_count - end_skip; i++) {		if (dir_u->entry_sizes[i] > free)			/* i-th entry doesn't fit into the remaining free space */			break;		free -= dir_u->entry_sizes[i];		entries++;	}	if (entries == dir_u->entry_count) {		reiserfs_panic(NULL, "free space %d, entry_count %d\n", free,			       dir_u->entry_count);	}	/* "." and ".." can not be separated from each other */	if (start_skip == 0 && (dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)	    && entries < 2)		entries = 0;	return entries ? : -1;}static int direntry_check_right(struct virtual_item *vi, int free){	int i;	int entries = 0;	struct direntry_uarea *dir_u = vi->vi_uarea;	for (i = dir_u->entry_count - 1; i >= 0; i--) {		if (dir_u->entry_sizes[i] > free)			/* i-th entry doesn't fit into the remaining free space */			break;		free -= dir_u->entry_sizes[i];		entries++;	}	BUG_ON(entries == dir_u->entry_count);	/* "." and ".." can not be separated from each other */	if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)	    && entries > dir_u->entry_count - 2)		entries = dir_u->entry_count - 2;	return entries ? : -1;}/* sum of entry sizes between from-th and to-th entries including both edges */static int direntry_part_size(struct virtual_item *vi, int first, int count){	int i, retval;	int from, to;	struct direntry_uarea *dir_u = vi->vi_uarea;	retval = 0;	if (first == 0)		from = 0;	else		from = dir_u->entry_count - count;	to = from + count - 1;	for (i = from; i <= to; i++)		retval += dir_u->entry_sizes[i];	return retval;}static int direntry_unit_num(struct virtual_item *vi){	struct direntry_uarea *dir_u = vi->vi_uarea;	return dir_u->entry_count;}static void direntry_print_vi(struct virtual_item *vi){	int i;	struct direntry_uarea *dir_u = vi->vi_uarea;	reiserfs_warning(NULL, "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",			 vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);	printk("%d entries: ", dir_u->entry_count);	for (i = 0; i < dir_u->entry_count; i++)		printk("%d ", dir_u->entry_sizes[i]);	printk("\n");}static struct item_operations direntry_ops = {	.bytes_number = direntry_bytes_number,	.decrement_key = direntry_decrement_key,	.is_left_mergeable = direntry_is_left_mergeable,	.print_item = direntry_print_item,	.check_item = direntry_check_item,	.create_vi = direntry_create_vi,	.check_left = direntry_check_left,	.check_right = direntry_check_right,	.part_size = direntry_part_size,	.unit_num = direntry_unit_num,	.print_vi = direntry_print_vi};//////////////////////////////////////////////////////////////////////////////// Error catching functions to catch errors caused by incorrect item types.//static int errcatch_bytes_number(struct item_head *ih, int block_size){	reiserfs_warning(NULL,			 "green-16001: Invalid item type observed, run fsck ASAP");	return 0;}static void errcatch_decrement_key(struct cpu_key *key){	reiserfs_warning(NULL,			 "green-16002: Invalid item type observed, run fsck ASAP");}static int errcatch_is_left_mergeable(struct reiserfs_key *key,				      unsigned long bsize){	reiserfs_warning(NULL,			 "green-16003: Invalid item type observed, run fsck ASAP");	return 0;}static void errcatch_print_item(struct item_head *ih, char *item){	reiserfs_warning(NULL,			 "green-16004: Invalid item type observed, run fsck ASAP");}static void errcatch_check_item(struct item_head *ih, char *item){	reiserfs_warning(NULL,			 "green-16005: Invalid item type observed, run fsck ASAP");}static int errcatch_create_vi(struct virtual_node *vn,			      struct virtual_item *vi,			      int is_affected, int insert_size){	reiserfs_warning(NULL,			 "green-16006: Invalid item type observed, run fsck ASAP");	return 0;		// We might return -1 here as well, but it won't help as create_virtual_node() from where	// this operation is called from is of return type void.}static int errcatch_check_left(struct virtual_item *vi, int free,			       int start_skip, int end_skip){	reiserfs_warning(NULL,			 "green-16007: Invalid item type observed, run fsck ASAP");	return -1;}static int errcatch_check_right(struct virtual_item *vi, int free){	reiserfs_warning(NULL,			 "green-16008: Invalid item type observed, run fsck ASAP");	return -1;}static int errcatch_part_size(struct virtual_item *vi, int first, int count){	reiserfs_warning(NULL,			 "green-16009: Invalid item type observed, run fsck ASAP");	return 0;}static int errcatch_unit_num(struct virtual_item *vi){	reiserfs_warning(NULL,			 "green-16010: Invalid item type observed, run fsck ASAP");	return 0;}static void errcatch_print_vi(struct virtual_item *vi){	reiserfs_warning(NULL,			 "green-16011: Invalid item type observed, run fsck ASAP");}static struct item_operations errcatch_ops = {	errcatch_bytes_number,	errcatch_decrement_key,	errcatch_is_left_mergeable,	errcatch_print_item,	errcatch_check_item,	errcatch_create_vi,	errcatch_check_left,	errcatch_check_right,	errcatch_part_size,	errcatch_unit_num,	errcatch_print_vi};//////////////////////////////////////////////////////////////////////////////////#if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)#error Item types must use disk-format assigned values.#endifstruct item_operations *item_ops[TYPE_ANY + 1] = {	&stat_data_ops,	&indirect_ops,	&direct_ops,	&direntry_ops,	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	&errcatch_ops		/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */};

⌨️ 快捷键说明

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