]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From cea9c22800773cecb1d41f4a6139f9eb6a95368b Mon Sep 17 00:00:00 2001 |
2 | From: NeilBrown <neilb@suse.de> | |
3 | Date: Tue, 31 Mar 2009 15:15:05 +1100 | |
4 | Subject: [PATCH] md: add explicit method to signal the end of a reshape. | |
5 | ||
6 | Currently raid5 (the only module that supports restriping) | |
7 | notices that the reshape has finished be sync_request being | |
8 | given a large value, and handles any cleanup them. | |
9 | ||
10 | This patch changes it so md_check_recovery calls into an | |
11 | explicit finish_reshape method as well. | |
12 | ||
13 | The clean-up from sync_request can do things that need to be | |
14 | done promptly, typically things local to the raid5_conf_t | |
15 | structure. | |
16 | ||
17 | The "finish_reshape" method is called under the mddev_lock | |
18 | so it can do things involving reconfiguring the device. | |
19 | ||
20 | This allows us to get rid of md_set_array_sectors_locked, which | |
21 | would have caused a deadlock if you tried to stop and array | |
22 | while a reshape was happening. | |
23 | ||
24 | Signed-off-by: NeilBrown <neilb@suse.de> | |
25 | --- | |
26 | drivers/md/md.c | 11 ++-------- | |
27 | drivers/md/raid5.c | 50 +++++++++++++++++++++++++++------------------- | |
28 | include/linux/raid/md_k.h | 2 - | |
29 | 3 files changed, 34 insertions(+), 29 deletions(-) | |
30 | ||
31 | --- linux-2.6.27-SLE11_BRANCH.orig/drivers/md/md.c | |
32 | +++ linux-2.6.27-SLE11_BRANCH/drivers/md/md.c | |
33 | @@ -4759,14 +4759,6 @@ void md_set_array_sectors(mddev_t *mddev | |
34 | } | |
35 | EXPORT_SYMBOL(md_set_array_sectors); | |
36 | ||
37 | -void md_set_array_sectors_lock(mddev_t *mddev, sector_t array_sectors) | |
38 | -{ | |
39 | - mddev_lock(mddev); | |
40 | - md_set_array_sectors(mddev, array_sectors); | |
41 | - mddev_unlock(mddev); | |
42 | -} | |
43 | -EXPORT_SYMBOL(md_set_array_sectors_lock); | |
44 | - | |
45 | static int update_size(mddev_t *mddev, sector_t num_sectors) | |
46 | { | |
47 | mdk_rdev_t * rdev; | |
48 | @@ -6313,6 +6305,9 @@ void md_check_recovery(mddev_t *mddev) | |
49 | sysfs_notify(&mddev->kobj, NULL, | |
50 | "degraded"); | |
51 | } | |
52 | + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && | |
53 | + mddev->pers->finish_reshape) | |
54 | + mddev->pers->finish_reshape(mddev); | |
55 | md_update_sb(mddev, 1); | |
56 | ||
57 | /* if array is no-longer degraded, then any saved_raid_disk | |
58 | --- linux-2.6.27-SLE11_BRANCH.orig/drivers/md/raid5.c | |
59 | +++ linux-2.6.27-SLE11_BRANCH/drivers/md/raid5.c | |
60 | @@ -3853,6 +3853,7 @@ static inline sector_t sync_request(mdde | |
61 | if (sector_nr >= max_sector) { | |
62 | /* just being told to finish up .. nothing much to do */ | |
63 | unplug_slaves(mddev); | |
64 | + | |
65 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { | |
66 | end_reshape(conf); | |
67 | return 0; | |
68 | @@ -4798,43 +4799,49 @@ static int raid5_start_reshape(mddev_t * | |
69 | ||
70 | static void end_reshape(raid5_conf_t *conf) | |
71 | { | |
72 | - struct block_device *bdev; | |
73 | ||
74 | if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { | |
75 | - mddev_t *mddev = conf->mddev; | |
76 | - | |
77 | - md_set_array_sectors_lock(mddev, raid5_size(mddev, 0, | |
78 | - conf->raid_disks)); | |
79 | - set_capacity(mddev->gendisk, mddev->array_sectors); | |
80 | - mddev->changed = 1; | |
81 | - conf->previous_raid_disks = conf->raid_disks; | |
82 | ||
83 | - bdev = bdget_disk(conf->mddev->gendisk, 0); | |
84 | - if (bdev) { | |
85 | - mutex_lock(&bdev->bd_inode->i_mutex); | |
86 | - i_size_write(bdev->bd_inode, | |
87 | - (loff_t)conf->mddev->array_sectors << 9); | |
88 | - mutex_unlock(&bdev->bd_inode->i_mutex); | |
89 | - bdput(bdev); | |
90 | - } | |
91 | spin_lock_irq(&conf->device_lock); | |
92 | + conf->previous_raid_disks = conf->raid_disks; | |
93 | conf->expand_progress = MaxSector; | |
94 | spin_unlock_irq(&conf->device_lock); | |
95 | - conf->mddev->reshape_position = MaxSector; | |
96 | ||
97 | /* read-ahead size must cover two whole stripes, which is | |
98 | * 2 * (datadisks) * chunksize where 'n' is the number of raid devices | |
99 | */ | |
100 | { | |
101 | - int data_disks = conf->previous_raid_disks - conf->max_degraded; | |
102 | - int stripe = data_disks * | |
103 | - (conf->mddev->chunk_size / PAGE_SIZE); | |
104 | + int data_disks = conf->raid_disks - conf->max_degraded; | |
105 | + int stripe = data_disks * (conf->chunk_size | |
106 | + / PAGE_SIZE); | |
107 | if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe) | |
108 | conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe; | |
109 | } | |
110 | } | |
111 | } | |
112 | ||
113 | +static void raid5_finish_reshape(mddev_t *mddev) | |
114 | +{ | |
115 | + struct block_device *bdev; | |
116 | + | |
117 | + if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | |
118 | + | |
119 | + md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); | |
120 | + set_capacity(mddev->gendisk, mddev->array_sectors); | |
121 | + mddev->changed = 1; | |
122 | + mddev->reshape_position = MaxSector; | |
123 | + | |
124 | + bdev = bdget_disk(mddev->gendisk, 0); | |
125 | + if (bdev) { | |
126 | + mutex_lock(&bdev->bd_inode->i_mutex); | |
127 | + i_size_write(bdev->bd_inode, | |
128 | + (loff_t)mddev->array_sectors << 9); | |
129 | + mutex_unlock(&bdev->bd_inode->i_mutex); | |
130 | + bdput(bdev); | |
131 | + } | |
132 | + } | |
133 | +} | |
134 | + | |
135 | static void raid5_quiesce(mddev_t *mddev, int state) | |
136 | { | |
137 | raid5_conf_t *conf = mddev_to_conf(mddev); | |
138 | @@ -4883,6 +4890,7 @@ static struct mdk_personality raid6_pers | |
139 | #ifdef CONFIG_MD_RAID5_RESHAPE | |
140 | .check_reshape = raid5_check_reshape, | |
141 | .start_reshape = raid5_start_reshape, | |
142 | + .finish_reshape = raid5_finish_reshape, | |
143 | #endif | |
144 | .quiesce = raid5_quiesce, | |
145 | }; | |
146 | @@ -4905,6 +4913,7 @@ static struct mdk_personality raid5_pers | |
147 | #ifdef CONFIG_MD_RAID5_RESHAPE | |
148 | .check_reshape = raid5_check_reshape, | |
149 | .start_reshape = raid5_start_reshape, | |
150 | + .finish_reshape = raid5_finish_reshape, | |
151 | #endif | |
152 | .quiesce = raid5_quiesce, | |
153 | }; | |
154 | @@ -4928,6 +4937,7 @@ static struct mdk_personality raid4_pers | |
155 | #ifdef CONFIG_MD_RAID5_RESHAPE | |
156 | .check_reshape = raid5_check_reshape, | |
157 | .start_reshape = raid5_start_reshape, | |
158 | + .finish_reshape = raid5_finish_reshape, | |
159 | #endif | |
160 | .quiesce = raid5_quiesce, | |
161 | }; | |
162 | --- linux-2.6.27-SLE11_BRANCH.orig/include/linux/raid/md_k.h | |
163 | +++ linux-2.6.27-SLE11_BRANCH/include/linux/raid/md_k.h | |
164 | @@ -310,6 +310,7 @@ struct mdk_personality | |
165 | sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks); | |
166 | int (*check_reshape) (mddev_t *mddev); | |
167 | int (*start_reshape) (mddev_t *mddev); | |
168 | + void (*finish_reshape) (mddev_t *mddev); | |
169 | int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); | |
170 | /* quiesce moves between quiescence states | |
171 | * 0 - fully active | |
172 | @@ -396,4 +397,3 @@ static inline void safe_put_page(struct | |
173 | #endif /* CONFIG_BLOCK */ | |
174 | #endif | |
175 | ||
176 | -extern void md_set_array_sectors_lock(mddev_t *mddev, sector_t array_sectors); |