xref: /OK3568_Linux_fs/kernel/fs/reiserfs/item_ops.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3*4882a593Smuzhiyun  */
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/time.h>
6*4882a593Smuzhiyun #include "reiserfs.h"
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  * this contains item handlers for old item types: sd, direct,
10*4882a593Smuzhiyun  * indirect, directory
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun  * and where are the comments? how about saying where we can find an
15*4882a593Smuzhiyun  * explanation of each item handler method? -Hans
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /* stat data functions */
sd_bytes_number(struct item_head * ih,int block_size)19*4882a593Smuzhiyun static int sd_bytes_number(struct item_head *ih, int block_size)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	return 0;
22*4882a593Smuzhiyun }
23*4882a593Smuzhiyun 
sd_decrement_key(struct cpu_key * key)24*4882a593Smuzhiyun static void sd_decrement_key(struct cpu_key *key)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	key->on_disk_key.k_objectid--;
27*4882a593Smuzhiyun 	set_cpu_key_k_type(key, TYPE_ANY);
28*4882a593Smuzhiyun 	set_cpu_key_k_offset(key, (loff_t)(~0ULL >> 1));
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun 
sd_is_left_mergeable(struct reiserfs_key * key,unsigned long bsize)31*4882a593Smuzhiyun static int sd_is_left_mergeable(struct reiserfs_key *key, unsigned long bsize)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	return 0;
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun 
sd_print_item(struct item_head * ih,char * item)36*4882a593Smuzhiyun static void sd_print_item(struct item_head *ih, char *item)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun 	printk("\tmode | size | nlinks | first direct | mtime\n");
39*4882a593Smuzhiyun 	if (stat_data_v1(ih)) {
40*4882a593Smuzhiyun 		struct stat_data_v1 *sd = (struct stat_data_v1 *)item;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 		printk("\t0%-6o | %6u | %2u | %d | %u\n", sd_v1_mode(sd),
43*4882a593Smuzhiyun 		       sd_v1_size(sd), sd_v1_nlink(sd),
44*4882a593Smuzhiyun 		       sd_v1_first_direct_byte(sd),
45*4882a593Smuzhiyun 		       sd_v1_mtime(sd));
46*4882a593Smuzhiyun 	} else {
47*4882a593Smuzhiyun 		struct stat_data *sd = (struct stat_data *)item;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 		printk("\t0%-6o | %6llu | %2u | %d | %u\n", sd_v2_mode(sd),
50*4882a593Smuzhiyun 		       (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
51*4882a593Smuzhiyun 		       sd_v2_rdev(sd), sd_v2_mtime(sd));
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
sd_check_item(struct item_head * ih,char * item)55*4882a593Smuzhiyun static void sd_check_item(struct item_head *ih, char *item)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	/* unused */
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
sd_create_vi(struct virtual_node * vn,struct virtual_item * vi,int is_affected,int insert_size)60*4882a593Smuzhiyun static int sd_create_vi(struct virtual_node *vn,
61*4882a593Smuzhiyun 			struct virtual_item *vi,
62*4882a593Smuzhiyun 			int is_affected, int insert_size)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	vi->vi_index = TYPE_STAT_DATA;
65*4882a593Smuzhiyun 	return 0;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun 
sd_check_left(struct virtual_item * vi,int free,int start_skip,int end_skip)68*4882a593Smuzhiyun static int sd_check_left(struct virtual_item *vi, int free,
69*4882a593Smuzhiyun 			 int start_skip, int end_skip)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	BUG_ON(start_skip || end_skip);
72*4882a593Smuzhiyun 	return -1;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
sd_check_right(struct virtual_item * vi,int free)75*4882a593Smuzhiyun static int sd_check_right(struct virtual_item *vi, int free)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun 	return -1;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
sd_part_size(struct virtual_item * vi,int first,int count)80*4882a593Smuzhiyun static int sd_part_size(struct virtual_item *vi, int first, int count)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	BUG_ON(count);
83*4882a593Smuzhiyun 	return 0;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
sd_unit_num(struct virtual_item * vi)86*4882a593Smuzhiyun static int sd_unit_num(struct virtual_item *vi)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	return vi->vi_item_len - IH_SIZE;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
sd_print_vi(struct virtual_item * vi)91*4882a593Smuzhiyun static void sd_print_vi(struct virtual_item *vi)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun 	reiserfs_warning(NULL, "reiserfs-16100",
94*4882a593Smuzhiyun 			 "STATDATA, index %d, type 0x%x, %h",
95*4882a593Smuzhiyun 			 vi->vi_index, vi->vi_type, vi->vi_ih);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun static struct item_operations stat_data_ops = {
99*4882a593Smuzhiyun 	.bytes_number = sd_bytes_number,
100*4882a593Smuzhiyun 	.decrement_key = sd_decrement_key,
101*4882a593Smuzhiyun 	.is_left_mergeable = sd_is_left_mergeable,
102*4882a593Smuzhiyun 	.print_item = sd_print_item,
103*4882a593Smuzhiyun 	.check_item = sd_check_item,
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	.create_vi = sd_create_vi,
106*4882a593Smuzhiyun 	.check_left = sd_check_left,
107*4882a593Smuzhiyun 	.check_right = sd_check_right,
108*4882a593Smuzhiyun 	.part_size = sd_part_size,
109*4882a593Smuzhiyun 	.unit_num = sd_unit_num,
110*4882a593Smuzhiyun 	.print_vi = sd_print_vi
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun /* direct item functions */
direct_bytes_number(struct item_head * ih,int block_size)114*4882a593Smuzhiyun static int direct_bytes_number(struct item_head *ih, int block_size)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	return ih_item_len(ih);
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun /* FIXME: this should probably switch to indirect as well */
direct_decrement_key(struct cpu_key * key)120*4882a593Smuzhiyun static void direct_decrement_key(struct cpu_key *key)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	cpu_key_k_offset_dec(key);
123*4882a593Smuzhiyun 	if (cpu_key_k_offset(key) == 0)
124*4882a593Smuzhiyun 		set_cpu_key_k_type(key, TYPE_STAT_DATA);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
direct_is_left_mergeable(struct reiserfs_key * key,unsigned long bsize)127*4882a593Smuzhiyun static int direct_is_left_mergeable(struct reiserfs_key *key,
128*4882a593Smuzhiyun 				    unsigned long bsize)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	int version = le_key_version(key);
131*4882a593Smuzhiyun 	return ((le_key_k_offset(version, key) & (bsize - 1)) != 1);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun 
direct_print_item(struct item_head * ih,char * item)134*4882a593Smuzhiyun static void direct_print_item(struct item_head *ih, char *item)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	int j = 0;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /*    return; */
139*4882a593Smuzhiyun 	printk("\"");
140*4882a593Smuzhiyun 	while (j < ih_item_len(ih))
141*4882a593Smuzhiyun 		printk("%c", item[j++]);
142*4882a593Smuzhiyun 	printk("\"\n");
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
direct_check_item(struct item_head * ih,char * item)145*4882a593Smuzhiyun static void direct_check_item(struct item_head *ih, char *item)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	/* unused */
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
direct_create_vi(struct virtual_node * vn,struct virtual_item * vi,int is_affected,int insert_size)150*4882a593Smuzhiyun static int direct_create_vi(struct virtual_node *vn,
151*4882a593Smuzhiyun 			    struct virtual_item *vi,
152*4882a593Smuzhiyun 			    int is_affected, int insert_size)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	vi->vi_index = TYPE_DIRECT;
155*4882a593Smuzhiyun 	return 0;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
direct_check_left(struct virtual_item * vi,int free,int start_skip,int end_skip)158*4882a593Smuzhiyun static int direct_check_left(struct virtual_item *vi, int free,
159*4882a593Smuzhiyun 			     int start_skip, int end_skip)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	int bytes;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	bytes = free - free % 8;
164*4882a593Smuzhiyun 	return bytes ? : -1;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
direct_check_right(struct virtual_item * vi,int free)167*4882a593Smuzhiyun static int direct_check_right(struct virtual_item *vi, int free)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun 	return direct_check_left(vi, free, 0, 0);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun 
direct_part_size(struct virtual_item * vi,int first,int count)172*4882a593Smuzhiyun static int direct_part_size(struct virtual_item *vi, int first, int count)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	return count;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
direct_unit_num(struct virtual_item * vi)177*4882a593Smuzhiyun static int direct_unit_num(struct virtual_item *vi)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	return vi->vi_item_len - IH_SIZE;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
direct_print_vi(struct virtual_item * vi)182*4882a593Smuzhiyun static void direct_print_vi(struct virtual_item *vi)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	reiserfs_warning(NULL, "reiserfs-16101",
185*4882a593Smuzhiyun 			 "DIRECT, index %d, type 0x%x, %h",
186*4882a593Smuzhiyun 			 vi->vi_index, vi->vi_type, vi->vi_ih);
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun static struct item_operations direct_ops = {
190*4882a593Smuzhiyun 	.bytes_number = direct_bytes_number,
191*4882a593Smuzhiyun 	.decrement_key = direct_decrement_key,
192*4882a593Smuzhiyun 	.is_left_mergeable = direct_is_left_mergeable,
193*4882a593Smuzhiyun 	.print_item = direct_print_item,
194*4882a593Smuzhiyun 	.check_item = direct_check_item,
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	.create_vi = direct_create_vi,
197*4882a593Smuzhiyun 	.check_left = direct_check_left,
198*4882a593Smuzhiyun 	.check_right = direct_check_right,
199*4882a593Smuzhiyun 	.part_size = direct_part_size,
200*4882a593Smuzhiyun 	.unit_num = direct_unit_num,
201*4882a593Smuzhiyun 	.print_vi = direct_print_vi
202*4882a593Smuzhiyun };
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun /* indirect item functions */
indirect_bytes_number(struct item_head * ih,int block_size)205*4882a593Smuzhiyun static int indirect_bytes_number(struct item_head *ih, int block_size)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	return ih_item_len(ih) / UNFM_P_SIZE * block_size;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun /* decrease offset, if it becomes 0, change type to stat data */
indirect_decrement_key(struct cpu_key * key)211*4882a593Smuzhiyun static void indirect_decrement_key(struct cpu_key *key)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	cpu_key_k_offset_dec(key);
214*4882a593Smuzhiyun 	if (cpu_key_k_offset(key) == 0)
215*4882a593Smuzhiyun 		set_cpu_key_k_type(key, TYPE_STAT_DATA);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun /* if it is not first item of the body, then it is mergeable */
indirect_is_left_mergeable(struct reiserfs_key * key,unsigned long bsize)219*4882a593Smuzhiyun static int indirect_is_left_mergeable(struct reiserfs_key *key,
220*4882a593Smuzhiyun 				      unsigned long bsize)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	int version = le_key_version(key);
223*4882a593Smuzhiyun 	return (le_key_k_offset(version, key) != 1);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /* printing of indirect item */
start_new_sequence(__u32 * start,int * len,__u32 new)227*4882a593Smuzhiyun static void start_new_sequence(__u32 * start, int *len, __u32 new)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun 	*start = new;
230*4882a593Smuzhiyun 	*len = 1;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
sequence_finished(__u32 start,int * len,__u32 new)233*4882a593Smuzhiyun static int sequence_finished(__u32 start, int *len, __u32 new)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	if (start == INT_MAX)
236*4882a593Smuzhiyun 		return 1;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	if (start == 0 && new == 0) {
239*4882a593Smuzhiyun 		(*len)++;
240*4882a593Smuzhiyun 		return 0;
241*4882a593Smuzhiyun 	}
242*4882a593Smuzhiyun 	if (start != 0 && (start + *len) == new) {
243*4882a593Smuzhiyun 		(*len)++;
244*4882a593Smuzhiyun 		return 0;
245*4882a593Smuzhiyun 	}
246*4882a593Smuzhiyun 	return 1;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
print_sequence(__u32 start,int len)249*4882a593Smuzhiyun static void print_sequence(__u32 start, int len)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun 	if (start == INT_MAX)
252*4882a593Smuzhiyun 		return;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	if (len == 1)
255*4882a593Smuzhiyun 		printk(" %d", start);
256*4882a593Smuzhiyun 	else
257*4882a593Smuzhiyun 		printk(" %d(%d)", start, len);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
indirect_print_item(struct item_head * ih,char * item)260*4882a593Smuzhiyun static void indirect_print_item(struct item_head *ih, char *item)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	int j;
263*4882a593Smuzhiyun 	__le32 *unp;
264*4882a593Smuzhiyun 	__u32 prev = INT_MAX;
265*4882a593Smuzhiyun 	int num = 0;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	unp = (__le32 *) item;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	if (ih_item_len(ih) % UNFM_P_SIZE)
270*4882a593Smuzhiyun 		reiserfs_warning(NULL, "reiserfs-16102", "invalid item len");
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	printk("%d pointers\n[ ", (int)I_UNFM_NUM(ih));
273*4882a593Smuzhiyun 	for (j = 0; j < I_UNFM_NUM(ih); j++) {
274*4882a593Smuzhiyun 		if (sequence_finished(prev, &num, get_block_num(unp, j))) {
275*4882a593Smuzhiyun 			print_sequence(prev, num);
276*4882a593Smuzhiyun 			start_new_sequence(&prev, &num, get_block_num(unp, j));
277*4882a593Smuzhiyun 		}
278*4882a593Smuzhiyun 	}
279*4882a593Smuzhiyun 	print_sequence(prev, num);
280*4882a593Smuzhiyun 	printk("]\n");
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
indirect_check_item(struct item_head * ih,char * item)283*4882a593Smuzhiyun static void indirect_check_item(struct item_head *ih, char *item)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	/* unused */
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun 
indirect_create_vi(struct virtual_node * vn,struct virtual_item * vi,int is_affected,int insert_size)288*4882a593Smuzhiyun static int indirect_create_vi(struct virtual_node *vn,
289*4882a593Smuzhiyun 			      struct virtual_item *vi,
290*4882a593Smuzhiyun 			      int is_affected, int insert_size)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	vi->vi_index = TYPE_INDIRECT;
293*4882a593Smuzhiyun 	return 0;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun 
indirect_check_left(struct virtual_item * vi,int free,int start_skip,int end_skip)296*4882a593Smuzhiyun static int indirect_check_left(struct virtual_item *vi, int free,
297*4882a593Smuzhiyun 			       int start_skip, int end_skip)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun 	int bytes;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	bytes = free - free % UNFM_P_SIZE;
302*4882a593Smuzhiyun 	return bytes ? : -1;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
indirect_check_right(struct virtual_item * vi,int free)305*4882a593Smuzhiyun static int indirect_check_right(struct virtual_item *vi, int free)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	return indirect_check_left(vi, free, 0, 0);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun /*
311*4882a593Smuzhiyun  * return size in bytes of 'units' units. If first == 0 - calculate
312*4882a593Smuzhiyun  * from the head (left), otherwise - from tail (right)
313*4882a593Smuzhiyun  */
indirect_part_size(struct virtual_item * vi,int first,int units)314*4882a593Smuzhiyun static int indirect_part_size(struct virtual_item *vi, int first, int units)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun 	/* unit of indirect item is byte (yet) */
317*4882a593Smuzhiyun 	return units;
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun 
indirect_unit_num(struct virtual_item * vi)320*4882a593Smuzhiyun static int indirect_unit_num(struct virtual_item *vi)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	/* unit of indirect item is byte (yet) */
323*4882a593Smuzhiyun 	return vi->vi_item_len - IH_SIZE;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
indirect_print_vi(struct virtual_item * vi)326*4882a593Smuzhiyun static void indirect_print_vi(struct virtual_item *vi)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	reiserfs_warning(NULL, "reiserfs-16103",
329*4882a593Smuzhiyun 			 "INDIRECT, index %d, type 0x%x, %h",
330*4882a593Smuzhiyun 			 vi->vi_index, vi->vi_type, vi->vi_ih);
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun static struct item_operations indirect_ops = {
334*4882a593Smuzhiyun 	.bytes_number = indirect_bytes_number,
335*4882a593Smuzhiyun 	.decrement_key = indirect_decrement_key,
336*4882a593Smuzhiyun 	.is_left_mergeable = indirect_is_left_mergeable,
337*4882a593Smuzhiyun 	.print_item = indirect_print_item,
338*4882a593Smuzhiyun 	.check_item = indirect_check_item,
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	.create_vi = indirect_create_vi,
341*4882a593Smuzhiyun 	.check_left = indirect_check_left,
342*4882a593Smuzhiyun 	.check_right = indirect_check_right,
343*4882a593Smuzhiyun 	.part_size = indirect_part_size,
344*4882a593Smuzhiyun 	.unit_num = indirect_unit_num,
345*4882a593Smuzhiyun 	.print_vi = indirect_print_vi
346*4882a593Smuzhiyun };
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun /* direntry functions */
direntry_bytes_number(struct item_head * ih,int block_size)349*4882a593Smuzhiyun static int direntry_bytes_number(struct item_head *ih, int block_size)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	reiserfs_warning(NULL, "vs-16090",
352*4882a593Smuzhiyun 			 "bytes number is asked for direntry");
353*4882a593Smuzhiyun 	return 0;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
direntry_decrement_key(struct cpu_key * key)356*4882a593Smuzhiyun static void direntry_decrement_key(struct cpu_key *key)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun 	cpu_key_k_offset_dec(key);
359*4882a593Smuzhiyun 	if (cpu_key_k_offset(key) == 0)
360*4882a593Smuzhiyun 		set_cpu_key_k_type(key, TYPE_STAT_DATA);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun 
direntry_is_left_mergeable(struct reiserfs_key * key,unsigned long bsize)363*4882a593Smuzhiyun static int direntry_is_left_mergeable(struct reiserfs_key *key,
364*4882a593Smuzhiyun 				      unsigned long bsize)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun 	if (le32_to_cpu(key->u.k_offset_v1.k_offset) == DOT_OFFSET)
367*4882a593Smuzhiyun 		return 0;
368*4882a593Smuzhiyun 	return 1;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
direntry_print_item(struct item_head * ih,char * item)372*4882a593Smuzhiyun static void direntry_print_item(struct item_head *ih, char *item)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	int i;
375*4882a593Smuzhiyun 	int namelen;
376*4882a593Smuzhiyun 	struct reiserfs_de_head *deh;
377*4882a593Smuzhiyun 	char *name;
378*4882a593Smuzhiyun 	static char namebuf[80];
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	printk("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name",
381*4882a593Smuzhiyun 	       "Key of pointed object", "Hash", "Gen number", "Status");
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	deh = (struct reiserfs_de_head *)item;
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	for (i = 0; i < ih_entry_count(ih); i++, deh++) {
386*4882a593Smuzhiyun 		namelen =
387*4882a593Smuzhiyun 		    (i ? (deh_location(deh - 1)) : ih_item_len(ih)) -
388*4882a593Smuzhiyun 		    deh_location(deh);
389*4882a593Smuzhiyun 		name = item + deh_location(deh);
390*4882a593Smuzhiyun 		if (name[namelen - 1] == 0)
391*4882a593Smuzhiyun 			namelen = strlen(name);
392*4882a593Smuzhiyun 		namebuf[0] = '"';
393*4882a593Smuzhiyun 		if (namelen > sizeof(namebuf) - 3) {
394*4882a593Smuzhiyun 			strncpy(namebuf + 1, name, sizeof(namebuf) - 3);
395*4882a593Smuzhiyun 			namebuf[sizeof(namebuf) - 2] = '"';
396*4882a593Smuzhiyun 			namebuf[sizeof(namebuf) - 1] = 0;
397*4882a593Smuzhiyun 		} else {
398*4882a593Smuzhiyun 			memcpy(namebuf + 1, name, namelen);
399*4882a593Smuzhiyun 			namebuf[namelen + 1] = '"';
400*4882a593Smuzhiyun 			namebuf[namelen + 2] = 0;
401*4882a593Smuzhiyun 		}
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 		printk("%d:  %-15s%-15d%-15d%-15lld%-15lld(%s)\n",
404*4882a593Smuzhiyun 		       i, namebuf,
405*4882a593Smuzhiyun 		       deh_dir_id(deh), deh_objectid(deh),
406*4882a593Smuzhiyun 		       GET_HASH_VALUE(deh_offset(deh)),
407*4882a593Smuzhiyun 		       GET_GENERATION_NUMBER((deh_offset(deh))),
408*4882a593Smuzhiyun 		       (de_hidden(deh)) ? "HIDDEN" : "VISIBLE");
409*4882a593Smuzhiyun 	}
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun 
direntry_check_item(struct item_head * ih,char * item)412*4882a593Smuzhiyun static void direntry_check_item(struct item_head *ih, char *item)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun 	int i;
415*4882a593Smuzhiyun 	struct reiserfs_de_head *deh;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	/* unused */
418*4882a593Smuzhiyun 	deh = (struct reiserfs_de_head *)item;
419*4882a593Smuzhiyun 	for (i = 0; i < ih_entry_count(ih); i++, deh++) {
420*4882a593Smuzhiyun 		;
421*4882a593Smuzhiyun 	}
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun /*
427*4882a593Smuzhiyun  * function returns old entry number in directory item in real node
428*4882a593Smuzhiyun  * using new entry number in virtual item in virtual node
429*4882a593Smuzhiyun  */
old_entry_num(int is_affected,int virtual_entry_num,int pos_in_item,int mode)430*4882a593Smuzhiyun static inline int old_entry_num(int is_affected, int virtual_entry_num,
431*4882a593Smuzhiyun 				int pos_in_item, int mode)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	if (mode == M_INSERT || mode == M_DELETE)
434*4882a593Smuzhiyun 		return virtual_entry_num;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	if (!is_affected)
437*4882a593Smuzhiyun 		/* cut or paste is applied to another item */
438*4882a593Smuzhiyun 		return virtual_entry_num;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	if (virtual_entry_num < pos_in_item)
441*4882a593Smuzhiyun 		return virtual_entry_num;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	if (mode == M_CUT)
444*4882a593Smuzhiyun 		return virtual_entry_num + 1;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	RFALSE(mode != M_PASTE || virtual_entry_num == 0,
447*4882a593Smuzhiyun 	       "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'",
448*4882a593Smuzhiyun 	       mode);
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	return virtual_entry_num - 1;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun /*
454*4882a593Smuzhiyun  * Create an array of sizes of directory entries for virtual
455*4882a593Smuzhiyun  * item. Return space used by an item. FIXME: no control over
456*4882a593Smuzhiyun  * consuming of space used by this item handler
457*4882a593Smuzhiyun  */
direntry_create_vi(struct virtual_node * vn,struct virtual_item * vi,int is_affected,int insert_size)458*4882a593Smuzhiyun static int direntry_create_vi(struct virtual_node *vn,
459*4882a593Smuzhiyun 			      struct virtual_item *vi,
460*4882a593Smuzhiyun 			      int is_affected, int insert_size)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun 	struct direntry_uarea *dir_u = vi->vi_uarea;
463*4882a593Smuzhiyun 	int i, j;
464*4882a593Smuzhiyun 	int size = sizeof(struct direntry_uarea);
465*4882a593Smuzhiyun 	struct reiserfs_de_head *deh;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	vi->vi_index = TYPE_DIRENTRY;
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	BUG_ON(!(vi->vi_ih) || !vi->vi_item);
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	dir_u->flags = 0;
472*4882a593Smuzhiyun 	if (le_ih_k_offset(vi->vi_ih) == DOT_OFFSET)
473*4882a593Smuzhiyun 		dir_u->flags |= DIRENTRY_VI_FIRST_DIRENTRY_ITEM;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	deh = (struct reiserfs_de_head *)(vi->vi_item);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	/* virtual directory item have this amount of entry after */
478*4882a593Smuzhiyun 	dir_u->entry_count = ih_entry_count(vi->vi_ih) +
479*4882a593Smuzhiyun 	    ((is_affected) ? ((vn->vn_mode == M_CUT) ? -1 :
480*4882a593Smuzhiyun 			      (vn->vn_mode == M_PASTE ? 1 : 0)) : 0);
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	for (i = 0; i < dir_u->entry_count; i++) {
483*4882a593Smuzhiyun 		j = old_entry_num(is_affected, i, vn->vn_pos_in_item,
484*4882a593Smuzhiyun 				  vn->vn_mode);
485*4882a593Smuzhiyun 		dir_u->entry_sizes[i] =
486*4882a593Smuzhiyun 		    (j ? deh_location(&deh[j - 1]) : ih_item_len(vi->vi_ih)) -
487*4882a593Smuzhiyun 		    deh_location(&deh[j]) + DEH_SIZE;
488*4882a593Smuzhiyun 	}
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	size += (dir_u->entry_count * sizeof(short));
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	/* set size of pasted entry */
493*4882a593Smuzhiyun 	if (is_affected && vn->vn_mode == M_PASTE)
494*4882a593Smuzhiyun 		dir_u->entry_sizes[vn->vn_pos_in_item] = insert_size;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun #ifdef CONFIG_REISERFS_CHECK
497*4882a593Smuzhiyun 	/* compare total size of entries with item length */
498*4882a593Smuzhiyun 	{
499*4882a593Smuzhiyun 		int k, l;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 		l = 0;
502*4882a593Smuzhiyun 		for (k = 0; k < dir_u->entry_count; k++)
503*4882a593Smuzhiyun 			l += dir_u->entry_sizes[k];
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 		if (l + IH_SIZE != vi->vi_item_len +
506*4882a593Smuzhiyun 		    ((is_affected
507*4882a593Smuzhiyun 		      && (vn->vn_mode == M_PASTE
508*4882a593Smuzhiyun 			  || vn->vn_mode == M_CUT)) ? insert_size : 0)) {
509*4882a593Smuzhiyun 			reiserfs_panic(NULL, "vs-8025", "(mode==%c, "
510*4882a593Smuzhiyun 				       "insert_size==%d), invalid length of "
511*4882a593Smuzhiyun 				       "directory item",
512*4882a593Smuzhiyun 				       vn->vn_mode, insert_size);
513*4882a593Smuzhiyun 		}
514*4882a593Smuzhiyun 	}
515*4882a593Smuzhiyun #endif
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	return size;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun /*
522*4882a593Smuzhiyun  * return number of entries which may fit into specified amount of
523*4882a593Smuzhiyun  * free space, or -1 if free space is not enough even for 1 entry
524*4882a593Smuzhiyun  */
direntry_check_left(struct virtual_item * vi,int free,int start_skip,int end_skip)525*4882a593Smuzhiyun static int direntry_check_left(struct virtual_item *vi, int free,
526*4882a593Smuzhiyun 			       int start_skip, int end_skip)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun 	int i;
529*4882a593Smuzhiyun 	int entries = 0;
530*4882a593Smuzhiyun 	struct direntry_uarea *dir_u = vi->vi_uarea;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	for (i = start_skip; i < dir_u->entry_count - end_skip; i++) {
533*4882a593Smuzhiyun 		/* i-th entry doesn't fit into the remaining free space */
534*4882a593Smuzhiyun 		if (dir_u->entry_sizes[i] > free)
535*4882a593Smuzhiyun 			break;
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 		free -= dir_u->entry_sizes[i];
538*4882a593Smuzhiyun 		entries++;
539*4882a593Smuzhiyun 	}
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	if (entries == dir_u->entry_count) {
542*4882a593Smuzhiyun 		reiserfs_panic(NULL, "item_ops-1",
543*4882a593Smuzhiyun 			       "free space %d, entry_count %d", free,
544*4882a593Smuzhiyun 			       dir_u->entry_count);
545*4882a593Smuzhiyun 	}
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	/* "." and ".." can not be separated from each other */
548*4882a593Smuzhiyun 	if (start_skip == 0 && (dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
549*4882a593Smuzhiyun 	    && entries < 2)
550*4882a593Smuzhiyun 		entries = 0;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	return entries ? : -1;
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun 
direntry_check_right(struct virtual_item * vi,int free)555*4882a593Smuzhiyun static int direntry_check_right(struct virtual_item *vi, int free)
556*4882a593Smuzhiyun {
557*4882a593Smuzhiyun 	int i;
558*4882a593Smuzhiyun 	int entries = 0;
559*4882a593Smuzhiyun 	struct direntry_uarea *dir_u = vi->vi_uarea;
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	for (i = dir_u->entry_count - 1; i >= 0; i--) {
562*4882a593Smuzhiyun 		/* i-th entry doesn't fit into the remaining free space */
563*4882a593Smuzhiyun 		if (dir_u->entry_sizes[i] > free)
564*4882a593Smuzhiyun 			break;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 		free -= dir_u->entry_sizes[i];
567*4882a593Smuzhiyun 		entries++;
568*4882a593Smuzhiyun 	}
569*4882a593Smuzhiyun 	BUG_ON(entries == dir_u->entry_count);
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	/* "." and ".." can not be separated from each other */
572*4882a593Smuzhiyun 	if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
573*4882a593Smuzhiyun 	    && entries > dir_u->entry_count - 2)
574*4882a593Smuzhiyun 		entries = dir_u->entry_count - 2;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	return entries ? : -1;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun /* sum of entry sizes between from-th and to-th entries including both edges */
direntry_part_size(struct virtual_item * vi,int first,int count)580*4882a593Smuzhiyun static int direntry_part_size(struct virtual_item *vi, int first, int count)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun 	int i, retval;
583*4882a593Smuzhiyun 	int from, to;
584*4882a593Smuzhiyun 	struct direntry_uarea *dir_u = vi->vi_uarea;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	retval = 0;
587*4882a593Smuzhiyun 	if (first == 0)
588*4882a593Smuzhiyun 		from = 0;
589*4882a593Smuzhiyun 	else
590*4882a593Smuzhiyun 		from = dir_u->entry_count - count;
591*4882a593Smuzhiyun 	to = from + count - 1;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	for (i = from; i <= to; i++)
594*4882a593Smuzhiyun 		retval += dir_u->entry_sizes[i];
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun 	return retval;
597*4882a593Smuzhiyun }
598*4882a593Smuzhiyun 
direntry_unit_num(struct virtual_item * vi)599*4882a593Smuzhiyun static int direntry_unit_num(struct virtual_item *vi)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun 	struct direntry_uarea *dir_u = vi->vi_uarea;
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	return dir_u->entry_count;
604*4882a593Smuzhiyun }
605*4882a593Smuzhiyun 
direntry_print_vi(struct virtual_item * vi)606*4882a593Smuzhiyun static void direntry_print_vi(struct virtual_item *vi)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun 	int i;
609*4882a593Smuzhiyun 	struct direntry_uarea *dir_u = vi->vi_uarea;
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	reiserfs_warning(NULL, "reiserfs-16104",
612*4882a593Smuzhiyun 			 "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
613*4882a593Smuzhiyun 			 vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);
614*4882a593Smuzhiyun 	printk("%d entries: ", dir_u->entry_count);
615*4882a593Smuzhiyun 	for (i = 0; i < dir_u->entry_count; i++)
616*4882a593Smuzhiyun 		printk("%d ", dir_u->entry_sizes[i]);
617*4882a593Smuzhiyun 	printk("\n");
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun static struct item_operations direntry_ops = {
621*4882a593Smuzhiyun 	.bytes_number = direntry_bytes_number,
622*4882a593Smuzhiyun 	.decrement_key = direntry_decrement_key,
623*4882a593Smuzhiyun 	.is_left_mergeable = direntry_is_left_mergeable,
624*4882a593Smuzhiyun 	.print_item = direntry_print_item,
625*4882a593Smuzhiyun 	.check_item = direntry_check_item,
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	.create_vi = direntry_create_vi,
628*4882a593Smuzhiyun 	.check_left = direntry_check_left,
629*4882a593Smuzhiyun 	.check_right = direntry_check_right,
630*4882a593Smuzhiyun 	.part_size = direntry_part_size,
631*4882a593Smuzhiyun 	.unit_num = direntry_unit_num,
632*4882a593Smuzhiyun 	.print_vi = direntry_print_vi
633*4882a593Smuzhiyun };
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun /* Error catching functions to catch errors caused by incorrect item types. */
errcatch_bytes_number(struct item_head * ih,int block_size)636*4882a593Smuzhiyun static int errcatch_bytes_number(struct item_head *ih, int block_size)
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16001",
639*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
640*4882a593Smuzhiyun 	return 0;
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun 
errcatch_decrement_key(struct cpu_key * key)643*4882a593Smuzhiyun static void errcatch_decrement_key(struct cpu_key *key)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16002",
646*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun 
errcatch_is_left_mergeable(struct reiserfs_key * key,unsigned long bsize)649*4882a593Smuzhiyun static int errcatch_is_left_mergeable(struct reiserfs_key *key,
650*4882a593Smuzhiyun 				      unsigned long bsize)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16003",
653*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
654*4882a593Smuzhiyun 	return 0;
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun 
errcatch_print_item(struct item_head * ih,char * item)657*4882a593Smuzhiyun static void errcatch_print_item(struct item_head *ih, char *item)
658*4882a593Smuzhiyun {
659*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16004",
660*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun 
errcatch_check_item(struct item_head * ih,char * item)663*4882a593Smuzhiyun static void errcatch_check_item(struct item_head *ih, char *item)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16005",
666*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun 
errcatch_create_vi(struct virtual_node * vn,struct virtual_item * vi,int is_affected,int insert_size)669*4882a593Smuzhiyun static int errcatch_create_vi(struct virtual_node *vn,
670*4882a593Smuzhiyun 			      struct virtual_item *vi,
671*4882a593Smuzhiyun 			      int is_affected, int insert_size)
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16006",
674*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
675*4882a593Smuzhiyun 	/*
676*4882a593Smuzhiyun 	 * We might return -1 here as well, but it won't help as
677*4882a593Smuzhiyun 	 * create_virtual_node() from where this operation is called
678*4882a593Smuzhiyun 	 * from is of return type void.
679*4882a593Smuzhiyun 	 */
680*4882a593Smuzhiyun 	return 0;
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun 
errcatch_check_left(struct virtual_item * vi,int free,int start_skip,int end_skip)683*4882a593Smuzhiyun static int errcatch_check_left(struct virtual_item *vi, int free,
684*4882a593Smuzhiyun 			       int start_skip, int end_skip)
685*4882a593Smuzhiyun {
686*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16007",
687*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
688*4882a593Smuzhiyun 	return -1;
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun 
errcatch_check_right(struct virtual_item * vi,int free)691*4882a593Smuzhiyun static int errcatch_check_right(struct virtual_item *vi, int free)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16008",
694*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
695*4882a593Smuzhiyun 	return -1;
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun 
errcatch_part_size(struct virtual_item * vi,int first,int count)698*4882a593Smuzhiyun static int errcatch_part_size(struct virtual_item *vi, int first, int count)
699*4882a593Smuzhiyun {
700*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16009",
701*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
702*4882a593Smuzhiyun 	return 0;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun 
errcatch_unit_num(struct virtual_item * vi)705*4882a593Smuzhiyun static int errcatch_unit_num(struct virtual_item *vi)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16010",
708*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
709*4882a593Smuzhiyun 	return 0;
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun 
errcatch_print_vi(struct virtual_item * vi)712*4882a593Smuzhiyun static void errcatch_print_vi(struct virtual_item *vi)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun 	reiserfs_warning(NULL, "green-16011",
715*4882a593Smuzhiyun 			 "Invalid item type observed, run fsck ASAP");
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun static struct item_operations errcatch_ops = {
719*4882a593Smuzhiyun 	.bytes_number = errcatch_bytes_number,
720*4882a593Smuzhiyun 	.decrement_key = errcatch_decrement_key,
721*4882a593Smuzhiyun 	.is_left_mergeable = errcatch_is_left_mergeable,
722*4882a593Smuzhiyun 	.print_item = errcatch_print_item,
723*4882a593Smuzhiyun 	.check_item = errcatch_check_item,
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	.create_vi = errcatch_create_vi,
726*4882a593Smuzhiyun 	.check_left = errcatch_check_left,
727*4882a593Smuzhiyun 	.check_right = errcatch_check_right,
728*4882a593Smuzhiyun 	.part_size = errcatch_part_size,
729*4882a593Smuzhiyun 	.unit_num = errcatch_unit_num,
730*4882a593Smuzhiyun 	.print_vi = errcatch_print_vi
731*4882a593Smuzhiyun };
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
734*4882a593Smuzhiyun #error Item types must use disk-format assigned values.
735*4882a593Smuzhiyun #endif
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun struct item_operations *item_ops[TYPE_ANY + 1] = {
738*4882a593Smuzhiyun 	&stat_data_ops,
739*4882a593Smuzhiyun 	&indirect_ops,
740*4882a593Smuzhiyun 	&direct_ops,
741*4882a593Smuzhiyun 	&direntry_ops,
742*4882a593Smuzhiyun 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
743*4882a593Smuzhiyun 	&errcatch_ops		/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
744*4882a593Smuzhiyun };
745