Merge tag 'for-6.9-part2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.git] / fs / btrfs / rcu-string.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2012 Red Hat.  All rights reserved.
4  */
5
6 #ifndef BTRFS_RCU_STRING_H
7 #define BTRFS_RCU_STRING_H
8
9 #include <linux/types.h>
10 #include <linux/string.h>
11 #include <linux/slab.h>
12 #include <linux/rcupdate.h>
13 #include <linux/printk.h>
14
15 struct rcu_string {
16         struct rcu_head rcu;
17         char str[];
18 };
19
20 static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask)
21 {
22         size_t len = strlen(src) + 1;
23         struct rcu_string *ret = kzalloc(sizeof(struct rcu_string) +
24                                          (len * sizeof(char)), mask);
25         if (!ret)
26                 return ret;
27         /* Warn if the source got unexpectedly truncated. */
28         if (WARN_ON(strscpy(ret->str, src, len) < 0)) {
29                 kfree(ret);
30                 return NULL;
31         }
32         return ret;
33 }
34
35 static inline void rcu_string_free(struct rcu_string *str)
36 {
37         if (str)
38                 kfree_rcu(str, rcu);
39 }
40
41 #define printk_in_rcu(fmt, ...) do {    \
42         rcu_read_lock();                \
43         printk(fmt, __VA_ARGS__);       \
44         rcu_read_unlock();              \
45 } while (0)
46
47 #define printk_ratelimited_in_rcu(fmt, ...) do {        \
48         rcu_read_lock();                                \
49         printk_ratelimited(fmt, __VA_ARGS__);           \
50         rcu_read_unlock();                              \
51 } while (0)
52
53 #define rcu_str_deref(rcu_str) ({                               \
54         struct rcu_string *__str = rcu_dereference(rcu_str);    \
55         __str->str;                                             \
56 })
57
58 #endif