1/*-
2 * Copyright 2000 Hans Reiser
3 * See README for licensing and copyright details
4 *
5 * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron@club-internet.fr>
6 *
7 * $FreeBSD$
8 */
9
10#include <gnu/fs/reiserfs/reiserfs_fs.h>
11
12#if 0
13static char error_buf[1024];
14static char fmt_buf[1024];
15static char off_buf[80];
16
17static char *
18reiserfs_cpu_offset(struct cpu_key *key)
19{
20
21	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
22		sprintf(off_buf, "%Lu(%Lu)",
23		    (unsigned long long)GET_HASH_VALUE(cpu_key_k_offset(key)),
24		    (unsigned long long)GET_GENERATION_NUMBER(
25			cpu_key_k_offset(key)));
26	else
27		sprintf(off_buf, "0x%Lx",
28		    (unsigned long long)cpu_key_k_offset(key));
29
30	return (off_buf);
31}
32
33static char *
34le_offset(struct key *key)
35{
36	int version;
37
38	version = le_key_version(key);
39	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
40		sprintf(off_buf, "%Lu(%Lu)",
41		    (unsigned long long)GET_HASH_VALUE(
42			le_key_k_offset(version, key)),
43		    (unsigned long long)GET_GENERATION_NUMBER(
44			le_key_k_offset(version, key)));
45	else
46		sprintf(off_buf, "0x%Lx",
47		    (unsigned long long)le_key_k_offset(version, key));
48
49	return (off_buf);
50}
51
52static char *
53cpu_type(struct cpu_key *key)
54{
55
56	if (cpu_key_k_type(key) == TYPE_STAT_DATA)
57		return ("SD");
58	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
59		return ("DIR");
60	if (cpu_key_k_type(key) == TYPE_DIRECT)
61		return ("DIRECT");
62	if (cpu_key_k_type(key) == TYPE_INDIRECT)
63		return ("IND");
64
65	return ("UNKNOWN");
66}
67
68static char *
69le_type(struct key *key)
70{
71	int version;
72
73	version = le_key_version(key);
74
75	if (le_key_k_type(version, key) == TYPE_STAT_DATA)
76		return ("SD");
77	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
78		return ("DIR");
79	if (le_key_k_type(version, key) == TYPE_DIRECT)
80		return ("DIRECT");
81	if (le_key_k_type(version, key) == TYPE_INDIRECT)
82		return ("IND");
83
84	return ("UNKNOWN");
85}
86
87/* %k */
88static void
89sprintf_le_key(char *buf, struct key *key)
90{
91
92	if (key)
93		sprintf(buf, "[%d %d %s %s]", le32toh(key->k_dir_id),
94		    le32toh(key->k_objectid), le_offset(key), le_type(key));
95	else
96		sprintf(buf, "[NULL]");
97}
98
99/* %K */
100static void
101sprintf_cpu_key(char *buf, struct cpu_key *key)
102{
103
104	if (key)
105		sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
106		    key->on_disk_key.k_objectid, reiserfs_cpu_offset (key),
107		    cpu_type (key));
108	else
109		sprintf(buf, "[NULL]");
110}
111
112static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh)
113{
114
115	if (deh)
116		sprintf(buf,
117		    "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
118		    deh_offset(deh), deh_dir_id(deh),
119		    deh_objectid(deh), deh_location(deh), deh_state(deh));
120	else
121		sprintf(buf, "[NULL]");
122}
123
124static void
125sprintf_item_head(char *buf, struct item_head *ih)
126{
127
128	if (ih) {
129		strcpy(buf, (ih_version(ih) == KEY_FORMAT_3_6) ?
130		    "*3.6* " : "*3.5*");
131		sprintf_le_key(buf + strlen(buf), &(ih->ih_key));
132		sprintf(buf + strlen(buf), ", item_len %d, item_location %d, "
133		    "free_space(entry_count) %d",
134		    ih_item_len(ih), ih_location(ih), ih_free_space(ih));
135	} else
136		sprintf(buf, "[NULL]");
137}
138
139static void
140sprintf_direntry(char *buf, struct reiserfs_dir_entry *de)
141{
142	char name[20];
143
144	memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
145	name [de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
146	sprintf(buf, "\"%s\" ==> [%d %d]",
147	    name, de->de_dir_id, de->de_objectid);
148}
149
150static void
151sprintf_block_head(char *buf, struct buf *bp)
152{
153
154	sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
155	    B_LEVEL(bp), B_NR_ITEMS(bp), B_FREE_SPACE(bp));
156}
157
158static void
159sprintf_disk_child(char *buf, struct disk_child *dc)
160{
161
162	sprintf (buf, "[dc_number=%d, dc_size=%u]",
163	    dc_block_number(dc), dc_size(dc));
164}
165
166static char *
167is_there_reiserfs_struct (char *fmt, int *what, int *skip)
168{
169	char *k;
170
171	k = fmt;
172	*skip = 0;
173
174	while ((k = strchr(k, '%')) != NULL) {
175		if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
176		    k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a' ) {
177			*what = k[1];
178			break;
179		}
180		(*skip)++;
181		k++;
182	}
183
184	return (k);
185}
186
187static void
188prepare_error_buf(const char *fmt, va_list args)
189{
190	char *fmt1, *k, *p;
191	int i, j, what, skip;
192
193	fmt1 = fmt_buf;
194	p = error_buf;
195	strcpy (fmt1, fmt);
196
197	while ((k = is_there_reiserfs_struct(fmt1, &what, &skip)) != NULL) {
198		*k = 0;
199
200		p += vsprintf (p, fmt1, args);
201
202		for (i = 0; i < skip; i ++)
203			j = va_arg(args, int);
204
205		switch (what) {
206		case 'k':
207			sprintf_le_key(p, va_arg(args, struct key *));
208			break;
209		case 'K':
210			sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
211			break;
212		case 'h':
213			sprintf_item_head(p, va_arg(args, struct item_head *));
214			break;
215		case 't':
216			sprintf_direntry(p,
217			    va_arg(args, struct reiserfs_dir_entry *));
218			break;
219		case 'y':
220			sprintf_disk_child(p,
221			    va_arg(args, struct disk_child *));
222			break;
223		case 'z':
224			sprintf_block_head(p,
225			    va_arg(args, struct buffer_head *));
226			break;
227		case 'a':
228			sprintf_de_head(p,
229			    va_arg(args, struct reiserfs_de_head *));
230			break;
231		}
232
233		p   += strlen(p);
234		fmt1 = k + 2;
235	}
236
237	vsprintf(p, fmt1, args);
238}
239
240/*
241 * In addition to usual conversion specifiers this accepts reiserfs
242 * specific conversion specifiers:
243 *   %k to print little endian key,
244 *   %K to print cpu key,
245 *   %h to print item_head,
246 *   %t to print directory entry,
247 *   %z to print block head (arg must be struct buf *)
248 */
249
250#define do_reiserfs_warning(fmt)					\
251{									\
252	va_list args;							\
253	va_start(args, fmt);						\
254	prepare_error_buf(fmt, args);					\
255	va_end(args);							\
256}
257
258void
259__reiserfs_log(int level, const char * fmt, ...)
260{
261
262	do_reiserfs_warning(fmt);
263	log(level, "ReiserFS/%s: %s\n", __FUNCTION__, error_buf);
264}
265
266#endif
267
268char *
269reiserfs_hashname(int code)
270{
271
272	if (code == YURA_HASH)
273		return ("rupasov");
274	if (code == TEA_HASH)
275		return ("tea");
276	if (code == R5_HASH)
277		return ("r5");
278
279	return ("unknown");
280}
281
282void
283reiserfs_dump_buffer(caddr_t buf, off_t len)
284{
285	int i, j;
286
287	log(LOG_DEBUG, "reiserfs: dumping a buffer of %jd bytes\n",
288	    (intmax_t)len);
289	for (i = 0; i < len; i += 16) {
290		log(LOG_DEBUG, "%08x: ", i);
291		for (j = 0; j < 16; j += 2) {
292			if (i + j >= len)
293				log(LOG_DEBUG, "     ");
294			else
295				log(LOG_DEBUG, "%02x%02x ",
296				    buf[i + j] & 0xff,
297				    buf[i + j + 1] & 0xff);
298		}
299		for (j = 0; j < 16; ++j) {
300			if (i + j >= len)
301				break;
302			log(LOG_DEBUG, "%c",
303			    isprint(buf[i + j]) ? buf[i + j] : '.');
304		}
305		log(LOG_DEBUG, "\n");
306	}
307}
308