aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/linear.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/linear.c')
-rw-r--r--drivers/md/linear.c67
1 files changed, 20 insertions, 47 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 64713b77df1c..fa7d577f3d12 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -34,7 +34,7 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
34 34
35 lo = 0; 35 lo = 0;
36 hi = mddev->raid_disks - 1; 36 hi = mddev->raid_disks - 1;
37 conf = rcu_dereference(mddev->private); 37 conf = mddev->private;
38 38
39 /* 39 /*
40 * Binary Search 40 * Binary Search
@@ -60,18 +60,16 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
60 * 60 *
61 * Return amount of bytes we can take at this offset 61 * Return amount of bytes we can take at this offset
62 */ 62 */
63static int linear_mergeable_bvec(struct request_queue *q, 63static int linear_mergeable_bvec(struct mddev *mddev,
64 struct bvec_merge_data *bvm, 64 struct bvec_merge_data *bvm,
65 struct bio_vec *biovec) 65 struct bio_vec *biovec)
66{ 66{
67 struct mddev *mddev = q->queuedata;
68 struct dev_info *dev0; 67 struct dev_info *dev0;
69 unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9; 68 unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9;
70 sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); 69 sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
71 int maxbytes = biovec->bv_len; 70 int maxbytes = biovec->bv_len;
72 struct request_queue *subq; 71 struct request_queue *subq;
73 72
74 rcu_read_lock();
75 dev0 = which_dev(mddev, sector); 73 dev0 = which_dev(mddev, sector);
76 maxsectors = dev0->end_sector - sector; 74 maxsectors = dev0->end_sector - sector;
77 subq = bdev_get_queue(dev0->rdev->bdev); 75 subq = bdev_get_queue(dev0->rdev->bdev);
@@ -81,7 +79,6 @@ static int linear_mergeable_bvec(struct request_queue *q,
81 maxbytes = min(maxbytes, subq->merge_bvec_fn(subq, bvm, 79 maxbytes = min(maxbytes, subq->merge_bvec_fn(subq, bvm,
82 biovec)); 80 biovec));
83 } 81 }
84 rcu_read_unlock();
85 82
86 if (maxsectors < bio_sectors) 83 if (maxsectors < bio_sectors)
87 maxsectors = 0; 84 maxsectors = 0;
@@ -97,24 +94,18 @@ static int linear_mergeable_bvec(struct request_queue *q,
97 return maxsectors << 9; 94 return maxsectors << 9;
98} 95}
99 96
100static int linear_congested(void *data, int bits) 97static int linear_congested(struct mddev *mddev, int bits)
101{ 98{
102 struct mddev *mddev = data;
103 struct linear_conf *conf; 99 struct linear_conf *conf;
104 int i, ret = 0; 100 int i, ret = 0;
105 101
106 if (mddev_congested(mddev, bits)) 102 conf = mddev->private;
107 return 1;
108
109 rcu_read_lock();
110 conf = rcu_dereference(mddev->private);
111 103
112 for (i = 0; i < mddev->raid_disks && !ret ; i++) { 104 for (i = 0; i < mddev->raid_disks && !ret ; i++) {
113 struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev); 105 struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
114 ret |= bdi_congested(&q->backing_dev_info, bits); 106 ret |= bdi_congested(&q->backing_dev_info, bits);
115 } 107 }
116 108
117 rcu_read_unlock();
118 return ret; 109 return ret;
119} 110}
120 111
@@ -123,12 +114,10 @@ static sector_t linear_size(struct mddev *mddev, sector_t sectors, int raid_disk
123 struct linear_conf *conf; 114 struct linear_conf *conf;
124 sector_t array_sectors; 115 sector_t array_sectors;
125 116
126 rcu_read_lock(); 117 conf = mddev->private;
127 conf = rcu_dereference(mddev->private);
128 WARN_ONCE(sectors || raid_disks, 118 WARN_ONCE(sectors || raid_disks,
129 "%s does not support generic reshape\n", __func__); 119 "%s does not support generic reshape\n", __func__);
130 array_sectors = conf->array_sectors; 120 array_sectors = conf->array_sectors;
131 rcu_read_unlock();
132 121
133 return array_sectors; 122 return array_sectors;
134} 123}
@@ -217,10 +206,6 @@ static int linear_run (struct mddev *mddev)
217 mddev->private = conf; 206 mddev->private = conf;
218 md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); 207 md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
219 208
220 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
221 mddev->queue->backing_dev_info.congested_fn = linear_congested;
222 mddev->queue->backing_dev_info.congested_data = mddev;
223
224 ret = md_integrity_register(mddev); 209 ret = md_integrity_register(mddev);
225 if (ret) { 210 if (ret) {
226 kfree(conf); 211 kfree(conf);
@@ -252,38 +237,23 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
252 if (!newconf) 237 if (!newconf)
253 return -ENOMEM; 238 return -ENOMEM;
254 239
255 oldconf = rcu_dereference_protected(mddev->private, 240 mddev_suspend(mddev);
256 lockdep_is_held( 241 oldconf = mddev->private;
257 &mddev->reconfig_mutex));
258 mddev->raid_disks++; 242 mddev->raid_disks++;
259 rcu_assign_pointer(mddev->private, newconf); 243 mddev->private = newconf;
260 md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); 244 md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
261 set_capacity(mddev->gendisk, mddev->array_sectors); 245 set_capacity(mddev->gendisk, mddev->array_sectors);
246 mddev_resume(mddev);
262 revalidate_disk(mddev->gendisk); 247 revalidate_disk(mddev->gendisk);
263 kfree_rcu(oldconf, rcu); 248 kfree(oldconf);
264 return 0; 249 return 0;
265} 250}
266 251
267static int linear_stop (struct mddev *mddev) 252static void linear_free(struct mddev *mddev, void *priv)
268{ 253{
269 struct linear_conf *conf = 254 struct linear_conf *conf = priv;
270 rcu_dereference_protected(mddev->private,
271 lockdep_is_held(
272 &mddev->reconfig_mutex));
273 255
274 /*
275 * We do not require rcu protection here since
276 * we hold reconfig_mutex for both linear_add and
277 * linear_stop, so they cannot race.
278 * We should make sure any old 'conf's are properly
279 * freed though.
280 */
281 rcu_barrier();
282 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
283 kfree(conf); 256 kfree(conf);
284 mddev->private = NULL;
285
286 return 0;
287} 257}
288 258
289static void linear_make_request(struct mddev *mddev, struct bio *bio) 259static void linear_make_request(struct mddev *mddev, struct bio *bio)
@@ -299,16 +269,12 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio)
299 } 269 }
300 270
301 do { 271 do {
302 rcu_read_lock();
303
304 tmp_dev = which_dev(mddev, bio->bi_iter.bi_sector); 272 tmp_dev = which_dev(mddev, bio->bi_iter.bi_sector);
305 start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors; 273 start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
306 end_sector = tmp_dev->end_sector; 274 end_sector = tmp_dev->end_sector;
307 data_offset = tmp_dev->rdev->data_offset; 275 data_offset = tmp_dev->rdev->data_offset;
308 bio->bi_bdev = tmp_dev->rdev->bdev; 276 bio->bi_bdev = tmp_dev->rdev->bdev;
309 277
310 rcu_read_unlock();
311
312 if (unlikely(bio->bi_iter.bi_sector >= end_sector || 278 if (unlikely(bio->bi_iter.bi_sector >= end_sector ||
313 bio->bi_iter.bi_sector < start_sector)) 279 bio->bi_iter.bi_sector < start_sector))
314 goto out_of_bounds; 280 goto out_of_bounds;
@@ -355,6 +321,10 @@ static void linear_status (struct seq_file *seq, struct mddev *mddev)
355 seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2); 321 seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2);
356} 322}
357 323
324static void linear_quiesce(struct mddev *mddev, int state)
325{
326}
327
358static struct md_personality linear_personality = 328static struct md_personality linear_personality =
359{ 329{
360 .name = "linear", 330 .name = "linear",
@@ -362,10 +332,13 @@ static struct md_personality linear_personality =
362 .owner = THIS_MODULE, 332 .owner = THIS_MODULE,
363 .make_request = linear_make_request, 333 .make_request = linear_make_request,
364 .run = linear_run, 334 .run = linear_run,
365 .stop = linear_stop, 335 .free = linear_free,
366 .status = linear_status, 336 .status = linear_status,
367 .hot_add_disk = linear_add, 337 .hot_add_disk = linear_add,
368 .size = linear_size, 338 .size = linear_size,
339 .quiesce = linear_quiesce,
340 .congested = linear_congested,
341 .mergeable_bvec = linear_mergeable_bvec,
369}; 342};
370 343
371static int __init linear_init (void) 344static int __init linear_init (void)