aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-25 21:20:35 -0400
committerNeilBrown <neilb@suse.de>2011-07-25 21:20:35 -0400
commitcbe47ec559c33a68b5ee002051b848d1531a8adb (patch)
tree922184b1b599ce0e97f01d7fc6a84fc4c8493a0c /drivers
parent83206d66b65118d995c38746f21edc2bb8564b49 (diff)
md/raid5: Protect some more code with ->device_lock.
Other places that change or follow dev->towrite and dev->written take the device_lock as well as the sh->lock. So it should really be held in these places too. Also, doing so will allow sh->lock to be discarded. with merged fixes by: Namhyung Kim <namhyung@gmail.com> Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Namhyung Kim <namhyung@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/raid5.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index f2f2ab329690..9985138f4c04 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1021,10 +1021,12 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
1021 struct bio *wbi; 1021 struct bio *wbi;
1022 1022
1023 spin_lock(&sh->lock); 1023 spin_lock(&sh->lock);
1024 spin_lock_irq(&sh->raid_conf->device_lock);
1024 chosen = dev->towrite; 1025 chosen = dev->towrite;
1025 dev->towrite = NULL; 1026 dev->towrite = NULL;
1026 BUG_ON(dev->written); 1027 BUG_ON(dev->written);
1027 wbi = dev->written = chosen; 1028 wbi = dev->written = chosen;
1029 spin_unlock_irq(&sh->raid_conf->device_lock);
1028 spin_unlock(&sh->lock); 1030 spin_unlock(&sh->lock);
1029 1031
1030 while (wbi && wbi->bi_sector < 1032 while (wbi && wbi->bi_sector <
@@ -2141,7 +2143,7 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
2141 raid5_conf_t *conf = sh->raid_conf; 2143 raid5_conf_t *conf = sh->raid_conf;
2142 int firstwrite=0; 2144 int firstwrite=0;
2143 2145
2144 pr_debug("adding bh b#%llu to stripe s#%llu\n", 2146 pr_debug("adding bi b#%llu to stripe s#%llu\n",
2145 (unsigned long long)bi->bi_sector, 2147 (unsigned long long)bi->bi_sector,
2146 (unsigned long long)sh->sector); 2148 (unsigned long long)sh->sector);
2147 2149
@@ -2167,19 +2169,6 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
2167 bi->bi_next = *bip; 2169 bi->bi_next = *bip;
2168 *bip = bi; 2170 *bip = bi;
2169 bi->bi_phys_segments++; 2171 bi->bi_phys_segments++;
2170 spin_unlock_irq(&conf->device_lock);
2171 spin_unlock(&sh->lock);
2172
2173 pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n",
2174 (unsigned long long)bi->bi_sector,
2175 (unsigned long long)sh->sector, dd_idx);
2176
2177 if (conf->mddev->bitmap && firstwrite) {
2178 bitmap_startwrite(conf->mddev->bitmap, sh->sector,
2179 STRIPE_SECTORS, 0);
2180 sh->bm_seq = conf->seq_flush+1;
2181 set_bit(STRIPE_BIT_DELAY, &sh->state);
2182 }
2183 2172
2184 if (forwrite) { 2173 if (forwrite) {
2185 /* check if page is covered */ 2174 /* check if page is covered */
@@ -2194,6 +2183,19 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in
2194 if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS) 2183 if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS)
2195 set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags); 2184 set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags);
2196 } 2185 }
2186 spin_unlock_irq(&conf->device_lock);
2187 spin_unlock(&sh->lock);
2188
2189 pr_debug("added bi b#%llu to stripe s#%llu, disk %d.\n",
2190 (unsigned long long)(*bip)->bi_sector,
2191 (unsigned long long)sh->sector, dd_idx);
2192
2193 if (conf->mddev->bitmap && firstwrite) {
2194 bitmap_startwrite(conf->mddev->bitmap, sh->sector,
2195 STRIPE_SECTORS, 0);
2196 sh->bm_seq = conf->seq_flush+1;
2197 set_bit(STRIPE_BIT_DELAY, &sh->state);
2198 }
2197 return 1; 2199 return 1;
2198 2200
2199 overlap: 2201 overlap: