aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bitmap.c132
-rw-r--r--drivers/md/md.c40
-rw-r--r--include/linux/raid/bitmap.h2
-rw-r--r--include/linux/raid/md.h15
-rw-r--r--include/linux/raid/md_k.h4
-rw-r--r--include/linux/raid/md_p.h7
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 */
262static 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
288static 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 */
264static int write_page(struct bitmap *bitmap, struct page *page, int wait) 309static 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
940void 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
878static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) 954static 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
340static int sync_page_io(struct block_device *bdev, sector_t sector, int size, 340int 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);
255int bitmap_update_sb(struct bitmap *bitmap); 256int bitmap_update_sb(struct bitmap *bitmap);
256 257
257int bitmap_setallbits(struct bitmap *bitmap); 258int bitmap_setallbits(struct bitmap *bitmap);
259void bitmap_write_all(struct bitmap *bitmap);
258 260
259/* these are exported */ 261/* these are exported */
260int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); 262int 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
65extern int register_md_personality (int p_num, mdk_personality_t *p); 72extern int register_md_personality (int p_num, mdk_personality_t *p);
66extern int unregister_md_personality (int p_num); 73extern int unregister_md_personality (int p_num);
@@ -78,6 +85,12 @@ extern void md_unplug_mddev(mddev_t *mddev);
78 85
79extern void md_print_devices (void); 86extern void md_print_devices (void);
80 87
88extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
89 sector_t sector, int size, struct page *page);
90extern 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 */
99typedef struct mdp_superblock_s { 100typedef 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 */