1 /*
2 key.c -- reiserfs keys code
3 Copyright (C) 2001, 2002 Yury Umanets <torque@ukrpost.net>, see COPYING for
4 licensing and copyright details.
5
6 Some parts of this code are from original reiserfs code as found in reiserfsprogs
7 and the linux kernel.
8 Copyright 1996-2002 Hans Reiser, see COPYING.NAMESYS for licensing
9 and copyright details
10 */
11
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
15
16 #include <string.h>
17 #include <reiserfs/reiserfs.h>
18
19 #define N_(String) (String)
20 #if ENABLE_NLS
21 # include <libintl.h>
22 # define _(String) dgettext (PACKAGE, String)
23 #else
24 # define _(String) (String)
25 #endif
26
27 #define KEY_OFFSET_MASK 0xfffffffffffffffLL
28 #define KEY_TYPE_MASK 0xf000000000000000LL
29
reiserfs_key_uniq2type(uint32_t uniq)30 uint32_t reiserfs_key_uniq2type(uint32_t uniq) {
31 switch (uniq) {
32 case KEY_UNIQ_SD: return KEY_TYPE_SD;
33 case KEY_UNIQ_IT: return KEY_TYPE_IT;
34 case KEY_UNIQ_DT: return KEY_TYPE_DT;
35 case KEY_UNIQ_DR: return KEY_TYPE_DR;
36 }
37 return KEY_TYPE_UN;
38 }
39
reiserfs_key_type2uniq(uint32_t type)40 uint32_t reiserfs_key_type2uniq(uint32_t type) {
41 switch (type) {
42 case KEY_TYPE_SD: return KEY_UNIQ_SD;
43 case KEY_TYPE_IT: return KEY_UNIQ_IT;
44 case KEY_TYPE_DT: return KEY_UNIQ_DT;
45 case KEY_TYPE_DR: return KEY_UNIQ_DR;
46 }
47 return KEY_UNIQ_UN;
48 }
49
get_key_v2_offset(const struct key * key)50 uint64_t get_key_v2_offset(const struct key *key) {
51 uint64_t * p, tmp;
52
53 p = (uint64_t *)(&(key->u.k_offset_v2));
54 tmp = LE64_TO_CPU(*p);
55 tmp &= KEY_OFFSET_MASK;
56 tmp >>= 0;
57 return tmp;
58 }
59
set_key_v2_offset(struct key * key,uint64_t val)60 void set_key_v2_offset(struct key *key, uint64_t val) {
61 uint64_t * p, tmp;
62
63 p = (uint64_t *)(&(key->u.k_offset_v2));
64 tmp = LE64_TO_CPU(*p);
65 tmp &= ~KEY_OFFSET_MASK;
66 tmp |= (val << 0);
67
68 *p = CPU_TO_LE64 (tmp);
69 }
70
get_key_v2_type(const struct key * key)71 uint16_t get_key_v2_type(const struct key *key) {
72 uint64_t * p, tmp;
73
74 p = (uint64_t *)(&(key->u.k_offset_v2));
75 tmp = LE64_TO_CPU (*p);
76 tmp &= KEY_TYPE_MASK;
77 tmp >>= 60;
78 return (uint16_t)tmp;
79 }
80
set_key_v2_type(struct key * key,uint64_t val)81 void set_key_v2_type(struct key *key, uint64_t val) {
82 uint64_t * p, tmp;
83
84 if (val > 15) {
85 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
86 _("Key type (%d) is too big."), val);
87 return;
88 }
89
90 p = (uint64_t *)(&(key->u.k_offset_v2));
91 tmp = LE64_TO_CPU(*p);
92 tmp &= ~KEY_TYPE_MASK;
93 tmp |= (val << 60);
94
95 *p = CPU_TO_LE64(tmp);
96 }
97
reiserfs_key_format(const struct key * key)98 uint32_t reiserfs_key_format(const struct key *key) {
99 int type;
100
101 type = get_key_v2_type(key);
102
103 if (type == 0 || type == 15)
104 return KEY_FORMAT_1;
105
106 return KEY_FORMAT_2;
107 }
108
reiserfs_key_type(const struct key * key)109 uint32_t reiserfs_key_type(const struct key *key) {
110 if (reiserfs_key_format(key) == KEY_FORMAT_1)
111 return reiserfs_key_uniq2type(get_key_v1_type(key));
112
113 return get_key_v2_type(key);
114 }
115
reiserfs_key_offset(const struct key * key)116 uint64_t reiserfs_key_offset(const struct key *key) {
117 if (reiserfs_key_format(key) == KEY_FORMAT_1)
118 return get_key_v1_offset(key);
119
120 return get_key_v2_offset(key);
121 }
122
reiserfs_key_v1_form(struct key * key,uint32_t dirid,uint32_t objid,uint32_t offset,uint32_t type)123 void reiserfs_key_v1_form(struct key *key, uint32_t dirid, uint32_t objid,
124 uint32_t offset, uint32_t type)
125 {
126 memset(key, 0, sizeof(*key));
127 set_key_dirid(key, dirid);
128 set_key_objid(key, objid);
129 set_key_v1_offset(key, offset);
130 set_key_v1_type(key, type);
131 }
132
reiserfs_key_v2_form(struct key * key,uint32_t dirid,uint32_t objid,uint64_t offset,uint64_t type)133 void reiserfs_key_v2_form(struct key *key, uint32_t dirid, uint32_t objid,
134 uint64_t offset, uint64_t type)
135 {
136 memset(key, 0, sizeof(*key));
137 set_key_dirid(key, dirid);
138 set_key_objid(key, objid);
139 set_key_v2_offset(key, offset);
140 set_key_v2_type(key, type);
141 }
142
reiserfs_key_form(struct key * key,uint32_t dirid,uint32_t objid,uint64_t offset,uint64_t type,int format)143 void reiserfs_key_form(struct key *key, uint32_t dirid, uint32_t objid,
144 uint64_t offset, uint64_t type, int format)
145 {
146 (format == FS_FORMAT_3_5 ?
147 reiserfs_key_v1_form(key, dirid, objid, (uint32_t)offset,
148 reiserfs_key_type2uniq((uint32_t)type)) :
149 reiserfs_key_v2_form(key, dirid, objid, offset, type));
150 }
151
152 /* Compare functions */
reiserfs_key_comp_dirs(void * key1,void * key2)153 int reiserfs_key_comp_dirs(void *key1, void *key2) {
154
155 if (get_key_dirid((struct key *)key1) < get_key_dirid((struct key *)key2))
156 return -1;
157
158 if (get_key_dirid((struct key *)key1) > get_key_dirid((struct key *)key2))
159 return 1;
160
161 return 0;
162 }
163
reiserfs_key_comp_objects(void * key1,void * key2)164 int reiserfs_key_comp_objects(void *key1, void *key2) {
165
166 if (get_key_objid((struct key *)key1) < get_key_objid((struct key *)key2))
167 return -1;
168
169 if (get_key_objid((struct key *)key1) > get_key_objid((struct key *)key2))
170 return 1;
171
172 return 0;
173 }
174
reiserfs_key_comp_two_components(void * key1,void * key2)175 int reiserfs_key_comp_two_components(void *key1, void *key2) {
176 uint32_t *p_key1, *p_key2;
177 int key_length = SHORT_KEY_LEN;
178
179 p_key1 = (uint32_t *)key1;
180 p_key2 = (uint32_t *)key2;
181
182 for(; key_length--; p_key1++, p_key2++) {
183 if (LE32_TO_CPU(*p_key1) < LE32_TO_CPU(*p_key2))
184 return -1;
185
186 if (LE32_TO_CPU(*p_key1) > LE32_TO_CPU(*p_key2))
187 return 1;
188 }
189
190 return 0;
191 }
192
reiserfs_key_comp_three_components(void * key1,void * key2)193 int reiserfs_key_comp_three_components(void *key1, void *key2) {
194 int retval;
195
196 if ((retval = reiserfs_key_comp_two_components(key1, key2)))
197 return retval;
198
199 if (reiserfs_key_offset((struct key *)key1) < reiserfs_key_offset((struct key *)key2))
200 return -1;
201
202 if (reiserfs_key_offset((struct key *)key1) > reiserfs_key_offset((struct key *)key2))
203 return 1;
204
205 return 0;
206 }
207
reiserfs_key_comp_four_components(void * key1,void * key2)208 int reiserfs_key_comp_four_components(void *key1, void *key2) {
209 int retval;
210
211 if ((retval = reiserfs_key_comp_three_components(key1, key2)))
212 return retval;
213
214 if (reiserfs_key_type((struct key *)key1) < reiserfs_key_type((struct key *)key2))
215 return -1;
216
217 if (reiserfs_key_type((struct key *)key1) > reiserfs_key_type((struct key *)key2))
218 return 1;
219
220 return 0;
221 }
222
223