diff options
-rw-r--r-- | drivers/md/bitmap.c | 22 | ||||
-rw-r--r-- | include/linux/raid/bitmap.h | 1 |
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 11108165e264..059704fbb753 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1160,6 +1160,22 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
1160 | return 0; | 1160 | return 0; |
1161 | } | 1161 | } |
1162 | 1162 | ||
1163 | if (unlikely((*bmc & COUNTER_MAX) == COUNTER_MAX)) { | ||
1164 | DEFINE_WAIT(__wait); | ||
1165 | /* note that it is safe to do the prepare_to_wait | ||
1166 | * after the test as long as we do it before dropping | ||
1167 | * the spinlock. | ||
1168 | */ | ||
1169 | prepare_to_wait(&bitmap->overflow_wait, &__wait, | ||
1170 | TASK_UNINTERRUPTIBLE); | ||
1171 | spin_unlock_irq(&bitmap->lock); | ||
1172 | bitmap->mddev->queue | ||
1173 | ->unplug_fn(bitmap->mddev->queue); | ||
1174 | schedule(); | ||
1175 | finish_wait(&bitmap->overflow_wait, &__wait); | ||
1176 | continue; | ||
1177 | } | ||
1178 | |||
1163 | switch(*bmc) { | 1179 | switch(*bmc) { |
1164 | case 0: | 1180 | case 0: |
1165 | bitmap_file_set_bit(bitmap, offset); | 1181 | bitmap_file_set_bit(bitmap, offset); |
@@ -1169,7 +1185,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
1169 | case 1: | 1185 | case 1: |
1170 | *bmc = 2; | 1186 | *bmc = 2; |
1171 | } | 1187 | } |
1172 | BUG_ON((*bmc & COUNTER_MAX) == COUNTER_MAX); | 1188 | |
1173 | (*bmc)++; | 1189 | (*bmc)++; |
1174 | 1190 | ||
1175 | spin_unlock_irq(&bitmap->lock); | 1191 | spin_unlock_irq(&bitmap->lock); |
@@ -1207,6 +1223,9 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto | |||
1207 | if (!success && ! (*bmc & NEEDED_MASK)) | 1223 | if (!success && ! (*bmc & NEEDED_MASK)) |
1208 | *bmc |= NEEDED_MASK; | 1224 | *bmc |= NEEDED_MASK; |
1209 | 1225 | ||
1226 | if ((*bmc & COUNTER_MAX) == COUNTER_MAX) | ||
1227 | wake_up(&bitmap->overflow_wait); | ||
1228 | |||
1210 | (*bmc)--; | 1229 | (*bmc)--; |
1211 | if (*bmc <= 2) { | 1230 | if (*bmc <= 2) { |
1212 | set_page_attr(bitmap, | 1231 | set_page_attr(bitmap, |
@@ -1431,6 +1450,7 @@ int bitmap_create(mddev_t *mddev) | |||
1431 | spin_lock_init(&bitmap->lock); | 1450 | spin_lock_init(&bitmap->lock); |
1432 | atomic_set(&bitmap->pending_writes, 0); | 1451 | atomic_set(&bitmap->pending_writes, 0); |
1433 | init_waitqueue_head(&bitmap->write_wait); | 1452 | init_waitqueue_head(&bitmap->write_wait); |
1453 | init_waitqueue_head(&bitmap->overflow_wait); | ||
1434 | 1454 | ||
1435 | bitmap->mddev = mddev; | 1455 | bitmap->mddev = mddev; |
1436 | 1456 | ||
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index ebd42a3710b4..6db9a4c15355 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
@@ -247,6 +247,7 @@ struct bitmap { | |||
247 | 247 | ||
248 | atomic_t pending_writes; /* pending writes to the bitmap file */ | 248 | atomic_t pending_writes; /* pending writes to the bitmap file */ |
249 | wait_queue_head_t write_wait; | 249 | wait_queue_head_t write_wait; |
250 | wait_queue_head_t overflow_wait; | ||
250 | 251 | ||
251 | }; | 252 | }; |
252 | 253 | ||