diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 24 |
1 files changed, 18 insertions, 6 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 | ||
1081 | void bitmap_daemon_work(struct bitmap *bitmap) | 1081 | void 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 | ||
1208 | static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | 1217 | static 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 | |||
1577 | void bitmap_destroy(mddev_t *mddev) | 1587 | void 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 | ||