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/check-integrity.c | |
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/check-integrity.c')
-rw-r--r-- | fs/btrfs/check-integrity.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index 9cebb1fd6a3c..da6e9364a5e3 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -93,6 +93,7 @@ | |||
93 | #include "print-tree.h" | 93 | #include "print-tree.h" |
94 | #include "locking.h" | 94 | #include "locking.h" |
95 | #include "check-integrity.h" | 95 | #include "check-integrity.h" |
96 | #include "rcu-string.h" | ||
96 | 97 | ||
97 | #define BTRFSIC_BLOCK_HASHTABLE_SIZE 0x10000 | 98 | #define BTRFSIC_BLOCK_HASHTABLE_SIZE 0x10000 |
98 | #define BTRFSIC_BLOCK_LINK_HASHTABLE_SIZE 0x10000 | 99 | #define BTRFSIC_BLOCK_LINK_HASHTABLE_SIZE 0x10000 |
@@ -843,13 +844,14 @@ static int btrfsic_process_superblock_dev_mirror( | |||
843 | superblock_tmp->never_written = 0; | 844 | superblock_tmp->never_written = 0; |
844 | superblock_tmp->mirror_num = 1 + superblock_mirror_num; | 845 | superblock_tmp->mirror_num = 1 + superblock_mirror_num; |
845 | if (state->print_mask & BTRFSIC_PRINT_MASK_SUPERBLOCK_WRITE) | 846 | if (state->print_mask & BTRFSIC_PRINT_MASK_SUPERBLOCK_WRITE) |
846 | printk(KERN_INFO "New initial S-block (bdev %p, %s)" | 847 | printk_in_rcu(KERN_INFO "New initial S-block (bdev %p, %s)" |
847 | " @%llu (%s/%llu/%d)\n", | 848 | " @%llu (%s/%llu/%d)\n", |
848 | superblock_bdev, device->name, | 849 | superblock_bdev, |
849 | (unsigned long long)dev_bytenr, | 850 | rcu_str_deref(device->name), |
850 | dev_state->name, | 851 | (unsigned long long)dev_bytenr, |
851 | (unsigned long long)dev_bytenr, | 852 | dev_state->name, |
852 | superblock_mirror_num); | 853 | (unsigned long long)dev_bytenr, |
854 | superblock_mirror_num); | ||
853 | list_add(&superblock_tmp->all_blocks_node, | 855 | list_add(&superblock_tmp->all_blocks_node, |
854 | &state->all_blocks_list); | 856 | &state->all_blocks_list); |
855 | btrfsic_block_hashtable_add(superblock_tmp, | 857 | btrfsic_block_hashtable_add(superblock_tmp, |