mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
md: make ->congested robust against personality changes.
There is currently no locking around calls to the 'congested' bdi function. If called at an awkward time while an array is being converted from one level (or personality) to another, there is a tiny chance of running code in an unreferenced module etc. So add a 'congested' function to the md_personality operations structure, and call it with appropriate locking from a central 'mddev_congested'. When the array personality is changing the array will be 'suspended' so no IO is processed. If mddev_congested detects this, it simply reports that the array is congested, which is a safe guess. As mddev_suspend calls synchronize_rcu(), mddev_congested can avoid races by included the whole call inside an rcu_read_lock() region. This require that the congested functions for all subordinate devices can be run under rcu_lock. Fortunately this is the case. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
85572d7c75
commit
5c675f83c6
12 changed files with 38 additions and 77 deletions
|
@ -4149,7 +4149,7 @@ static void activate_bit_delay(struct r5conf *conf,
|
|||
}
|
||||
}
|
||||
|
||||
int md_raid5_congested(struct mddev *mddev, int bits)
|
||||
static int raid5_congested(struct mddev *mddev, int bits)
|
||||
{
|
||||
struct r5conf *conf = mddev->private;
|
||||
|
||||
|
@ -4166,15 +4166,6 @@ int md_raid5_congested(struct mddev *mddev, int bits)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(md_raid5_congested);
|
||||
|
||||
static int raid5_congested(void *data, int bits)
|
||||
{
|
||||
struct mddev *mddev = data;
|
||||
|
||||
return mddev_congested(mddev, bits) ||
|
||||
md_raid5_congested(mddev, bits);
|
||||
}
|
||||
|
||||
/* We want read requests to align with chunks where possible,
|
||||
* but write requests don't need to.
|
||||
|
@ -6248,9 +6239,6 @@ static int run(struct mddev *mddev)
|
|||
|
||||
blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
|
||||
|
||||
mddev->queue->backing_dev_info.congested_data = mddev;
|
||||
mddev->queue->backing_dev_info.congested_fn = raid5_congested;
|
||||
|
||||
chunk_size = mddev->chunk_sectors << 9;
|
||||
blk_queue_io_min(mddev->queue, chunk_size);
|
||||
blk_queue_io_opt(mddev->queue, chunk_size *
|
||||
|
@ -6333,8 +6321,6 @@ static int stop(struct mddev *mddev)
|
|||
struct r5conf *conf = mddev->private;
|
||||
|
||||
md_unregister_thread(&mddev->thread);
|
||||
if (mddev->queue)
|
||||
mddev->queue->backing_dev_info.congested_fn = NULL;
|
||||
free_conf(conf);
|
||||
mddev->private = NULL;
|
||||
mddev->to_remove = &raid5_attrs_group;
|
||||
|
@ -7126,6 +7112,7 @@ static struct md_personality raid6_personality =
|
|||
.finish_reshape = raid5_finish_reshape,
|
||||
.quiesce = raid5_quiesce,
|
||||
.takeover = raid6_takeover,
|
||||
.congested = raid5_congested,
|
||||
};
|
||||
static struct md_personality raid5_personality =
|
||||
{
|
||||
|
@ -7148,6 +7135,7 @@ static struct md_personality raid5_personality =
|
|||
.finish_reshape = raid5_finish_reshape,
|
||||
.quiesce = raid5_quiesce,
|
||||
.takeover = raid5_takeover,
|
||||
.congested = raid5_congested,
|
||||
};
|
||||
|
||||
static struct md_personality raid4_personality =
|
||||
|
@ -7171,6 +7159,7 @@ static struct md_personality raid4_personality =
|
|||
.finish_reshape = raid5_finish_reshape,
|
||||
.quiesce = raid5_quiesce,
|
||||
.takeover = raid4_takeover,
|
||||
.congested = raid5_congested,
|
||||
};
|
||||
|
||||
static int __init raid5_init(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue