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