]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - queue-4.4/revert-block-loop-use-global-lock-for-ioctl-operation.patch
4.4-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.4 / revert-block-loop-use-global-lock-for-ioctl-operation.patch
CommitLineData
3f652c1e
GKH
1From c80e299925d45086b9fc252e3c67c4e98fb5ab65 Mon Sep 17 00:00:00 2001
2From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
3Date: Mon, 29 Apr 2019 15:56:26 +0200
4Subject: Revert "block/loop: Use global lock for ioctl() operation."
5
6From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7
8This reverts commit b3f3107fbd928fed6e4fecbe3da2ed5f43216439 which is
9commit 310ca162d779efee8a2dc3731439680f3e9c1e86 upstream.
10
11Jan Kara has reported seeing problems with this patch applied, as has
12Salvatore Bonaccorso, so let's drop it for now.
13
14Reported-by: Salvatore Bonaccorso <carnil@debian.org>
15Reported-by: Jan Kara <jack@suse.cz>
16Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
17Cc: Jens Axboe <axboe@kernel.dk>
18Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19---
20 drivers/block/loop.c | 42 +++++++++++++++++++++---------------------
21 drivers/block/loop.h | 1 +
22 2 files changed, 22 insertions(+), 21 deletions(-)
23
24--- a/drivers/block/loop.c
25+++ b/drivers/block/loop.c
26@@ -82,7 +82,6 @@
27
28 static DEFINE_IDR(loop_index_idr);
29 static DEFINE_MUTEX(loop_index_mutex);
30-static DEFINE_MUTEX(loop_ctl_mutex);
31
32 static int max_part;
33 static int part_shift;
34@@ -1045,7 +1044,7 @@ static int loop_clr_fd(struct loop_devic
35 */
36 if (atomic_read(&lo->lo_refcnt) > 1) {
37 lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
38- mutex_unlock(&loop_ctl_mutex);
39+ mutex_unlock(&lo->lo_ctl_mutex);
40 return 0;
41 }
42
43@@ -1094,12 +1093,12 @@ static int loop_clr_fd(struct loop_devic
44 if (!part_shift)
45 lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
46 loop_unprepare_queue(lo);
47- mutex_unlock(&loop_ctl_mutex);
48+ mutex_unlock(&lo->lo_ctl_mutex);
49 /*
50- * Need not hold loop_ctl_mutex to fput backing file.
51- * Calling fput holding loop_ctl_mutex triggers a circular
52+ * Need not hold lo_ctl_mutex to fput backing file.
53+ * Calling fput holding lo_ctl_mutex triggers a circular
54 * lock dependency possibility warning as fput can take
55- * bd_mutex which is usually taken before loop_ctl_mutex.
56+ * bd_mutex which is usually taken before lo_ctl_mutex.
57 */
58 fput(filp);
59 return 0;
60@@ -1362,7 +1361,7 @@ static int lo_ioctl(struct block_device
61 struct loop_device *lo = bdev->bd_disk->private_data;
62 int err;
63
64- mutex_lock_nested(&loop_ctl_mutex, 1);
65+ mutex_lock_nested(&lo->lo_ctl_mutex, 1);
66 switch (cmd) {
67 case LOOP_SET_FD:
68 err = loop_set_fd(lo, mode, bdev, arg);
69@@ -1371,7 +1370,7 @@ static int lo_ioctl(struct block_device
70 err = loop_change_fd(lo, bdev, arg);
71 break;
72 case LOOP_CLR_FD:
73- /* loop_clr_fd would have unlocked loop_ctl_mutex on success */
74+ /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
75 err = loop_clr_fd(lo);
76 if (!err)
77 goto out_unlocked;
78@@ -1407,7 +1406,7 @@ static int lo_ioctl(struct block_device
79 default:
80 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
81 }
82- mutex_unlock(&loop_ctl_mutex);
83+ mutex_unlock(&lo->lo_ctl_mutex);
84
85 out_unlocked:
86 return err;
87@@ -1540,16 +1539,16 @@ static int lo_compat_ioctl(struct block_
88
89 switch(cmd) {
90 case LOOP_SET_STATUS:
91- mutex_lock(&loop_ctl_mutex);
92+ mutex_lock(&lo->lo_ctl_mutex);
93 err = loop_set_status_compat(
94 lo, (const struct compat_loop_info __user *) arg);
95- mutex_unlock(&loop_ctl_mutex);
96+ mutex_unlock(&lo->lo_ctl_mutex);
97 break;
98 case LOOP_GET_STATUS:
99- mutex_lock(&loop_ctl_mutex);
100+ mutex_lock(&lo->lo_ctl_mutex);
101 err = loop_get_status_compat(
102 lo, (struct compat_loop_info __user *) arg);
103- mutex_unlock(&loop_ctl_mutex);
104+ mutex_unlock(&lo->lo_ctl_mutex);
105 break;
106 case LOOP_SET_CAPACITY:
107 case LOOP_CLR_FD:
108@@ -1593,7 +1592,7 @@ static void __lo_release(struct loop_dev
109 if (atomic_dec_return(&lo->lo_refcnt))
110 return;
111
112- mutex_lock(&loop_ctl_mutex);
113+ mutex_lock(&lo->lo_ctl_mutex);
114 if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
115 /*
116 * In autoclear mode, stop the loop thread
117@@ -1610,7 +1609,7 @@ static void __lo_release(struct loop_dev
118 loop_flush(lo);
119 }
120
121- mutex_unlock(&loop_ctl_mutex);
122+ mutex_unlock(&lo->lo_ctl_mutex);
123 }
124
125 static void lo_release(struct gendisk *disk, fmode_t mode)
126@@ -1656,10 +1655,10 @@ static int unregister_transfer_cb(int id
127 struct loop_device *lo = ptr;
128 struct loop_func_table *xfer = data;
129
130- mutex_lock(&loop_ctl_mutex);
131+ mutex_lock(&lo->lo_ctl_mutex);
132 if (lo->lo_encryption == xfer)
133 loop_release_xfer(lo);
134- mutex_unlock(&loop_ctl_mutex);
135+ mutex_unlock(&lo->lo_ctl_mutex);
136 return 0;
137 }
138
139@@ -1821,6 +1820,7 @@ static int loop_add(struct loop_device *
140 if (!part_shift)
141 disk->flags |= GENHD_FL_NO_PART_SCAN;
142 disk->flags |= GENHD_FL_EXT_DEVT;
143+ mutex_init(&lo->lo_ctl_mutex);
144 atomic_set(&lo->lo_refcnt, 0);
145 lo->lo_number = i;
146 spin_lock_init(&lo->lo_lock);
147@@ -1933,19 +1933,19 @@ static long loop_control_ioctl(struct fi
148 ret = loop_lookup(&lo, parm);
149 if (ret < 0)
150 break;
151- mutex_lock(&loop_ctl_mutex);
152+ mutex_lock(&lo->lo_ctl_mutex);
153 if (lo->lo_state != Lo_unbound) {
154 ret = -EBUSY;
155- mutex_unlock(&loop_ctl_mutex);
156+ mutex_unlock(&lo->lo_ctl_mutex);
157 break;
158 }
159 if (atomic_read(&lo->lo_refcnt) > 0) {
160 ret = -EBUSY;
161- mutex_unlock(&loop_ctl_mutex);
162+ mutex_unlock(&lo->lo_ctl_mutex);
163 break;
164 }
165 lo->lo_disk->private_data = NULL;
166- mutex_unlock(&loop_ctl_mutex);
167+ mutex_unlock(&lo->lo_ctl_mutex);
168 idr_remove(&loop_index_idr, lo->lo_number);
169 loop_remove(lo);
170 break;
171--- a/drivers/block/loop.h
172+++ b/drivers/block/loop.h
173@@ -55,6 +55,7 @@ struct loop_device {
174
175 spinlock_t lo_lock;
176 int lo_state;
177+ struct mutex lo_ctl_mutex;
178 struct kthread_worker worker;
179 struct task_struct *worker_task;
180 bool use_dio;