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