aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-09-09 19:23:47 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 19:39:10 -0400
commit4b6d287f627b5fb6a49f78f9e81649ff98c62bb7 (patch)
tree7b6cbc6a997e25a7fb6185da7129e539c4ffda8b /drivers/md/bitmap.c
parent8ddf9efe6708f3674f0ddfeb6425fd27bea109a2 (diff)
[PATCH] md: add write-behind support for md/raid1
If a device is flagged 'WriteMostly' and the array has a bitmap, and the bitmap superblock indicates that write_behind is allowed, then write_behind is enabled for WriteMostly devices. Write requests will be acknowledges as complete to the caller (via b_end_io) when all non-WriteMostly devices have completed the write, but will not be cleared from the bitmap until all devices complete. This requires memory allocation to make a local copy of the data being written. If there is insufficient memory, then we fall-back on normal write semantics. Signed-Off-By: Paul Clements <paul.clements@steeleye.com> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c26
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
1285int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors) 1290int 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
1321void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, 1333void 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;