diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index eba83e25b678..621a272a2c74 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -241,10 +241,10 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde | |||
241 | static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | 241 | static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) |
242 | { | 242 | { |
243 | mdk_rdev_t *rdev; | 243 | mdk_rdev_t *rdev; |
244 | struct list_head *tmp; | ||
245 | mddev_t *mddev = bitmap->mddev; | 244 | mddev_t *mddev = bitmap->mddev; |
246 | 245 | ||
247 | rdev_for_each(rdev, tmp, mddev) | 246 | rcu_read_lock(); |
247 | rdev_for_each_rcu(rdev, mddev) | ||
248 | if (test_bit(In_sync, &rdev->flags) | 248 | if (test_bit(In_sync, &rdev->flags) |
249 | && !test_bit(Faulty, &rdev->flags)) { | 249 | && !test_bit(Faulty, &rdev->flags)) { |
250 | int size = PAGE_SIZE; | 250 | int size = PAGE_SIZE; |
@@ -260,11 +260,11 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
260 | + (long)(page->index * (PAGE_SIZE/512)) | 260 | + (long)(page->index * (PAGE_SIZE/512)) |
261 | + size/512 > 0) | 261 | + size/512 > 0) |
262 | /* bitmap runs in to metadata */ | 262 | /* bitmap runs in to metadata */ |
263 | return -EINVAL; | 263 | goto bad_alignment; |
264 | if (rdev->data_offset + mddev->size*2 | 264 | if (rdev->data_offset + mddev->size*2 |
265 | > rdev->sb_start + bitmap->offset) | 265 | > rdev->sb_start + bitmap->offset) |
266 | /* data runs in to bitmap */ | 266 | /* data runs in to bitmap */ |
267 | return -EINVAL; | 267 | goto bad_alignment; |
268 | } else if (rdev->sb_start < rdev->data_offset) { | 268 | } else if (rdev->sb_start < rdev->data_offset) { |
269 | /* METADATA BITMAP DATA */ | 269 | /* METADATA BITMAP DATA */ |
270 | if (rdev->sb_start | 270 | if (rdev->sb_start |
@@ -272,7 +272,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
272 | + page->index*(PAGE_SIZE/512) + size/512 | 272 | + page->index*(PAGE_SIZE/512) + size/512 |
273 | > rdev->data_offset) | 273 | > rdev->data_offset) |
274 | /* bitmap runs in to data */ | 274 | /* bitmap runs in to data */ |
275 | return -EINVAL; | 275 | goto bad_alignment; |
276 | } else { | 276 | } else { |
277 | /* DATA METADATA BITMAP - no problems */ | 277 | /* DATA METADATA BITMAP - no problems */ |
278 | } | 278 | } |
@@ -282,10 +282,15 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
282 | size, | 282 | size, |
283 | page); | 283 | page); |
284 | } | 284 | } |
285 | rcu_read_unlock(); | ||
285 | 286 | ||
286 | if (wait) | 287 | if (wait) |
287 | md_super_wait(mddev); | 288 | md_super_wait(mddev); |
288 | return 0; | 289 | return 0; |
290 | |||
291 | bad_alignment: | ||
292 | rcu_read_unlock(); | ||
293 | return -EINVAL; | ||
289 | } | 294 | } |
290 | 295 | ||
291 | static void bitmap_file_kick(struct bitmap *bitmap); | 296 | static void bitmap_file_kick(struct bitmap *bitmap); |