Skip to content

Commit 5d8e7fb

Browse files
committed
Merge tag 'md/3.20' of git://neil.brown.name/md
Pull md updates from Neil Brown: - assorted locking changes so that access to /proc/mdstat and much of /sys/block/mdXX/md/* is protected by a spinlock rather than a mutex and will never block indefinitely. - Make an 'if' condition in RAID5 - which has been implicated in recent bugs - more readable. - misc minor fixes * tag 'md/3.20' of git://neil.brown.name/md: (28 commits) md/raid10: fix conversion from RAID0 to RAID10 md: wakeup thread upon rdev_dec_pending() md: make reconfig_mutex optional for writes to md sysfs files. md: move mddev_lock and related to md.h md: use mddev->lock to protect updates to resync_{min,max}. md: minor cleanup in safe_delay_store. md: move GET_BITMAP_FILE ioctl out from mddev_lock. md: tidy up set_bitmap_file md: remove unnecessary 'buf' from get_bitmap_file. md: remove mddev_lock from rdev_attr_show() md: remove mddev_lock() from md_attr_show() md/raid5: use ->lock to protect accessing raid5 sysfs attributes. md: remove need for mddev_lock() in md_seq_show() md/bitmap: protect clearing of ->bitmap by mddev->lock md: protect ->pers changes with mddev->lock md: level_store: group all important changes into one place. md: rename ->stop to ->free md: split detach operation out from ->stop. md/linear: remove rcu protections in favour of suspend/resume md: make merge_bvec_fn more robust in face of personality changes. ...
2 parents 87c9172 + 53a6ab4 commit 5d8e7fb

File tree

18 files changed

+867
-608
lines changed

18 files changed

+867
-608
lines changed

arch/x86/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTI
148148

149149
# does binutils support specific instructions?
150150
asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1)
151+
asinstr += $(call as-instr,pshufb %xmm0$(comma)%xmm0,-DCONFIG_AS_SSSE3=1)
151152
asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1)
152153
avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1)
153154
avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1)

drivers/md/bitmap.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,9 @@ void bitmap_destroy(struct mddev *mddev)
16191619
return;
16201620

16211621
mutex_lock(&mddev->bitmap_info.mutex);
1622+
spin_lock(&mddev->lock);
16221623
mddev->bitmap = NULL; /* disconnect from the md device */
1624+
spin_unlock(&mddev->lock);
16231625
mutex_unlock(&mddev->bitmap_info.mutex);
16241626
if (mddev->thread)
16251627
mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
@@ -2209,11 +2211,13 @@ __ATTR(metadata, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
22092211
static ssize_t can_clear_show(struct mddev *mddev, char *page)
22102212
{
22112213
int len;
2214+
spin_lock(&mddev->lock);
22122215
if (mddev->bitmap)
22132216
len = sprintf(page, "%s\n", (mddev->bitmap->need_sync ?
22142217
"false" : "true"));
22152218
else
22162219
len = sprintf(page, "\n");
2220+
spin_unlock(&mddev->lock);
22172221
return len;
22182222
}
22192223

@@ -2238,10 +2242,15 @@ __ATTR(can_clear, S_IRUGO|S_IWUSR, can_clear_show, can_clear_store);
22382242
static ssize_t
22392243
behind_writes_used_show(struct mddev *mddev, char *page)
22402244
{
2245+
ssize_t ret;
2246+
spin_lock(&mddev->lock);
22412247
if (mddev->bitmap == NULL)
2242-
return sprintf(page, "0\n");
2243-
return sprintf(page, "%lu\n",
2244-
mddev->bitmap->behind_writes_used);
2248+
ret = sprintf(page, "0\n");
2249+
else
2250+
ret = sprintf(page, "%lu\n",
2251+
mddev->bitmap->behind_writes_used);
2252+
spin_unlock(&mddev->lock);
2253+
return ret;
22452254
}
22462255

22472256
static ssize_t

drivers/md/dm-raid.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -746,13 +746,7 @@ static int raid_is_congested(struct dm_target_callbacks *cb, int bits)
746746
{
747747
struct raid_set *rs = container_of(cb, struct raid_set, callbacks);
748748

749-
if (rs->raid_type->level == 1)
750-
return md_raid1_congested(&rs->md, bits);
751-
752-
if (rs->raid_type->level == 10)
753-
return md_raid10_congested(&rs->md, bits);
754-
755-
return md_raid5_congested(&rs->md, bits);
749+
return mddev_congested(&rs->md, bits);
756750
}
757751

758752
/*

drivers/md/faulty.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,11 @@ static int run(struct mddev *mddev)
332332
return 0;
333333
}
334334

335-
static int stop(struct mddev *mddev)
335+
static void faulty_free(struct mddev *mddev, void *priv)
336336
{
337-
struct faulty_conf *conf = mddev->private;
337+
struct faulty_conf *conf = priv;
338338

339339
kfree(conf);
340-
mddev->private = NULL;
341-
return 0;
342340
}
343341

344342
static struct md_personality faulty_personality =
@@ -348,7 +346,7 @@ static struct md_personality faulty_personality =
348346
.owner = THIS_MODULE,
349347
.make_request = make_request,
350348
.run = run,
351-
.stop = stop,
349+
.free = faulty_free,
352350
.status = status,
353351
.check_reshape = reshape,
354352
.size = faulty_size,

drivers/md/linear.c

Lines changed: 20 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
3434

3535
lo = 0;
3636
hi = mddev->raid_disks - 1;
37-
conf = rcu_dereference(mddev->private);
37+
conf = mddev->private;
3838

3939
/*
4040
* Binary Search
@@ -60,18 +60,16 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
6060
*
6161
* Return amount of bytes we can take at this offset
6262
*/
63-
static int linear_mergeable_bvec(struct request_queue *q,
63+
static int linear_mergeable_bvec(struct mddev *mddev,
6464
struct bvec_merge_data *bvm,
6565
struct bio_vec *biovec)
6666
{
67-
struct mddev *mddev = q->queuedata;
6867
struct dev_info *dev0;
6968
unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9;
7069
sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
7170
int maxbytes = biovec->bv_len;
7271
struct request_queue *subq;
7372

74-
rcu_read_lock();
7573
dev0 = which_dev(mddev, sector);
7674
maxsectors = dev0->end_sector - sector;
7775
subq = bdev_get_queue(dev0->rdev->bdev);
@@ -81,7 +79,6 @@ static int linear_mergeable_bvec(struct request_queue *q,
8179
maxbytes = min(maxbytes, subq->merge_bvec_fn(subq, bvm,
8280
biovec));
8381
}
84-
rcu_read_unlock();
8582

8683
if (maxsectors < bio_sectors)
8784
maxsectors = 0;
@@ -97,24 +94,18 @@ static int linear_mergeable_bvec(struct request_queue *q,
9794
return maxsectors << 9;
9895
}
9996

100-
static int linear_congested(void *data, int bits)
97+
static int linear_congested(struct mddev *mddev, int bits)
10198
{
102-
struct mddev *mddev = data;
10399
struct linear_conf *conf;
104100
int i, ret = 0;
105101

106-
if (mddev_congested(mddev, bits))
107-
return 1;
108-
109-
rcu_read_lock();
110-
conf = rcu_dereference(mddev->private);
102+
conf = mddev->private;
111103

112104
for (i = 0; i < mddev->raid_disks && !ret ; i++) {
113105
struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
114106
ret |= bdi_congested(&q->backing_dev_info, bits);
115107
}
116108

117-
rcu_read_unlock();
118109
return ret;
119110
}
120111

@@ -123,12 +114,10 @@ static sector_t linear_size(struct mddev *mddev, sector_t sectors, int raid_disk
123114
struct linear_conf *conf;
124115
sector_t array_sectors;
125116

126-
rcu_read_lock();
127-
conf = rcu_dereference(mddev->private);
117+
conf = mddev->private;
128118
WARN_ONCE(sectors || raid_disks,
129119
"%s does not support generic reshape\n", __func__);
130120
array_sectors = conf->array_sectors;
131-
rcu_read_unlock();
132121

133122
return array_sectors;
134123
}
@@ -217,10 +206,6 @@ static int linear_run (struct mddev *mddev)
217206
mddev->private = conf;
218207
md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
219208

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-
224209
ret = md_integrity_register(mddev);
225210
if (ret) {
226211
kfree(conf);
@@ -252,38 +237,23 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
252237
if (!newconf)
253238
return -ENOMEM;
254239

255-
oldconf = rcu_dereference_protected(mddev->private,
256-
lockdep_is_held(
257-
&mddev->reconfig_mutex));
240+
mddev_suspend(mddev);
241+
oldconf = mddev->private;
258242
mddev->raid_disks++;
259-
rcu_assign_pointer(mddev->private, newconf);
243+
mddev->private = newconf;
260244
md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
261245
set_capacity(mddev->gendisk, mddev->array_sectors);
246+
mddev_resume(mddev);
262247
revalidate_disk(mddev->gendisk);
263-
kfree_rcu(oldconf, rcu);
248+
kfree(oldconf);
264249
return 0;
265250
}
266251

267-
static int linear_stop (struct mddev *mddev)
252+
static void linear_free(struct mddev *mddev, void *priv)
268253
{
269-
struct linear_conf *conf =
270-
rcu_dereference_protected(mddev->private,
271-
lockdep_is_held(
272-
&mddev->reconfig_mutex));
254+
struct linear_conf *conf = priv;
273255

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'*/
283256
kfree(conf);
284-
mddev->private = NULL;
285-
286-
return 0;
287257
}
288258

289259
static 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)
299269
}
300270

301271
do {
302-
rcu_read_lock();
303-
304272
tmp_dev = which_dev(mddev, bio->bi_iter.bi_sector);
305273
start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
306274
end_sector = tmp_dev->end_sector;
307275
data_offset = tmp_dev->rdev->data_offset;
308276
bio->bi_bdev = tmp_dev->rdev->bdev;
309277

310-
rcu_read_unlock();
311-
312278
if (unlikely(bio->bi_iter.bi_sector >= end_sector ||
313279
bio->bi_iter.bi_sector < start_sector))
314280
goto out_of_bounds;
@@ -355,17 +321,24 @@ static void linear_status (struct seq_file *seq, struct mddev *mddev)
355321
seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2);
356322
}
357323

324+
static void linear_quiesce(struct mddev *mddev, int state)
325+
{
326+
}
327+
358328
static struct md_personality linear_personality =
359329
{
360330
.name = "linear",
361331
.level = LEVEL_LINEAR,
362332
.owner = THIS_MODULE,
363333
.make_request = linear_make_request,
364334
.run = linear_run,
365-
.stop = linear_stop,
335+
.free = linear_free,
366336
.status = linear_status,
367337
.hot_add_disk = linear_add,
368338
.size = linear_size,
339+
.quiesce = linear_quiesce,
340+
.congested = linear_congested,
341+
.mergeable_bvec = linear_mergeable_bvec,
369342
};
370343

371344
static int __init linear_init (void)

0 commit comments

Comments
 (0)