diff options
| -rw-r--r-- | drivers/md/bitmap.c | 132 | ||||
| -rw-r--r-- | drivers/md/md.c | 40 | ||||
| -rw-r--r-- | include/linux/raid/bitmap.h | 2 | ||||
| -rw-r--r-- | include/linux/raid/md.h | 15 | ||||
| -rw-r--r-- | include/linux/raid/md_k.h | 4 | ||||
| -rw-r--r-- | include/linux/raid/md_p.h | 7 |
6 files changed, 170 insertions, 30 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 204564dc6a0d..030d6861051a 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -116,7 +116,7 @@ static unsigned char *bitmap_alloc_page(struct bitmap *bitmap) | |||
| 116 | if (!page) | 116 | if (!page) |
| 117 | printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap)); | 117 | printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap)); |
| 118 | else | 118 | else |
| 119 | printk("%s: bitmap_alloc_page: allocated page at %p\n", | 119 | PRINTK("%s: bitmap_alloc_page: allocated page at %p\n", |
| 120 | bmname(bitmap), page); | 120 | bmname(bitmap), page); |
| 121 | return page; | 121 | return page; |
| 122 | } | 122 | } |
| @@ -258,13 +258,61 @@ char *file_path(struct file *file, char *buf, int count) | |||
| 258 | * basic page I/O operations | 258 | * basic page I/O operations |
| 259 | */ | 259 | */ |
| 260 | 260 | ||
| 261 | /* IO operations when bitmap is stored near all superblocks */ | ||
| 262 | static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long index) | ||
| 263 | { | ||
| 264 | /* choose a good rdev and read the page from there */ | ||
| 265 | |||
| 266 | mdk_rdev_t *rdev; | ||
| 267 | struct list_head *tmp; | ||
| 268 | struct page *page = alloc_page(GFP_KERNEL); | ||
| 269 | sector_t target; | ||
| 270 | |||
| 271 | if (!page) | ||
| 272 | return ERR_PTR(-ENOMEM); | ||
| 273 | do { | ||
| 274 | ITERATE_RDEV(mddev, rdev, tmp) | ||
| 275 | if (rdev->in_sync && !rdev->faulty) | ||
| 276 | goto found; | ||
| 277 | return ERR_PTR(-EIO); | ||
| 278 | |||
| 279 | found: | ||
| 280 | target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); | ||
| 281 | |||
| 282 | } while (!sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)); | ||
| 283 | |||
| 284 | page->index = index; | ||
| 285 | return page; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait) | ||
| 289 | { | ||
| 290 | mdk_rdev_t *rdev; | ||
| 291 | struct list_head *tmp; | ||
| 292 | |||
| 293 | ITERATE_RDEV(mddev, rdev, tmp) | ||
| 294 | if (rdev->in_sync && !rdev->faulty) | ||
| 295 | md_super_write(mddev, rdev, | ||
| 296 | (rdev->sb_offset<<1) + offset | ||
| 297 | + page->index * (PAGE_SIZE/512), | ||
| 298 | PAGE_SIZE, | ||
| 299 | page); | ||
| 300 | |||
| 301 | if (wait) | ||
| 302 | wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); | ||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 261 | /* | 306 | /* |
| 262 | * write out a page | 307 | * write out a page to a file |
| 263 | */ | 308 | */ |
| 264 | static int write_page(struct bitmap *bitmap, struct page *page, int wait) | 309 | static int write_page(struct bitmap *bitmap, struct page *page, int wait) |
| 265 | { | 310 | { |
| 266 | int ret = -ENOMEM; | 311 | int ret = -ENOMEM; |
| 267 | 312 | ||
| 313 | if (bitmap->file == NULL) | ||
| 314 | return write_sb_page(bitmap->mddev, bitmap->offset, page, wait); | ||
| 315 | |||
| 268 | lock_page(page); | 316 | lock_page(page); |
| 269 | 317 | ||
| 270 | ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); | 318 | ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE); |
| @@ -394,7 +442,12 @@ static int bitmap_read_sb(struct bitmap *bitmap) | |||
| 394 | int err = -EINVAL; | 442 | int err = -EINVAL; |
| 395 | 443 | ||
| 396 | /* page 0 is the superblock, read it... */ | 444 | /* page 0 is the superblock, read it... */ |
| 397 | bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read); | 445 | if (bitmap->file) |
| 446 | bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read); | ||
| 447 | else { | ||
| 448 | bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); | ||
| 449 | bytes_read = PAGE_SIZE; | ||
| 450 | } | ||
| 398 | if (IS_ERR(bitmap->sb_page)) { | 451 | if (IS_ERR(bitmap->sb_page)) { |
| 399 | err = PTR_ERR(bitmap->sb_page); | 452 | err = PTR_ERR(bitmap->sb_page); |
| 400 | bitmap->sb_page = NULL; | 453 | bitmap->sb_page = NULL; |
| @@ -625,14 +678,16 @@ static void bitmap_file_kick(struct bitmap *bitmap) | |||
| 625 | bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET); | 678 | bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET); |
| 626 | bitmap_update_sb(bitmap); | 679 | bitmap_update_sb(bitmap); |
| 627 | 680 | ||
| 628 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); | 681 | if (bitmap->file) { |
| 629 | if (path) | 682 | path = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 630 | ptr = file_path(bitmap->file, path, PAGE_SIZE); | 683 | if (path) |
| 684 | ptr = file_path(bitmap->file, path, PAGE_SIZE); | ||
| 631 | 685 | ||
| 632 | printk(KERN_ALERT "%s: kicking failed bitmap file %s from array!\n", | 686 | printk(KERN_ALERT "%s: kicking failed bitmap file %s from array!\n", |
| 633 | bmname(bitmap), ptr ? ptr : ""); | 687 | bmname(bitmap), ptr ? ptr : ""); |
| 634 | 688 | ||
| 635 | kfree(path); | 689 | kfree(path); |
| 690 | } | ||
| 636 | 691 | ||
| 637 | bitmap_file_put(bitmap); | 692 | bitmap_file_put(bitmap); |
| 638 | 693 | ||
| @@ -676,7 +731,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block) | |||
| 676 | void *kaddr; | 731 | void *kaddr; |
| 677 | unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap); | 732 | unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap); |
| 678 | 733 | ||
| 679 | if (!bitmap->file || !bitmap->filemap) { | 734 | if (!bitmap->filemap) { |
| 680 | return; | 735 | return; |
| 681 | } | 736 | } |
| 682 | 737 | ||
| @@ -715,7 +770,7 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
| 715 | * flushed out to disk */ | 770 | * flushed out to disk */ |
| 716 | for (i = 0; i < bitmap->file_pages; i++) { | 771 | for (i = 0; i < bitmap->file_pages; i++) { |
| 717 | spin_lock_irqsave(&bitmap->lock, flags); | 772 | spin_lock_irqsave(&bitmap->lock, flags); |
| 718 | if (!bitmap->file || !bitmap->filemap) { | 773 | if (!bitmap->filemap) { |
| 719 | spin_unlock_irqrestore(&bitmap->lock, flags); | 774 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 720 | return 0; | 775 | return 0; |
| 721 | } | 776 | } |
| @@ -732,11 +787,15 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
| 732 | return 1; | 787 | return 1; |
| 733 | } | 788 | } |
| 734 | if (wait) { /* if any writes were performed, we need to wait on them */ | 789 | if (wait) { /* if any writes were performed, we need to wait on them */ |
| 735 | spin_lock_irq(&bitmap->write_lock); | 790 | if (bitmap->file) { |
| 736 | wait_event_lock_irq(bitmap->write_wait, | 791 | spin_lock_irq(&bitmap->write_lock); |
| 737 | list_empty(&bitmap->complete_pages), bitmap->write_lock, | 792 | wait_event_lock_irq(bitmap->write_wait, |
| 738 | wake_up_process(bitmap->writeback_daemon->tsk)); | 793 | list_empty(&bitmap->complete_pages), bitmap->write_lock, |
| 739 | spin_unlock_irq(&bitmap->write_lock); | 794 | wake_up_process(bitmap->writeback_daemon->tsk)); |
| 795 | spin_unlock_irq(&bitmap->write_lock); | ||
| 796 | } else | ||
| 797 | wait_event(bitmap->mddev->sb_wait, | ||
| 798 | atomic_read(&bitmap->mddev->pending_writes)==0); | ||
| 740 | } | 799 | } |
| 741 | return 0; | 800 | return 0; |
| 742 | } | 801 | } |
| @@ -764,7 +823,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
| 764 | chunks = bitmap->chunks; | 823 | chunks = bitmap->chunks; |
| 765 | file = bitmap->file; | 824 | file = bitmap->file; |
| 766 | 825 | ||
| 767 | BUG_ON(!file); | 826 | BUG_ON(!file && !bitmap->offset); |
| 768 | 827 | ||
| 769 | #if INJECT_FAULTS_3 | 828 | #if INJECT_FAULTS_3 |
| 770 | outofdate = 1; | 829 | outofdate = 1; |
| @@ -779,7 +838,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
| 779 | 838 | ||
| 780 | num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE; | 839 | num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE; |
| 781 | 840 | ||
| 782 | if (i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { | 841 | if (file && i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) { |
| 783 | printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n", | 842 | printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n", |
| 784 | bmname(bitmap), | 843 | bmname(bitmap), |
| 785 | (unsigned long) i_size_read(file->f_mapping->host), | 844 | (unsigned long) i_size_read(file->f_mapping->host), |
| @@ -816,14 +875,18 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
| 816 | */ | 875 | */ |
| 817 | page = bitmap->sb_page; | 876 | page = bitmap->sb_page; |
| 818 | offset = sizeof(bitmap_super_t); | 877 | offset = sizeof(bitmap_super_t); |
| 819 | } else { | 878 | } else if (file) { |
| 820 | page = read_page(file, index, &dummy); | 879 | page = read_page(file, index, &dummy); |
| 821 | if (IS_ERR(page)) { /* read error */ | 880 | offset = 0; |
| 822 | ret = PTR_ERR(page); | 881 | } else { |
| 823 | goto out; | 882 | page = read_sb_page(bitmap->mddev, bitmap->offset, index); |
| 824 | } | ||
| 825 | offset = 0; | 883 | offset = 0; |
| 826 | } | 884 | } |
| 885 | if (IS_ERR(page)) { /* read error */ | ||
| 886 | ret = PTR_ERR(page); | ||
| 887 | goto out; | ||
| 888 | } | ||
| 889 | |||
| 827 | oldindex = index; | 890 | oldindex = index; |
| 828 | oldpage = page; | 891 | oldpage = page; |
| 829 | kmap(page); | 892 | kmap(page); |
| @@ -874,6 +937,19 @@ out: | |||
| 874 | return ret; | 937 | return ret; |
| 875 | } | 938 | } |
| 876 | 939 | ||
| 940 | void bitmap_write_all(struct bitmap *bitmap) | ||
| 941 | { | ||
| 942 | /* We don't actually write all bitmap blocks here, | ||
| 943 | * just flag them as needing to be written | ||
| 944 | */ | ||
| 945 | |||
| 946 | unsigned long chunks = bitmap->chunks; | ||
| 947 | unsigned long bytes = (chunks+7)/8 + sizeof(bitmap_super_t); | ||
| 948 | unsigned long num_pages = (bytes + PAGE_SIZE-1) / PAGE_SIZE; | ||
| 949 | while (num_pages--) | ||
| 950 | bitmap->filemap_attr[num_pages] |= BITMAP_PAGE_NEEDWRITE; | ||
| 951 | } | ||
| 952 | |||
| 877 | 953 | ||
| 878 | static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) | 954 | static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) |
| 879 | { | 955 | { |
| @@ -913,7 +989,7 @@ int bitmap_daemon_work(struct bitmap *bitmap) | |||
| 913 | for (j = 0; j < bitmap->chunks; j++) { | 989 | for (j = 0; j < bitmap->chunks; j++) { |
| 914 | bitmap_counter_t *bmc; | 990 | bitmap_counter_t *bmc; |
| 915 | spin_lock_irqsave(&bitmap->lock, flags); | 991 | spin_lock_irqsave(&bitmap->lock, flags); |
| 916 | if (!bitmap->file || !bitmap->filemap) { | 992 | if (!bitmap->filemap) { |
| 917 | /* error or shutdown */ | 993 | /* error or shutdown */ |
| 918 | spin_unlock_irqrestore(&bitmap->lock, flags); | 994 | spin_unlock_irqrestore(&bitmap->lock, flags); |
| 919 | break; | 995 | break; |
| @@ -1072,6 +1148,7 @@ static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr, | |||
| 1072 | 1148 | ||
| 1073 | spin_lock_irqsave(&bitmap->lock, flags); | 1149 | spin_lock_irqsave(&bitmap->lock, flags); |
| 1074 | *ptr = NULL; | 1150 | *ptr = NULL; |
| 1151 | |||
| 1075 | if (!bitmap->file) /* no need for daemon if there's no backing file */ | 1152 | if (!bitmap->file) /* no need for daemon if there's no backing file */ |
| 1076 | goto out_unlock; | 1153 | goto out_unlock; |
| 1077 | 1154 | ||
| @@ -1416,9 +1493,11 @@ int bitmap_create(mddev_t *mddev) | |||
| 1416 | 1493 | ||
| 1417 | BUG_ON(sizeof(bitmap_super_t) != 256); | 1494 | BUG_ON(sizeof(bitmap_super_t) != 256); |
| 1418 | 1495 | ||
| 1419 | if (!file) /* bitmap disabled, nothing to do */ | 1496 | if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */ |
| 1420 | return 0; | 1497 | return 0; |
| 1421 | 1498 | ||
| 1499 | BUG_ON(file && mddev->bitmap_offset); | ||
| 1500 | |||
| 1422 | bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL); | 1501 | bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL); |
| 1423 | if (!bitmap) | 1502 | if (!bitmap) |
| 1424 | return -ENOMEM; | 1503 | return -ENOMEM; |
| @@ -1438,7 +1517,8 @@ int bitmap_create(mddev_t *mddev) | |||
| 1438 | return -ENOMEM; | 1517 | return -ENOMEM; |
| 1439 | 1518 | ||
| 1440 | bitmap->file = file; | 1519 | bitmap->file = file; |
| 1441 | get_file(file); | 1520 | bitmap->offset = mddev->bitmap_offset; |
| 1521 | if (file) get_file(file); | ||
| 1442 | /* read superblock from bitmap file (this sets bitmap->chunksize) */ | 1522 | /* read superblock from bitmap file (this sets bitmap->chunksize) */ |
| 1443 | err = bitmap_read_sb(bitmap); | 1523 | err = bitmap_read_sb(bitmap); |
| 1444 | if (err) | 1524 | if (err) |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7075bebb7f37..fde8acfac320 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -337,7 +337,7 @@ static int bi_complete(struct bio *bio, unsigned int bytes_done, int error) | |||
| 337 | return 0; | 337 | return 0; |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | static int sync_page_io(struct block_device *bdev, sector_t sector, int size, | 340 | int sync_page_io(struct block_device *bdev, sector_t sector, int size, |
| 341 | struct page *page, int rw) | 341 | struct page *page, int rw) |
| 342 | { | 342 | { |
| 343 | struct bio *bio = bio_alloc(GFP_NOIO, 1); | 343 | struct bio *bio = bio_alloc(GFP_NOIO, 1); |
| @@ -609,6 +609,17 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 609 | memcpy(mddev->uuid+12,&sb->set_uuid3, 4); | 609 | memcpy(mddev->uuid+12,&sb->set_uuid3, 4); |
| 610 | 610 | ||
| 611 | mddev->max_disks = MD_SB_DISKS; | 611 | mddev->max_disks = MD_SB_DISKS; |
| 612 | |||
| 613 | if (sb->state & (1<<MD_SB_BITMAP_PRESENT) && | ||
| 614 | mddev->bitmap_file == NULL) { | ||
| 615 | if (mddev->level != 1) { | ||
| 616 | /* FIXME use a better test */ | ||
| 617 | printk(KERN_WARNING "md: bitmaps only support for raid1\n"); | ||
| 618 | return -EINVAL; | ||
| 619 | } | ||
| 620 | mddev->bitmap_offset = (MD_SB_BYTES >> 9); | ||
| 621 | } | ||
| 622 | |||
| 612 | } else if (mddev->pers == NULL) { | 623 | } else if (mddev->pers == NULL) { |
| 613 | /* Insist on good event counter while assembling */ | 624 | /* Insist on good event counter while assembling */ |
| 614 | __u64 ev1 = md_event(sb); | 625 | __u64 ev1 = md_event(sb); |
| @@ -702,6 +713,9 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 702 | sb->layout = mddev->layout; | 713 | sb->layout = mddev->layout; |
| 703 | sb->chunk_size = mddev->chunk_size; | 714 | sb->chunk_size = mddev->chunk_size; |
| 704 | 715 | ||
| 716 | if (mddev->bitmap && mddev->bitmap_file == NULL) | ||
| 717 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); | ||
| 718 | |||
| 705 | sb->disks[0].state = (1<<MD_DISK_REMOVED); | 719 | sb->disks[0].state = (1<<MD_DISK_REMOVED); |
| 706 | ITERATE_RDEV(mddev,rdev2,tmp) { | 720 | ITERATE_RDEV(mddev,rdev2,tmp) { |
| 707 | mdp_disk_t *d; | 721 | mdp_disk_t *d; |
| @@ -898,6 +912,15 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 898 | memcpy(mddev->uuid, sb->set_uuid, 16); | 912 | memcpy(mddev->uuid, sb->set_uuid, 16); |
| 899 | 913 | ||
| 900 | mddev->max_disks = (4096-256)/2; | 914 | mddev->max_disks = (4096-256)/2; |
| 915 | |||
| 916 | if ((le32_to_cpu(sb->feature_map) & 1) && | ||
| 917 | mddev->bitmap_file == NULL ) { | ||
| 918 | if (mddev->level != 1) { | ||
| 919 | printk(KERN_WARNING "md: bitmaps only supported for raid1\n"); | ||
| 920 | return -EINVAL; | ||
| 921 | } | ||
| 922 | mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset); | ||
| 923 | } | ||
| 901 | } else if (mddev->pers == NULL) { | 924 | } else if (mddev->pers == NULL) { |
| 902 | /* Insist of good event counter while assembling */ | 925 | /* Insist of good event counter while assembling */ |
| 903 | __u64 ev1 = le64_to_cpu(sb->events); | 926 | __u64 ev1 = le64_to_cpu(sb->events); |
| @@ -960,6 +983,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 960 | else | 983 | else |
| 961 | sb->resync_offset = cpu_to_le64(0); | 984 | sb->resync_offset = cpu_to_le64(0); |
| 962 | 985 | ||
| 986 | if (mddev->bitmap && mddev->bitmap_file == NULL) { | ||
| 987 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); | ||
| 988 | sb->feature_map = cpu_to_le32(1); | ||
| 989 | } | ||
| 990 | |||
| 963 | max_dev = 0; | 991 | max_dev = 0; |
| 964 | ITERATE_RDEV(mddev,rdev2,tmp) | 992 | ITERATE_RDEV(mddev,rdev2,tmp) |
| 965 | if (rdev2->desc_nr+1 > max_dev) | 993 | if (rdev2->desc_nr+1 > max_dev) |
| @@ -2406,7 +2434,8 @@ static int set_bitmap_file(mddev_t *mddev, int fd) | |||
| 2406 | mdname(mddev)); | 2434 | mdname(mddev)); |
| 2407 | fput(mddev->bitmap_file); | 2435 | fput(mddev->bitmap_file); |
| 2408 | mddev->bitmap_file = NULL; | 2436 | mddev->bitmap_file = NULL; |
| 2409 | } | 2437 | } else |
| 2438 | mddev->bitmap_offset = 0; /* file overrides offset */ | ||
| 2410 | return err; | 2439 | return err; |
| 2411 | } | 2440 | } |
| 2412 | 2441 | ||
| @@ -3774,6 +3803,13 @@ void md_check_recovery(mddev_t *mddev) | |||
| 3774 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); | 3803 | set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
| 3775 | if (!spares) | 3804 | if (!spares) |
| 3776 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 3805 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
| 3806 | if (spares && mddev->bitmap && ! mddev->bitmap->file) { | ||
| 3807 | /* We are adding a device or devices to an array | ||
| 3808 | * which has the bitmap stored on all devices. | ||
| 3809 | * So make sure all bitmap pages get written | ||
| 3810 | */ | ||
| 3811 | bitmap_write_all(mddev->bitmap); | ||
| 3812 | } | ||
| 3777 | mddev->sync_thread = md_register_thread(md_do_sync, | 3813 | mddev->sync_thread = md_register_thread(md_do_sync, |
| 3778 | mddev, | 3814 | mddev, |
| 3779 | "%s_resync"); | 3815 | "%s_resync"); |
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index cfe60cfc8f3d..e24b74b11150 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
| @@ -217,6 +217,7 @@ struct bitmap { | |||
| 217 | /* bitmap spinlock */ | 217 | /* bitmap spinlock */ |
| 218 | spinlock_t lock; | 218 | spinlock_t lock; |
| 219 | 219 | ||
| 220 | long offset; /* offset from superblock if file is NULL */ | ||
| 220 | struct file *file; /* backing disk file */ | 221 | struct file *file; /* backing disk file */ |
| 221 | struct page *sb_page; /* cached copy of the bitmap file superblock */ | 222 | struct page *sb_page; /* cached copy of the bitmap file superblock */ |
| 222 | struct page **filemap; /* list of cache pages for the file */ | 223 | struct page **filemap; /* list of cache pages for the file */ |
| @@ -255,6 +256,7 @@ void bitmap_print_sb(struct bitmap *bitmap); | |||
| 255 | int bitmap_update_sb(struct bitmap *bitmap); | 256 | int bitmap_update_sb(struct bitmap *bitmap); |
| 256 | 257 | ||
| 257 | int bitmap_setallbits(struct bitmap *bitmap); | 258 | int bitmap_setallbits(struct bitmap *bitmap); |
| 259 | void bitmap_write_all(struct bitmap *bitmap); | ||
| 258 | 260 | ||
| 259 | /* these are exported */ | 261 | /* these are exported */ |
| 260 | int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); | 262 | int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); |
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index 75f41d8faed2..ffa316ce4dc8 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h | |||
| @@ -60,7 +60,14 @@ | |||
| 60 | */ | 60 | */ |
| 61 | #define MD_MAJOR_VERSION 0 | 61 | #define MD_MAJOR_VERSION 0 |
| 62 | #define MD_MINOR_VERSION 90 | 62 | #define MD_MINOR_VERSION 90 |
| 63 | #define MD_PATCHLEVEL_VERSION 1 | 63 | /* |
| 64 | * MD_PATCHLEVEL_VERSION indicates kernel functionality. | ||
| 65 | * >=1 means different superblock formats are selectable using SET_ARRAY_INFO | ||
| 66 | * and major_version/minor_version accordingly | ||
| 67 | * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT | ||
| 68 | * in the super status byte | ||
| 69 | */ | ||
| 70 | #define MD_PATCHLEVEL_VERSION 2 | ||
| 64 | 71 | ||
| 65 | extern int register_md_personality (int p_num, mdk_personality_t *p); | 72 | extern int register_md_personality (int p_num, mdk_personality_t *p); |
| 66 | extern int unregister_md_personality (int p_num); | 73 | extern int unregister_md_personality (int p_num); |
| @@ -78,6 +85,12 @@ extern void md_unplug_mddev(mddev_t *mddev); | |||
| 78 | 85 | ||
| 79 | extern void md_print_devices (void); | 86 | extern void md_print_devices (void); |
| 80 | 87 | ||
| 88 | extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | ||
| 89 | sector_t sector, int size, struct page *page); | ||
| 90 | extern int sync_page_io(struct block_device *bdev, sector_t sector, int size, | ||
| 91 | struct page *page, int rw); | ||
| 92 | |||
| 93 | |||
| 81 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } | 94 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } |
| 82 | 95 | ||
| 83 | #endif | 96 | #endif |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 3e977025cf43..a3725b57fb7d 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
| @@ -273,6 +273,10 @@ struct mddev_s | |||
| 273 | 273 | ||
| 274 | struct bitmap *bitmap; /* the bitmap for the device */ | 274 | struct bitmap *bitmap; /* the bitmap for the device */ |
| 275 | struct file *bitmap_file; /* the bitmap file */ | 275 | struct file *bitmap_file; /* the bitmap file */ |
| 276 | long bitmap_offset; /* offset from superblock of | ||
| 277 | * start of bitmap. May be | ||
| 278 | * negative, but not '0' | ||
| 279 | */ | ||
| 276 | 280 | ||
| 277 | struct list_head all_mddevs; | 281 | struct list_head all_mddevs; |
| 278 | }; | 282 | }; |
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h index 8ba95d67329f..8e592a25a8b5 100644 --- a/include/linux/raid/md_p.h +++ b/include/linux/raid/md_p.h | |||
| @@ -96,6 +96,7 @@ typedef struct mdp_device_descriptor_s { | |||
| 96 | #define MD_SB_CLEAN 0 | 96 | #define MD_SB_CLEAN 0 |
| 97 | #define MD_SB_ERRORS 1 | 97 | #define MD_SB_ERRORS 1 |
| 98 | 98 | ||
| 99 | #define MD_SB_BITMAP_PRESENT 8 /* bitmap may be present nearby */ | ||
| 99 | typedef struct mdp_superblock_s { | 100 | typedef struct mdp_superblock_s { |
| 100 | /* | 101 | /* |
| 101 | * Constant generic information | 102 | * Constant generic information |
| @@ -184,7 +185,7 @@ struct mdp_superblock_1 { | |||
| 184 | /* constant array information - 128 bytes */ | 185 | /* constant array information - 128 bytes */ |
| 185 | __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ | 186 | __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ |
| 186 | __u32 major_version; /* 1 */ | 187 | __u32 major_version; /* 1 */ |
| 187 | __u32 feature_map; /* 0 for now */ | 188 | __u32 feature_map; /* bit 0 set if 'bitmap_offset' is meaningful */ |
| 188 | __u32 pad0; /* always set to 0 when writing */ | 189 | __u32 pad0; /* always set to 0 when writing */ |
| 189 | 190 | ||
| 190 | __u8 set_uuid[16]; /* user-space generated. */ | 191 | __u8 set_uuid[16]; /* user-space generated. */ |
| @@ -197,6 +198,10 @@ struct mdp_superblock_1 { | |||
| 197 | 198 | ||
| 198 | __u32 chunksize; /* in 512byte sectors */ | 199 | __u32 chunksize; /* in 512byte sectors */ |
| 199 | __u32 raid_disks; | 200 | __u32 raid_disks; |
| 201 | __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts | ||
| 202 | * NOTE: signed, so bitmap can be before superblock | ||
| 203 | * only meaningful of feature_map[0] is set. | ||
| 204 | */ | ||
| 200 | __u8 pad1[128-96]; /* set to 0 when written */ | 205 | __u8 pad1[128-96]; /* set to 0 when written */ |
| 201 | 206 | ||
| 202 | /* constant this-device information - 64 bytes */ | 207 | /* constant this-device information - 64 bytes */ |
