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 15struct rcu_string { 16 struct rcu_head rcu; 17 char str[]; 18}; 19 20static 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 35static 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 59