1 | /* SPDX-License-Identifier: GPL-2.0 */ |
---|---|
2 | #ifndef _FS_CEPH_STRING_TABLE_H |
3 | #define _FS_CEPH_STRING_TABLE_H |
4 | |
5 | #include <linux/types.h> |
6 | #include <linux/kref.h> |
7 | #include <linux/rbtree.h> |
8 | #include <linux/rcupdate.h> |
9 | |
10 | struct ceph_string { |
11 | struct kref kref; |
12 | union { |
13 | struct rb_node node; |
14 | struct rcu_head rcu; |
15 | }; |
16 | size_t len; |
17 | char str[]; |
18 | }; |
19 | |
20 | extern void ceph_release_string(struct kref *ref); |
21 | extern struct ceph_string *ceph_find_or_create_string(const char *str, |
22 | size_t len); |
23 | extern bool ceph_strings_empty(void); |
24 | |
25 | static inline struct ceph_string *ceph_get_string(struct ceph_string *str) |
26 | { |
27 | kref_get(kref: &str->kref); |
28 | return str; |
29 | } |
30 | |
31 | static inline void ceph_put_string(struct ceph_string *str) |
32 | { |
33 | if (!str) |
34 | return; |
35 | kref_put(kref: &str->kref, release: ceph_release_string); |
36 | } |
37 | |
38 | static inline int ceph_compare_string(struct ceph_string *cs, |
39 | const char* str, size_t len) |
40 | { |
41 | size_t cs_len = cs ? cs->len : 0; |
42 | if (cs_len != len) |
43 | return cs_len - len; |
44 | if (len == 0) |
45 | return 0; |
46 | return strncmp(cs->str, str, len); |
47 | } |
48 | |
49 | #define ceph_try_get_string(x) \ |
50 | ({ \ |
51 | struct ceph_string *___str; \ |
52 | rcu_read_lock(); \ |
53 | for (;;) { \ |
54 | ___str = rcu_dereference(x); \ |
55 | if (!___str || \ |
56 | kref_get_unless_zero(&___str->kref)) \ |
57 | break; \ |
58 | } \ |
59 | rcu_read_unlock(); \ |
60 | (___str); \ |
61 | }) |
62 | |
63 | #endif |
64 |