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