Motr  M0
fid.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_OTHER
24 #include "lib/trace.h"
25 
26 #include "lib/errno.h" /* EINVAL */
27 #include "lib/misc.h" /* memcmp, strcmp */
28 #include "lib/string.h" /* sscanf */
29 #include "lib/assert.h" /* M0_PRE */
30 #include "lib/hash.h" /* m0_hash */
31 #include "lib/arith.h" /* m0_rnd */
32 #include "lib/uuid.h" /* m0_uuid_generate */
33 #include "fid/fid_xc.h"
34 #include "fid/fid.h"
35 #include "lib/memory.h" /* M0_ALLOC_ARR */
36 
43 /* TODO move to m0 */
44 static const struct m0_fid_type *fid_types[256];
45 
46 M0_INTERNAL void m0_fid_type_register(const struct m0_fid_type *fidt)
47 {
48  uint8_t id = fidt->ft_id;
49 
51  M0_PRE(fid_types[id] == NULL);
52  fid_types[id] = fidt;
53 }
54 
55 M0_INTERNAL void m0_fid_type_unregister(const struct m0_fid_type *fidt)
56 {
57  uint8_t id = fidt->ft_id;
58 
60  M0_PRE(fid_types[id] == fidt);
61  fid_types[id] = NULL;
62 }
63 
64 M0_INTERNAL const struct m0_fid_type *m0_fid_type_get(uint8_t id)
65 {
67  return fid_types[id];
68 }
69 
70 M0_INTERNAL const struct m0_fid_type *m0_fid_type_gethi(uint64_t id)
71 {
72  return m0_fid_type_get(id >> (64 - 8));
73 }
74 
75 M0_INTERNAL const struct m0_fid_type *
77 {
79 }
80 
81 M0_INTERNAL const struct m0_fid_type *m0_fid_type_getname(const char *name)
82 {
83  size_t i;
84  const struct m0_fid_type *fidt;
85 
86  for (i = 0; i < ARRAY_SIZE(fid_types); ++i) {
87  fidt = fid_types[i];
88  M0_ASSERT(ergo(fidt != NULL, fidt->ft_name != NULL));
89  if (fidt != NULL && strcmp(name, fidt->ft_name) == 0)
90  return fidt;
91  }
92 
93  return NULL;
94 }
95 
96 M0_INTERNAL bool m0_fid_is_valid(const struct m0_fid *fid)
97 {
98  const struct m0_fid_type *ft = m0_fid_type_getfid(fid);
99 
100  return
101  ft != NULL &&
102  ergo(ft->ft_is_valid != NULL, ft->ft_is_valid(fid));
103 }
104 M0_EXPORTED(m0_fid_is_valid);
105 
106 M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
107 {
108  static const struct m0_fid zero = {
109  .f_container = 0,
110  .f_key = 0
111  };
112  return !m0_fid_eq(fid, &zero);
113 }
114 M0_EXPORTED(m0_fid_is_set);
115 
116 M0_INTERNAL void m0_fid_set(struct m0_fid *fid, uint64_t container,
117  uint64_t key)
118 {
119  M0_PRE(fid != NULL);
120 
122  fid->f_key = key;
123 }
124 M0_EXPORTED(m0_fid_set);
125 
126 M0_INTERNAL void m0_fid_tset(struct m0_fid *fid,
127  uint8_t tid, uint64_t container, uint64_t key)
128 {
130 }
131 M0_EXPORTED(m0_fid_tset);
132 
133 M0_INTERNAL uint8_t m0_fid_tget(const struct m0_fid *fid)
134 {
135  return fid->f_container >> 56;
136 }
137 M0_EXPORTED(m0_fid_tget);
138 
139 M0_INTERNAL void m0_fid_tchange(struct m0_fid *fid, uint8_t tid)
140 {
141  M0_PRE(fid != NULL);
144 }
145 
146 M0_INTERNAL void m0_fid_tassume(struct m0_fid *fid,
147  const struct m0_fid_type *ft)
148 {
149  M0_PRE(fid != NULL);
150  M0_PRE(ft != NULL);
151 
152  m0_fid_tchange(fid, ft->ft_id);
153 }
154 
155 M0_INTERNAL void m0_fid_tgenerate(struct m0_fid *fid,
156  const uint8_t tid)
157 {
158  M0_PRE(fid != NULL);
159 
160  m0_uuid_generate((struct m0_uint128*)fid);
161  m0_fid_tchange(fid, tid);
162 }
163 
164 M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
165 {
166  return memcmp(fid0, fid1, sizeof *fid0) == 0;
167 }
168 M0_EXPORTED(m0_fid_eq);
169 
170 M0_INTERNAL int m0_fid_cmp(const struct m0_fid *fid0, const struct m0_fid *fid1)
171 {
172  const struct m0_uint128 u0 = {
173  .u_hi = fid0->f_container,
174  .u_lo = fid0->f_key
175  };
176 
177  const struct m0_uint128 u1 = {
178  .u_hi = fid1->f_container,
179  .u_lo = fid1->f_key
180  };
181 
182  return m0_uint128_cmp(&u0, &u1);
183 }
184 M0_EXPORTED(m0_fid_cmp);
185 
199 static int fid_sscanf(const char *s, struct m0_fid *fid, int *nob)
200 {
201  int rc;
202 
203  /* First check format with braces. */
204  rc = sscanf(s, FID_SF" %n", FID_S(fid), nob);
205  if (rc != 2) {
206  /* If not found then check the without braces. */
207  rc = sscanf(s, " %"SCNx64" : %"SCNx64" %n", FID_S(fid), nob);
208  /* See a comment in m0_xcode_read() on the effects of %n. */
209  if (rc != 2) {
210  uint8_t ft;
211 
212  /* Check for other formats. */
213  rc = sscanf(s, " %c | %"SCNi64" : %"SCNi64" %n",
214  &ft, FID_S(fid), nob);
215  if (rc == 3 && m0_fid_tget(fid) == 0) {
217  rc = 0;
218  } else
219  rc = -EINVAL; /* No M0_ERR() here. */
220  } else
221  rc = 0;
222  } else
223  rc = 0;
224  return M0_RC(rc);
225 }
226 
227 M0_INTERNAL int m0_fid_sscanf(const char *s, struct m0_fid *fid)
228 {
229  int nob;
230  return fid_sscanf(s, fid, &nob);
231 }
232 
233 M0_INTERNAL int m0_fid_print(char *s, size_t s_len, const struct m0_fid *fid)
234 {
235  int rc;
236 
237  M0_PRE(s != NULL);
239  M0_PRE(fid != NULL);
240 
241  rc = snprintf(s, s_len, "%" PRIx64 ":%"PRIx64, FID_P(fid));
242  if (rc < 0 || rc >= s_len)
243  return M0_ERR(-EINVAL);
244 
245  return M0_RC(rc);
246 }
247 
251 static const struct m0_fid_type misc = {
252  .ft_id = 0,
253  .ft_name = "miscellaneous"
254 };
255 
263 static int xt_read(const struct m0_xcode_cursor *it,
264  struct m0_xcode_obj *obj, const char *str)
265 {
266  int result;
267  int nr;
268 
269  M0_ASSERT(obj->xo_type == m0_fid_xc);
270  result = fid_sscanf(str, obj->xo_ptr, &nr);
271  return result == 0 ? nr : M0_ERR(result);
272 }
273 
277 static const struct m0_xcode_type_ops xt_ops = {
278  .xto_read = &xt_read
279 };
280 
281 M0_INTERNAL int m0_fid_init(void)
282 {
284  m0_fid_xc->xct_ops = &xt_ops;
285  return 0;
286 }
287 M0_EXPORTED(m0_fid_init);
288 
289 M0_INTERNAL void m0_fid_fini(void)
290 {
292 }
293 M0_EXPORTED(m0_fid_fini);
294 
295 M0_INTERNAL uint64_t m0_fid_hash(const struct m0_fid *fid)
296 
297 {
300 
301 }
302 
303 M0_INTERNAL int m0_fid_arr_copy(struct m0_fid_arr *to,
304  const struct m0_fid_arr *from)
305 {
306  int i;
307 
308  M0_ALLOC_ARR(to->af_elems, from->af_count);
309  if (to->af_elems == NULL)
310  return M0_ERR(-ENOMEM);
311 
312  to->af_count = from->af_count;
313  for (i = 0; i < to->af_count; ++i)
314  to->af_elems[i] = from->af_elems[i];
315 
316  return M0_RC(0);
317 }
318 
319 M0_INTERNAL bool m0_fid_arr_eq(const struct m0_fid_arr *a,
320  const struct m0_fid_arr *b)
321 {
322  return b->af_count == a->af_count
323  && m0_forall(i, a->af_count, m0_fid_eq(&a->af_elems[i],
324  &b->af_elems[i]));
325 }
326 
327 M0_INTERNAL bool m0_fid_arr_all_unique(const struct m0_fid_arr *a)
328 {
329  int i;
330  int j;
331 
332  for (i = 0; i < a->af_count; ++i) {
333  for (j = i + 1; j < a->af_count; ++j)
334  if (m0_fid_eq(&a->af_elems[i], &a->af_elems[j]))
335  return false;
336  }
337  return true;
338 }
339 
340 #undef M0_TRACE_SUBSYSTEM
341 
343 /*
344  * Local variables:
345  * c-indentation-style: "K&R"
346  * c-basic-offset: 8
347  * tab-width: 8
348  * fill-column: 80
349  * scroll-step: 1
350  * End:
351  */
M0_INTERNAL int m0_uint128_cmp(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:45
uint64_t id
Definition: cob.h:2380
static size_t nr
Definition: dump.c:1505
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
#define FID_SF
Definition: fid.h:76
M0_INTERNAL uint64_t m0_fid_hash(const struct m0_fid *fid)
Definition: fid.c:295
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_fid_tset(struct m0_fid *fid, uint8_t tid, uint64_t container, uint64_t key)
Definition: fid.c:126
#define ergo(a, b)
Definition: misc.h:293
M0_INTERNAL void m0_uuid_generate(struct m0_uint128 *u)
Definition: uuid.c:44
uint32_t s_len
Definition: string.h:99
#define SCNx64
Definition: types.h:62
struct m0_container container
uint8_t ft_id
Definition: fid.h:101
#define M0_FID_TCONTAINER(type, container)
Definition: fid.h:80
struct m0_fid * af_elems
Definition: fid.h:45
static const struct m0_fid_type * fid_types[256]
Definition: fid.c:44
M0_INTERNAL uint8_t m0_fid_tget(const struct m0_fid *fid)
Definition: fid.c:133
static struct m0_be_emap_cursor it
Definition: extmap.c:46
M0_INTERNAL const struct m0_fid_type * m0_fid_type_get(uint8_t id)
Definition: fid.c:64
M0_INTERNAL void m0_fid_fini(void)
Definition: fid.c:289
M0_INTERNAL int m0_fid_cmp(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:170
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
static struct foo * obj
Definition: tlist.c:302
#define PRIx64
Definition: types.h:61
struct m0_fid fid
Definition: di.c:46
return M0_RC(rc)
static const struct m0_uint128 zero
Definition: misc.c:41
int i
Definition: dir.c:1033
int(* xto_read)(const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str)
Definition: xcode.h:379
#define FID_S(f)
Definition: fid.h:78
M0_INTERNAL void m0_fid_set(struct m0_fid *fid, uint64_t container, uint64_t key)
Definition: fid.c:116
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_fid_type_register(const struct m0_fid_type *fidt)
Definition: fid.c:46
static int key
Definition: locality.c:283
const char * name
Definition: trace.c:110
#define M0_ASSERT(cond)
M0_INTERNAL void m0_fid_tgenerate(struct m0_fid *fid, const uint8_t tid)
Definition: fid.c:155
M0_INTERNAL const struct m0_fid_type * m0_fid_type_gethi(uint64_t id)
Definition: fid.c:70
static const struct m0_xcode_type_ops xt_ops
Definition: fid.c:277
uint64_t u_hi
Definition: types.h:36
M0_INTERNAL const struct m0_fid_type * m0_fid_type_getfid(const struct m0_fid *fid)
Definition: fid.c:76
#define SCNi64
Definition: types.h:63
Definition: fid.h:43
uint64_t f_container
Definition: fid.h:39
#define M0_POST(cond)
M0_INTERNAL int m0_fid_print(char *s, size_t s_len, const struct m0_fid *fid)
Definition: fid.c:233
M0_INTERNAL void m0_fid_type_unregister(const struct m0_fid_type *fidt)
Definition: fid.c:55
M0_INTERNAL bool m0_fid_arr_eq(const struct m0_fid_arr *a, const struct m0_fid_arr *b)
Definition: fid.c:319
M0_INTERNAL int m0_fid_sscanf(const char *s, struct m0_fid *fid)
Definition: fid.c:227
M0_INTERNAL const struct m0_fid_type * m0_fid_type_getname(const char *name)
Definition: fid.c:81
#define FID_P(f)
Definition: fid.h:77
#define M0_CIRCULAR_SHIFT_LEFT(val, bits)
Definition: misc.h:403
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define m0_forall(var, nr,...)
Definition: misc.h:112
const char * ft_name
Definition: fid.h:102
static const struct m0_fid_type misc
Definition: fid.c:251
static int fid_sscanf(const char *s, struct m0_fid *fid, int *nob)
Definition: fid.c:199
M0_INTERNAL void m0_fid_tchange(struct m0_fid *fid, uint8_t tid)
Definition: fid.c:139
Definition: fid.h:38
uint64_t f_key
Definition: fid.h:40
M0_INTERNAL int m0_fid_arr_copy(struct m0_fid_arr *to, const struct m0_fid_arr *from)
Definition: fid.c:303
#define IS_IN_ARRAY(idx, array)
Definition: misc.h:311
static struct m0_fop_type * ft[]
Definition: service_ut.c:856
static int xt_read(const struct m0_xcode_cursor *it, struct m0_xcode_obj *obj, const char *str)
Definition: fid.c:263
M0_INTERNAL bool m0_fid_is_valid(const struct m0_fid *fid)
Definition: fid.c:96
static struct m0_addb2_source * s
Definition: consumer.c:39
M0_INTERNAL bool m0_fid_arr_all_unique(const struct m0_fid_arr *a)
Definition: fid.c:327
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
uint32_t af_count
Definition: fid.h:44
Definition: idx_mock.c:47
M0_INTERNAL uint64_t m0_hash(uint64_t x)
Definition: hash.c:279
M0_INTERNAL void m0_fid_tassume(struct m0_fid *fid, const struct m0_fid_type *ft)
Definition: fid.c:146
M0_INTERNAL int m0_fid_init(void)
Definition: fid.c:281