git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
md: Protect access to mddev->disks list using RCU
[pandora-kernel.git]
/
drivers
/
md
/
bitmap.c
diff --git
a/drivers/md/bitmap.c
b/drivers/md/bitmap.c
index
eba83e2
..
621a272
100644
(file)
--- 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
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{
mdk_rdev_t *rdev;
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{
mdk_rdev_t *rdev;
- struct list_head *tmp;
mddev_t *mddev = bitmap->mddev;
mddev_t *mddev = bitmap->mddev;
- rdev_for_each(rdev, tmp, mddev)
+ rcu_read_lock();
+ rdev_for_each_rcu(rdev, mddev)
if (test_bit(In_sync, &rdev->flags)
&& !test_bit(Faulty, &rdev->flags)) {
int size = PAGE_SIZE;
if (test_bit(In_sync, &rdev->flags)
&& !test_bit(Faulty, &rdev->flags)) {
int size = PAGE_SIZE;
@@
-260,11
+260,11
@@
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
+ (long)(page->index * (PAGE_SIZE/512))
+ size/512 > 0)
/* bitmap runs in to metadata */
+ (long)(page->index * (PAGE_SIZE/512))
+ size/512 > 0)
/* bitmap runs in to metadata */
-
return -EINVAL
;
+
goto bad_alignment
;
if (rdev->data_offset + mddev->size*2
> rdev->sb_start + bitmap->offset)
/* data runs in to bitmap */
if (rdev->data_offset + mddev->size*2
> rdev->sb_start + bitmap->offset)
/* data runs in to bitmap */
-
return -EINVAL
;
+
goto bad_alignment
;
} else if (rdev->sb_start < rdev->data_offset) {
/* METADATA BITMAP DATA */
if (rdev->sb_start
} else if (rdev->sb_start < rdev->data_offset) {
/* METADATA BITMAP DATA */
if (rdev->sb_start
@@
-272,7
+272,7
@@
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
+ page->index*(PAGE_SIZE/512) + size/512
> rdev->data_offset)
/* bitmap runs in to data */
+ page->index*(PAGE_SIZE/512) + size/512
> rdev->data_offset)
/* bitmap runs in to data */
-
return -EINVAL
;
+
goto bad_alignment
;
} else {
/* DATA METADATA BITMAP - no problems */
}
} else {
/* DATA METADATA BITMAP - no problems */
}
@@
-282,10
+282,15
@@
static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
size,
page);
}
size,
page);
}
+ rcu_read_unlock();
if (wait)
md_super_wait(mddev);
return 0;
if (wait)
md_super_wait(mddev);
return 0;
+
+ bad_alignment:
+ rcu_read_unlock();
+ return -EINVAL;
}
static void bitmap_file_kick(struct bitmap *bitmap);
}
static void bitmap_file_kick(struct bitmap *bitmap);