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