]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.9/dm-cache-metadata-fix-read_lock-macros-and-cleanup-write_lock-macros.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.9 / dm-cache-metadata-fix-read_lock-macros-and-cleanup-write_lock-macros.patch
CommitLineData
4100f35f
GKH
1From 9567366fefddeaea4ed1d713270535d93a3b3c76 Mon Sep 17 00:00:00 2001
2From: Mike Snitzer <snitzer@redhat.com>
3Date: Tue, 12 Apr 2016 12:14:46 -0400
4Subject: dm cache metadata: fix READ_LOCK macros and cleanup WRITE_LOCK macros
5
6From: Mike Snitzer <snitzer@redhat.com>
7
8commit 9567366fefddeaea4ed1d713270535d93a3b3c76 upstream.
9
10The READ_LOCK macro was incorrectly returning -EINVAL if
11dm_bm_is_read_only() was true -- it will always be true once the cache
12metadata transitions to read-only by dm_cache_metadata_set_read_only().
13
14Wrap READ_LOCK and WRITE_LOCK multi-statement macros in do {} while(0).
15Also, all accesses of the 'cmd' argument passed to these related macros
16are now encapsulated in parenthesis.
17
18A follow-up patch can be developed to eliminate the use of macros in
19favor of pure C code. Avoiding that now given that this needs to apply
20to stable@.
21
22Reported-by: Ben Hutchings <ben@decadent.org.uk>
23Signed-off-by: Mike Snitzer <snitzer@redhat.com>
24Fixes: d14fcf3dd79 ("dm cache: make sure every metadata function checks fail_io")
25Signed-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 {