aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/bitmap.c24
-rw-r--r--drivers/md/bitmap.h2
-rw-r--r--drivers/md/md.c3
-rw-r--r--drivers/md/md.h1
4 files changed, 22 insertions, 8 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 60e2b322db11..a5e5f2fbf963 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1078,23 +1078,31 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
1078 * out to disk 1078 * out to disk
1079 */ 1079 */
1080 1080
1081void bitmap_daemon_work(struct bitmap *bitmap) 1081void bitmap_daemon_work(mddev_t *mddev)
1082{ 1082{
1083 struct bitmap *bitmap;
1083 unsigned long j; 1084 unsigned long j;
1084 unsigned long flags; 1085 unsigned long flags;
1085 struct page *page = NULL, *lastpage = NULL; 1086 struct page *page = NULL, *lastpage = NULL;
1086 int blocks; 1087 int blocks;
1087 void *paddr; 1088 void *paddr;
1088 1089
1089 if (bitmap == NULL) 1090 /* Use a mutex to guard daemon_work against
1091 * bitmap_destroy.
1092 */
1093 mutex_lock(&mddev->bitmap_mutex);
1094 bitmap = mddev->bitmap;
1095 if (bitmap == NULL) {
1096 mutex_unlock(&mddev->bitmap_mutex);
1090 return; 1097 return;
1098 }
1091 if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) 1099 if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ))
1092 goto done; 1100 goto done;
1093 1101
1094 bitmap->daemon_lastrun = jiffies; 1102 bitmap->daemon_lastrun = jiffies;
1095 if (bitmap->allclean) { 1103 if (bitmap->allclean) {
1096 bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; 1104 bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
1097 return; 1105 goto done;
1098 } 1106 }
1099 bitmap->allclean = 1; 1107 bitmap->allclean = 1;
1100 1108
@@ -1203,6 +1211,7 @@ void bitmap_daemon_work(struct bitmap *bitmap)
1203 done: 1211 done:
1204 if (bitmap->allclean == 0) 1212 if (bitmap->allclean == 0)
1205 bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; 1213 bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ;
1214 mutex_unlock(&mddev->bitmap_mutex);
1206} 1215}
1207 1216
1208static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, 1217static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
@@ -1541,9 +1550,9 @@ void bitmap_flush(mddev_t *mddev)
1541 */ 1550 */
1542 sleep = bitmap->daemon_sleep; 1551 sleep = bitmap->daemon_sleep;
1543 bitmap->daemon_sleep = 0; 1552 bitmap->daemon_sleep = 0;
1544 bitmap_daemon_work(bitmap); 1553 bitmap_daemon_work(mddev);
1545 bitmap_daemon_work(bitmap); 1554 bitmap_daemon_work(mddev);
1546 bitmap_daemon_work(bitmap); 1555 bitmap_daemon_work(mddev);
1547 bitmap->daemon_sleep = sleep; 1556 bitmap->daemon_sleep = sleep;
1548 bitmap_update_sb(bitmap); 1557 bitmap_update_sb(bitmap);
1549} 1558}
@@ -1574,6 +1583,7 @@ static void bitmap_free(struct bitmap *bitmap)
1574 kfree(bp); 1583 kfree(bp);
1575 kfree(bitmap); 1584 kfree(bitmap);
1576} 1585}
1586
1577void bitmap_destroy(mddev_t *mddev) 1587void bitmap_destroy(mddev_t *mddev)
1578{ 1588{
1579 struct bitmap *bitmap = mddev->bitmap; 1589 struct bitmap *bitmap = mddev->bitmap;
@@ -1581,7 +1591,9 @@ void bitmap_destroy(mddev_t *mddev)
1581 if (!bitmap) /* there was no bitmap */ 1591 if (!bitmap) /* there was no bitmap */
1582 return; 1592 return;
1583 1593
1594 mutex_lock(&mddev->bitmap_mutex);
1584 mddev->bitmap = NULL; /* disconnect from the md device */ 1595 mddev->bitmap = NULL; /* disconnect from the md device */
1596 mutex_unlock(&mddev->bitmap_mutex);
1585 if (mddev->thread) 1597 if (mddev->thread)
1586 mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; 1598 mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
1587 1599
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
index e98900671ca9..7e38d13ddcac 100644
--- a/drivers/md/bitmap.h
+++ b/drivers/md/bitmap.h
@@ -282,7 +282,7 @@ void bitmap_close_sync(struct bitmap *bitmap);
282void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector); 282void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
283 283
284void bitmap_unplug(struct bitmap *bitmap); 284void bitmap_unplug(struct bitmap *bitmap);
285void bitmap_daemon_work(struct bitmap *bitmap); 285void bitmap_daemon_work(mddev_t *mddev);
286#endif 286#endif
287 287
288#endif 288#endif
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5f154ef1e4be..1be7a16a7a53 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -363,6 +363,7 @@ static mddev_t * mddev_find(dev_t unit)
363 363
364 mutex_init(&new->open_mutex); 364 mutex_init(&new->open_mutex);
365 mutex_init(&new->reconfig_mutex); 365 mutex_init(&new->reconfig_mutex);
366 mutex_init(&new->bitmap_mutex);
366 INIT_LIST_HEAD(&new->disks); 367 INIT_LIST_HEAD(&new->disks);
367 INIT_LIST_HEAD(&new->all_mddevs); 368 INIT_LIST_HEAD(&new->all_mddevs);
368 init_timer(&new->safemode_timer); 369 init_timer(&new->safemode_timer);
@@ -6625,7 +6626,7 @@ void md_check_recovery(mddev_t *mddev)
6625 6626
6626 6627
6627 if (mddev->bitmap) 6628 if (mddev->bitmap)
6628 bitmap_daemon_work(mddev->bitmap); 6629 bitmap_daemon_work(mddev);
6629 6630
6630 if (mddev->ro) 6631 if (mddev->ro)
6631 return; 6632 return;
diff --git a/drivers/md/md.h b/drivers/md/md.h
index f184b69ef337..87430fea2875 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -289,6 +289,7 @@ struct mddev_s
289 * hot-adding a bitmap. It should 289 * hot-adding a bitmap. It should
290 * eventually be settable by sysfs. 290 * eventually be settable by sysfs.
291 */ 291 */
292 struct mutex bitmap_mutex;
292 293
293 struct list_head all_mddevs; 294 struct list_head all_mddevs;
294}; 295};