]>
Commit | Line | Data |
---|---|---|
3f652c1e GKH |
1 | From c80e299925d45086b9fc252e3c67c4e98fb5ab65 Mon Sep 17 00:00:00 2001 |
2 | From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
3 | Date: Mon, 29 Apr 2019 15:56:26 +0200 | |
4 | Subject: Revert "block/loop: Use global lock for ioctl() operation." | |
5 | ||
6 | From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
7 | ||
8 | This reverts commit b3f3107fbd928fed6e4fecbe3da2ed5f43216439 which is | |
9 | commit 310ca162d779efee8a2dc3731439680f3e9c1e86 upstream. | |
10 | ||
11 | Jan Kara has reported seeing problems with this patch applied, as has | |
12 | Salvatore Bonaccorso, so let's drop it for now. | |
13 | ||
14 | Reported-by: Salvatore Bonaccorso <carnil@debian.org> | |
15 | Reported-by: Jan Kara <jack@suse.cz> | |
16 | Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | |
17 | Cc: Jens Axboe <axboe@kernel.dk> | |
18 | Signed-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; |