1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
251e92737SYan, Zheng #ifndef _FS_CEPH_STRING_TABLE_H
351e92737SYan, Zheng #define _FS_CEPH_STRING_TABLE_H
451e92737SYan, Zheng 
551e92737SYan, Zheng #include <linux/types.h>
651e92737SYan, Zheng #include <linux/kref.h>
751e92737SYan, Zheng #include <linux/rbtree.h>
851e92737SYan, Zheng #include <linux/rcupdate.h>
951e92737SYan, Zheng 
1051e92737SYan, Zheng struct ceph_string {
1151e92737SYan, Zheng 	struct kref kref;
1251e92737SYan, Zheng 	union {
1351e92737SYan, Zheng 		struct rb_node node;
1451e92737SYan, Zheng 		struct rcu_head rcu;
1551e92737SYan, Zheng 	};
1651e92737SYan, Zheng 	size_t len;
1751e92737SYan, Zheng 	char str[];
1851e92737SYan, Zheng };
1951e92737SYan, Zheng 
2051e92737SYan, Zheng extern void ceph_release_string(struct kref *ref);
2151e92737SYan, Zheng extern struct ceph_string *ceph_find_or_create_string(const char *str,
2251e92737SYan, Zheng 						      size_t len);
2351e92737SYan, Zheng extern bool ceph_strings_empty(void);
2451e92737SYan, Zheng 
ceph_get_string(struct ceph_string * str)2551e92737SYan, Zheng static inline struct ceph_string *ceph_get_string(struct ceph_string *str)
2651e92737SYan, Zheng {
2751e92737SYan, Zheng 	kref_get(&str->kref);
2851e92737SYan, Zheng 	return str;
2951e92737SYan, Zheng }
3051e92737SYan, Zheng 
ceph_put_string(struct ceph_string * str)3151e92737SYan, Zheng static inline void ceph_put_string(struct ceph_string *str)
3251e92737SYan, Zheng {
3351e92737SYan, Zheng 	if (!str)
3451e92737SYan, Zheng 		return;
3551e92737SYan, Zheng 	kref_put(&str->kref, ceph_release_string);
3651e92737SYan, Zheng }
3751e92737SYan, Zheng 
ceph_compare_string(struct ceph_string * cs,const char * str,size_t len)3851e92737SYan, Zheng static inline int ceph_compare_string(struct ceph_string *cs,
3951e92737SYan, Zheng 				      const char* str, size_t len)
4051e92737SYan, Zheng {
4151e92737SYan, Zheng 	size_t cs_len = cs ? cs->len : 0;
4251e92737SYan, Zheng 	if (cs_len != len)
4351e92737SYan, Zheng 		return cs_len - len;
4451e92737SYan, Zheng 	if (len == 0)
4551e92737SYan, Zheng 		return 0;
4651e92737SYan, Zheng 	return strncmp(cs->str, str, len);
4751e92737SYan, Zheng }
4851e92737SYan, Zheng 
4951e92737SYan, Zheng #define ceph_try_get_string(x)					\
5051e92737SYan, Zheng ({								\
5151e92737SYan, Zheng 	struct ceph_string *___str;				\
5251e92737SYan, Zheng 	rcu_read_lock();					\
5351e92737SYan, Zheng 	for (;;) {						\
5451e92737SYan, Zheng 		___str = rcu_dereference(x);			\
5551e92737SYan, Zheng 		if (!___str ||					\
5651e92737SYan, Zheng 		    kref_get_unless_zero(&___str->kref))	\
5751e92737SYan, Zheng 			break;					\
5851e92737SYan, Zheng 	}							\
5951e92737SYan, Zheng 	rcu_read_unlock();					\
6051e92737SYan, Zheng 	(___str);						\
6151e92737SYan, Zheng })
6251e92737SYan, Zheng 
6351e92737SYan, Zheng #endif
64