0001
0002 #ifndef _FS_CEPH_STRING_TABLE_H
0003 #define _FS_CEPH_STRING_TABLE_H
0004
0005 #include <linux/types.h>
0006 #include <linux/kref.h>
0007 #include <linux/rbtree.h>
0008 #include <linux/rcupdate.h>
0009
0010 struct ceph_string {
0011 struct kref kref;
0012 union {
0013 struct rb_node node;
0014 struct rcu_head rcu;
0015 };
0016 size_t len;
0017 char str[];
0018 };
0019
0020 extern void ceph_release_string(struct kref *ref);
0021 extern struct ceph_string *ceph_find_or_create_string(const char *str,
0022 size_t len);
0023 extern bool ceph_strings_empty(void);
0024
0025 static inline struct ceph_string *ceph_get_string(struct ceph_string *str)
0026 {
0027 kref_get(&str->kref);
0028 return str;
0029 }
0030
0031 static inline void ceph_put_string(struct ceph_string *str)
0032 {
0033 if (!str)
0034 return;
0035 kref_put(&str->kref, ceph_release_string);
0036 }
0037
0038 static inline int ceph_compare_string(struct ceph_string *cs,
0039 const char* str, size_t len)
0040 {
0041 size_t cs_len = cs ? cs->len : 0;
0042 if (cs_len != len)
0043 return cs_len - len;
0044 if (len == 0)
0045 return 0;
0046 return strncmp(cs->str, str, len);
0047 }
0048
0049 #define ceph_try_get_string(x) \
0050 ({ \
0051 struct ceph_string *___str; \
0052 rcu_read_lock(); \
0053 for (;;) { \
0054 ___str = rcu_dereference(x); \
0055 if (!___str || \
0056 kref_get_unless_zero(&___str->kref)) \
0057 break; \
0058 } \
0059 rcu_read_unlock(); \
0060 (___str); \
0061 })
0062
0063 #endif