aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-01-06 03:20:40 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:34:07 -0500
commit1345b1d8adbdeceb1c871d9a4af5e2a700b341c6 (patch)
tree0da1db7d273752ad5281db415e9245f3f3a63383
parent7dd5d34c6c2da04e8cd0732e08b33cd3359e4bae (diff)
[PATCH] md: define and use safe_put_page for md
md sometimes call put_page on NULL pointers (treating it like kfree). This is not safe, so define and use a 'safe_put_page' which checks for NULL. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/bitmap.c3
-rw-r--r--drivers/md/raid1.c8
-rw-r--r--drivers/md/raid10.c8
-rw-r--r--drivers/md/raid6main.c3
-rw-r--r--include/linux/raid/md_k.h5
5 files changed, 15 insertions, 12 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index abe415f0c039..ee4a3424a8a3 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -626,8 +626,7 @@ static void bitmap_file_unmap(struct bitmap *bitmap)
626 kfree(map); 626 kfree(map);
627 kfree(attr); 627 kfree(attr);
628 628
629 if (sb_page) 629 safe_put_page(sb_page);
630 put_page(sb_page);
631} 630}
632 631
633static void bitmap_stop_daemon(struct bitmap *bitmap); 632static void bitmap_stop_daemon(struct bitmap *bitmap);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 39c10a65683d..feea4eeca1d9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -136,7 +136,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
136out_free_pages: 136out_free_pages:
137 for (i=0; i < RESYNC_PAGES ; i++) 137 for (i=0; i < RESYNC_PAGES ; i++)
138 for (j=0 ; j < pi->raid_disks; j++) 138 for (j=0 ; j < pi->raid_disks; j++)
139 put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page); 139 safe_put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
140 j = -1; 140 j = -1;
141out_free_bio: 141out_free_bio:
142 while ( ++j < pi->raid_disks ) 142 while ( ++j < pi->raid_disks )
@@ -156,7 +156,7 @@ static void r1buf_pool_free(void *__r1_bio, void *data)
156 if (j == 0 || 156 if (j == 0 ||
157 r1bio->bios[j]->bi_io_vec[i].bv_page != 157 r1bio->bios[j]->bi_io_vec[i].bv_page !=
158 r1bio->bios[0]->bi_io_vec[i].bv_page) 158 r1bio->bios[0]->bi_io_vec[i].bv_page)
159 put_page(r1bio->bios[j]->bi_io_vec[i].bv_page); 159 safe_put_page(r1bio->bios[j]->bi_io_vec[i].bv_page);
160 } 160 }
161 for (i=0 ; i < pi->raid_disks; i++) 161 for (i=0 ; i < pi->raid_disks; i++)
162 bio_put(r1bio->bios[i]); 162 bio_put(r1bio->bios[i]);
@@ -381,7 +381,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
381 /* free extra copy of the data pages */ 381 /* free extra copy of the data pages */
382 int i = bio->bi_vcnt; 382 int i = bio->bi_vcnt;
383 while (i--) 383 while (i--)
384 put_page(bio->bi_io_vec[i].bv_page); 384 safe_put_page(bio->bi_io_vec[i].bv_page);
385 } 385 }
386 /* clear the bitmap if all writes complete successfully */ 386 /* clear the bitmap if all writes complete successfully */
387 bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector, 387 bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
@@ -1907,7 +1907,7 @@ out_free_conf:
1907 if (conf->r1bio_pool) 1907 if (conf->r1bio_pool)
1908 mempool_destroy(conf->r1bio_pool); 1908 mempool_destroy(conf->r1bio_pool);
1909 kfree(conf->mirrors); 1909 kfree(conf->mirrors);
1910 put_page(conf->tmppage); 1910 safe_put_page(conf->tmppage);
1911 kfree(conf->poolinfo); 1911 kfree(conf->poolinfo);
1912 kfree(conf); 1912 kfree(conf);
1913 mddev->private = NULL; 1913 mddev->private = NULL;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 9647ebb0983a..fb952000fae2 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -132,10 +132,10 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
132 132
133out_free_pages: 133out_free_pages:
134 for ( ; i > 0 ; i--) 134 for ( ; i > 0 ; i--)
135 put_page(bio->bi_io_vec[i-1].bv_page); 135 safe_put_page(bio->bi_io_vec[i-1].bv_page);
136 while (j--) 136 while (j--)
137 for (i = 0; i < RESYNC_PAGES ; i++) 137 for (i = 0; i < RESYNC_PAGES ; i++)
138 put_page(r10_bio->devs[j].bio->bi_io_vec[i].bv_page); 138 safe_put_page(r10_bio->devs[j].bio->bi_io_vec[i].bv_page);
139 j = -1; 139 j = -1;
140out_free_bio: 140out_free_bio:
141 while ( ++j < nalloc ) 141 while ( ++j < nalloc )
@@ -155,7 +155,7 @@ static void r10buf_pool_free(void *__r10_bio, void *data)
155 struct bio *bio = r10bio->devs[j].bio; 155 struct bio *bio = r10bio->devs[j].bio;
156 if (bio) { 156 if (bio) {
157 for (i = 0; i < RESYNC_PAGES; i++) { 157 for (i = 0; i < RESYNC_PAGES; i++) {
158 put_page(bio->bi_io_vec[i].bv_page); 158 safe_put_page(bio->bi_io_vec[i].bv_page);
159 bio->bi_io_vec[i].bv_page = NULL; 159 bio->bi_io_vec[i].bv_page = NULL;
160 } 160 }
161 bio_put(bio); 161 bio_put(bio);
@@ -2042,7 +2042,7 @@ static int run(mddev_t *mddev)
2042out_free_conf: 2042out_free_conf:
2043 if (conf->r10bio_pool) 2043 if (conf->r10bio_pool)
2044 mempool_destroy(conf->r10bio_pool); 2044 mempool_destroy(conf->r10bio_pool);
2045 put_page(conf->tmppage); 2045 safe_put_page(conf->tmppage);
2046 kfree(conf->mirrors); 2046 kfree(conf->mirrors);
2047 kfree(conf); 2047 kfree(conf);
2048 mddev->private = NULL; 2048 mddev->private = NULL;
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 950e5fa6e1f2..06b32bd671a3 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -2072,8 +2072,7 @@ static int run(mddev_t *mddev)
2072abort: 2072abort:
2073 if (conf) { 2073 if (conf) {
2074 print_raid6_conf(conf); 2074 print_raid6_conf(conf);
2075 if (conf->spare_page) 2075 safe_put_page(conf->spare_page);
2076 put_page(conf->spare_page);
2077 kfree(conf->stripe_hashtbl); 2076 kfree(conf->stripe_hashtbl);
2078 kfree(conf); 2077 kfree(conf);
2079 } 2078 }
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index e559fb701aa1..12b3203e3419 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -324,5 +324,10 @@ do { \
324 __wait_event_lock_irq(wq, condition, lock, cmd); \ 324 __wait_event_lock_irq(wq, condition, lock, cmd); \
325} while (0) 325} while (0)
326 326
327static inline void safe_put_page(struct page *p)
328{
329 if (p) put_page(p);
330}
331
327#endif 332#endif
328 333