diff options
author | Josef Bacik <josef@redhat.com> | 2012-06-04 14:03:51 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-06-14 21:29:16 -0400 |
commit | 606686eeac4550d2212bf3d621a810407ef5e9bf (patch) | |
tree | 50adade3a750137b68304dc280d7a75436417b12 /fs/btrfs/rcu-string.h | |
parent | 17ca04aff7e6171df684b7b65804df8830eb8c15 (diff) |
Btrfs: use rcu to protect device->name
Al pointed out that we can just toss out the old name on a device and add a
new one arbitrarily, so anybody who uses device->name in printk could
possibly use free'd memory. Instead of adding locking around all of this he
suggested doing it with RCU, so I've introduced a struct rcu_string that
does just that and have gone through and protected all accesses to
device->name that aren't under the uuid_mutex with rcu_read_lock(). This
protects us and I will use it for dealing with removing the device that we
used to mount the file system in a later patch. Thanks,
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/rcu-string.h')
-rw-r--r-- | fs/btrfs/rcu-string.h | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/fs/btrfs/rcu-string.h b/fs/btrfs/rcu-string.h new file mode 100644 index 000000000000..9e111e4576d4 --- /dev/null +++ b/fs/btrfs/rcu-string.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Red Hat. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | struct rcu_string { | ||
20 | struct rcu_head rcu; | ||
21 | char str[0]; | ||
22 | }; | ||
23 | |||
24 | static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask) | ||
25 | { | ||
26 | size_t len = strlen(src) + 1; | ||
27 | struct rcu_string *ret = kzalloc(sizeof(struct rcu_string) + | ||
28 | (len * sizeof(char)), mask); | ||
29 | if (!ret) | ||
30 | return ret; | ||
31 | strncpy(ret->str, src, len); | ||
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 | }) | ||