File: node41_repair.c

package info (click to toggle)
reiser4progs 1.2.2-1
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 5,904 kB
  • sloc: ansic: 34,331; sh: 4,251; makefile: 994
file content (153 lines) | stat: -rw-r--r-- 3,747 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* Copyright 2001-2005 by Hans Reiser, licensing governed by
   reiser4progs/COPYING.

   node41_repair.c -- reiser4 node with short keys. */

#ifndef ENABLE_MINIMAL
#include "../node40/node40.h"
#include "../node40/node40_repair.h"
#include "node41.h"
#include <repair/plugin.h>

#define MIN_ITEM_LEN	1

/*
 * Look through ih array looking for the last valid item location. This will
 * be the last valid item.
 */
uint32_t node41_estimate_count(reiser4_node_t *node)
{
	return node40_estimate_count_common(node, sizeof(node41_header_t));
}

/*
 * Checks the count of items written in node_header. If it is wrong, it tries
 * to estimate it on the base of free_space fields and recover if REBUILD mode.
 * Returns FATAL otherwise.
 */
static errno_t node41_count_check(reiser4_node_t *node, uint8_t mode)
{
	return node40_count_check_common(node, mode, node41_estimate_count);
}

/*
 * Count of items is correct. Free space fields and item locations should be
 * checked/recovered if broken
 */
static errno_t node41_ih_array_check(reiser4_node_t *node, uint8_t mode)
{
	return node40_ih_array_check_common(node, mode,
					    sizeof(node41_header_t));
}

errno_t node41_check_struct(reiser4_node_t *node, uint8_t mode) {
	errno_t res;

	aal_assert("edward-17", node != NULL);

	/* Check the content of the node40 header. */
	if ((res = node41_count_check(node, mode)))
		return res;

	if (nh_get_num_items(node) == 0) {
		uint32_t offset = sizeof(node41_header_t);
		return node40_space_check(node, offset, mode);
	}

	/* Count looks ok. Recover the item array. */
	res = node41_ih_array_check(node, mode);

	if (repair_error_fatal(res))
		return res;

	res |= node40_iplug_check(node, mode);

	return res;
}

/*
 * Pack node41 header w/out magic and padding
 */
void node41_header_pack(reiser4_node_t *entity, aal_stream_t *stream)
{
	node41_header_t *head41;

	node40_header_pack(entity, stream);

	head41 = nh41(entity->block);
	aal_stream_write(stream, &head41->csum,
			 sizeof(head41->csum));
}

errno_t node41_pack(reiser4_node_t *entity, aal_stream_t *stream)
{
	return node40_pack_common(entity, stream,
				  node41_header_pack, node40_items_pack);
}

static int32_t node41_header_unpack(reiser4_node_t *entity,
				    aal_stream_t *stream)
{
	int32_t ret;
	uint32_t read;
	node41_header_t *head41;

	head41 = nh41(entity->block);
	ret = node40_header_unpack(entity, stream);
	if (ret)
		return ret;
	read = aal_stream_read(stream, &head41->csum,
			       sizeof(head41->csum));
	if (read != sizeof(head41->csum))
		return -1;
	return 0;
}

reiser4_node_t *node41_unpack(aal_block_t *block,
			      reiser4_key_plug_t *kplug,
			      aal_stream_t *stream)
{
	return node40_unpack_common(block, kplug, stream,
				    &node41_plug, NODE41_MAGIC,
				    node41_prepare,
				    node41_header_unpack,
				    node40_items_unpack);
}

static void node41_header_print(reiser4_node_t *entity, aal_stream_t *stream)
{
	uint8_t level;
	uint32_t csum;

	level = node40_get_level(entity);
	csum = node41_get_csum(entity);

	aal_stream_format(stream, "NODE (%llu) CSUM=%u LEVEL=%u ITEMS=%u "
			  "SPACE=%u MKFS ID=0x%x FLUSH=0x%llx\n",
			  entity->block->nr, csum, level,
			  node40_items(entity), node40_space(entity),
			  nh_get_mkfs_id(entity), nh_get_flush_id(entity));
}

/*
 * Prepare text node description and push it into specified @stream
 */
void node41_print(reiser4_node_t *entity, aal_stream_t *stream,
		  uint32_t start, uint32_t count, uint16_t options)
{
	return node40_print_common(entity, stream, start, count, options,
				   node41_header_print);
}

#endif

/*
   Local variables:
   c-indentation-style: "K&R"
   mode-name: "LC"
   c-basic-offset: 8
   tab-width: 8
   fill-column: 80
   scroll-step: 1
   End:
*/