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