18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2012 Red Hat. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef BTRFS_RCU_STRING_H 78c2ecf20Sopenharmony_ci#define BTRFS_RCU_STRING_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct rcu_string { 108c2ecf20Sopenharmony_ci struct rcu_head rcu; 118c2ecf20Sopenharmony_ci char str[]; 128c2ecf20Sopenharmony_ci}; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci size_t len = strlen(src) + 1; 178c2ecf20Sopenharmony_ci struct rcu_string *ret = kzalloc(sizeof(struct rcu_string) + 188c2ecf20Sopenharmony_ci (len * sizeof(char)), mask); 198c2ecf20Sopenharmony_ci if (!ret) 208c2ecf20Sopenharmony_ci return ret; 218c2ecf20Sopenharmony_ci /* Warn if the source got unexpectedly truncated. */ 228c2ecf20Sopenharmony_ci if (WARN_ON(strscpy(ret->str, src, len) < 0)) { 238c2ecf20Sopenharmony_ci kfree(ret); 248c2ecf20Sopenharmony_ci return NULL; 258c2ecf20Sopenharmony_ci } 268c2ecf20Sopenharmony_ci return ret; 278c2ecf20Sopenharmony_ci} 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic inline void rcu_string_free(struct rcu_string *str) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci if (str) 328c2ecf20Sopenharmony_ci kfree_rcu(str, rcu); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define printk_in_rcu(fmt, ...) do { \ 368c2ecf20Sopenharmony_ci rcu_read_lock(); \ 378c2ecf20Sopenharmony_ci printk(fmt, __VA_ARGS__); \ 388c2ecf20Sopenharmony_ci rcu_read_unlock(); \ 398c2ecf20Sopenharmony_ci} while (0) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define printk_ratelimited_in_rcu(fmt, ...) do { \ 428c2ecf20Sopenharmony_ci rcu_read_lock(); \ 438c2ecf20Sopenharmony_ci printk_ratelimited(fmt, __VA_ARGS__); \ 448c2ecf20Sopenharmony_ci rcu_read_unlock(); \ 458c2ecf20Sopenharmony_ci} while (0) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define rcu_str_deref(rcu_str) ({ \ 488c2ecf20Sopenharmony_ci struct rcu_string *__str = rcu_dereference(rcu_str); \ 498c2ecf20Sopenharmony_ci __str->str; \ 508c2ecf20Sopenharmony_ci}) 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#endif 53