diff options
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r-- | drivers/md/bitmap.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 2925219f0881..2c84de2b4ad5 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -437,6 +437,7 @@ void bitmap_print_sb(struct bitmap *bitmap) | |||
437 | printk(KERN_DEBUG " daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); | 437 | printk(KERN_DEBUG " daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); |
438 | printk(KERN_DEBUG " sync size: %llu KB\n", | 438 | printk(KERN_DEBUG " sync size: %llu KB\n", |
439 | (unsigned long long)le64_to_cpu(sb->sync_size)/2); | 439 | (unsigned long long)le64_to_cpu(sb->sync_size)/2); |
440 | printk(KERN_DEBUG "max write behind: %d\n", le32_to_cpu(sb->write_behind)); | ||
440 | kunmap(bitmap->sb_page); | 441 | kunmap(bitmap->sb_page); |
441 | } | 442 | } |
442 | 443 | ||
@@ -445,7 +446,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
445 | { | 446 | { |
446 | char *reason = NULL; | 447 | char *reason = NULL; |
447 | bitmap_super_t *sb; | 448 | bitmap_super_t *sb; |
448 | unsigned long chunksize, daemon_sleep; | 449 | unsigned long chunksize, daemon_sleep, write_behind; |
449 | unsigned long bytes_read; | 450 | unsigned long bytes_read; |
450 | unsigned long long events; | 451 | unsigned long long events; |
451 | int err = -EINVAL; | 452 | int err = -EINVAL; |
@@ -474,6 +475,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
474 | 475 | ||
475 | chunksize = le32_to_cpu(sb->chunksize); | 476 | chunksize = le32_to_cpu(sb->chunksize); |
476 | daemon_sleep = le32_to_cpu(sb->daemon_sleep); | 477 | daemon_sleep = le32_to_cpu(sb->daemon_sleep); |
478 | write_behind = le32_to_cpu(sb->write_behind); | ||
477 | 479 | ||
478 | /* verify that the bitmap-specific fields are valid */ | 480 | /* verify that the bitmap-specific fields are valid */ |
479 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) | 481 | if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) |
@@ -485,7 +487,9 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
485 | else if ((1 << ffz(~chunksize)) != chunksize) | 487 | else if ((1 << ffz(~chunksize)) != chunksize) |
486 | reason = "bitmap chunksize not a power of 2"; | 488 | reason = "bitmap chunksize not a power of 2"; |
487 | else if (daemon_sleep < 1 || daemon_sleep > 15) | 489 | else if (daemon_sleep < 1 || daemon_sleep > 15) |
488 | reason = "daemon sleep period out of range"; | 490 | reason = "daemon sleep period out of range (1-15s)"; |
491 | else if (write_behind > COUNTER_MAX) | ||
492 | reason = "write-behind limit out of range (0 - 16383)"; | ||
489 | if (reason) { | 493 | if (reason) { |
490 | printk(KERN_INFO "%s: invalid bitmap file superblock: %s\n", | 494 | printk(KERN_INFO "%s: invalid bitmap file superblock: %s\n", |
491 | bmname(bitmap), reason); | 495 | bmname(bitmap), reason); |
@@ -518,6 +522,7 @@ success: | |||
518 | /* assign fields using values from superblock */ | 522 | /* assign fields using values from superblock */ |
519 | bitmap->chunksize = chunksize; | 523 | bitmap->chunksize = chunksize; |
520 | bitmap->daemon_sleep = daemon_sleep; | 524 | bitmap->daemon_sleep = daemon_sleep; |
525 | bitmap->max_write_behind = write_behind; | ||
521 | bitmap->flags |= sb->state; | 526 | bitmap->flags |= sb->state; |
522 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); | 527 | bitmap->events_cleared = le64_to_cpu(sb->events_cleared); |
523 | if (sb->state & BITMAP_STALE) | 528 | if (sb->state & BITMAP_STALE) |
@@ -1282,9 +1287,16 @@ static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, | |||
1282 | } | 1287 | } |
1283 | } | 1288 | } |
1284 | 1289 | ||
1285 | int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors) | 1290 | int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind) |
1286 | { | 1291 | { |
1287 | if (!bitmap) return 0; | 1292 | if (!bitmap) return 0; |
1293 | |||
1294 | if (behind) { | ||
1295 | atomic_inc(&bitmap->behind_writes); | ||
1296 | PRINTK(KERN_DEBUG "inc write-behind count %d/%d\n", | ||
1297 | atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); | ||
1298 | } | ||
1299 | |||
1288 | while (sectors) { | 1300 | while (sectors) { |
1289 | int blocks; | 1301 | int blocks; |
1290 | bitmap_counter_t *bmc; | 1302 | bitmap_counter_t *bmc; |
@@ -1319,9 +1331,15 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
1319 | } | 1331 | } |
1320 | 1332 | ||
1321 | void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, | 1333 | void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, |
1322 | int success) | 1334 | int success, int behind) |
1323 | { | 1335 | { |
1324 | if (!bitmap) return; | 1336 | if (!bitmap) return; |
1337 | if (behind) { | ||
1338 | atomic_dec(&bitmap->behind_writes); | ||
1339 | PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n", | ||
1340 | atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); | ||
1341 | } | ||
1342 | |||
1325 | while (sectors) { | 1343 | while (sectors) { |
1326 | int blocks; | 1344 | int blocks; |
1327 | unsigned long flags; | 1345 | unsigned long flags; |