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 
ceph_get_string(struct ceph_string * str)25 static inline struct ceph_string *ceph_get_string(struct ceph_string *str)
26 {
27 	kref_get(&str->kref);
28 	return str;
29 }
30 
ceph_put_string(struct ceph_string * str)31 static inline void ceph_put_string(struct ceph_string *str)
32 {
33 	if (!str)
34 		return;
35 	kref_put(&str->kref, ceph_release_string);
36 }
37 
ceph_compare_string(struct ceph_string * cs,const char * str,size_t len)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