]>
Commit | Line | Data |
---|---|---|
4100f35f GKH |
1 | From 9567366fefddeaea4ed1d713270535d93a3b3c76 Mon Sep 17 00:00:00 2001 |
2 | From: Mike Snitzer <snitzer@redhat.com> | |
3 | Date: Tue, 12 Apr 2016 12:14:46 -0400 | |
4 | Subject: dm cache metadata: fix READ_LOCK macros and cleanup WRITE_LOCK macros | |
5 | ||
6 | From: Mike Snitzer <snitzer@redhat.com> | |
7 | ||
8 | commit 9567366fefddeaea4ed1d713270535d93a3b3c76 upstream. | |
9 | ||
10 | The READ_LOCK macro was incorrectly returning -EINVAL if | |
11 | dm_bm_is_read_only() was true -- it will always be true once the cache | |
12 | metadata transitions to read-only by dm_cache_metadata_set_read_only(). | |
13 | ||
14 | Wrap READ_LOCK and WRITE_LOCK multi-statement macros in do {} while(0). | |
15 | Also, all accesses of the 'cmd' argument passed to these related macros | |
16 | are now encapsulated in parenthesis. | |
17 | ||
18 | A follow-up patch can be developed to eliminate the use of macros in | |
19 | favor of pure C code. Avoiding that now given that this needs to apply | |
20 | to stable@. | |
21 | ||
22 | Reported-by: Ben Hutchings <ben@decadent.org.uk> | |
23 | Signed-off-by: Mike Snitzer <snitzer@redhat.com> | |
24 | Fixes: d14fcf3dd79 ("dm cache: make sure every metadata function checks fail_io") | |
25 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
26 | ||
27 | --- | |
28 | drivers/md/dm-cache-metadata.c | 64 +++++++++++++++++++++++++---------------- | |
29 | 1 file changed, 40 insertions(+), 24 deletions(-) | |
30 | ||
31 | --- a/drivers/md/dm-cache-metadata.c | |
32 | +++ b/drivers/md/dm-cache-metadata.c | |
33 | @@ -867,39 +867,55 @@ static int blocks_are_unmapped_or_clean( | |
34 | return 0; | |
35 | } | |
36 | ||
37 | -#define WRITE_LOCK(cmd) \ | |
38 | - down_write(&cmd->root_lock); \ | |
39 | - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | |
40 | - up_write(&cmd->root_lock); \ | |
41 | - return -EINVAL; \ | |
42 | +static bool cmd_write_lock(struct dm_cache_metadata *cmd) | |
43 | +{ | |
44 | + down_write(&cmd->root_lock); | |
45 | + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { | |
46 | + up_write(&cmd->root_lock); | |
47 | + return false; | |
48 | } | |
49 | + return true; | |
50 | +} | |
51 | ||
52 | -#define WRITE_LOCK_VOID(cmd) \ | |
53 | - down_write(&cmd->root_lock); \ | |
54 | - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | |
55 | - up_write(&cmd->root_lock); \ | |
56 | - return; \ | |
57 | - } | |
58 | +#define WRITE_LOCK(cmd) \ | |
59 | + do { \ | |
60 | + if (!cmd_write_lock((cmd))) \ | |
61 | + return -EINVAL; \ | |
62 | + } while(0) | |
63 | + | |
64 | +#define WRITE_LOCK_VOID(cmd) \ | |
65 | + do { \ | |
66 | + if (!cmd_write_lock((cmd))) \ | |
67 | + return; \ | |
68 | + } while(0) | |
69 | ||
70 | #define WRITE_UNLOCK(cmd) \ | |
71 | - up_write(&cmd->root_lock) | |
72 | + up_write(&(cmd)->root_lock) | |
73 | ||
74 | -#define READ_LOCK(cmd) \ | |
75 | - down_read(&cmd->root_lock); \ | |
76 | - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | |
77 | - up_read(&cmd->root_lock); \ | |
78 | - return -EINVAL; \ | |
79 | +static bool cmd_read_lock(struct dm_cache_metadata *cmd) | |
80 | +{ | |
81 | + down_write(&cmd->root_lock); | |
82 | + if (cmd->fail_io) { | |
83 | + up_write(&cmd->root_lock); | |
84 | + return false; | |
85 | } | |
86 | + return true; | |
87 | +} | |
88 | ||
89 | -#define READ_LOCK_VOID(cmd) \ | |
90 | - down_read(&cmd->root_lock); \ | |
91 | - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ | |
92 | - up_read(&cmd->root_lock); \ | |
93 | - return; \ | |
94 | - } | |
95 | +#define READ_LOCK(cmd) \ | |
96 | + do { \ | |
97 | + if (!cmd_read_lock((cmd))) \ | |
98 | + return -EINVAL; \ | |
99 | + } while(0) | |
100 | + | |
101 | +#define READ_LOCK_VOID(cmd) \ | |
102 | + do { \ | |
103 | + if (!cmd_read_lock((cmd))) \ | |
104 | + return; \ | |
105 | + } while(0) | |
106 | ||
107 | #define READ_UNLOCK(cmd) \ | |
108 | - up_read(&cmd->root_lock) | |
109 | + up_read(&(cmd)->root_lock) | |
110 | ||
111 | int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size) | |
112 | { |