~ubuntu-branches/ubuntu/precise/mdadm/precise-proposed

« back to all changes in this revision

Viewing changes to super0.c

  • Committer: Package Import Robot
  • Author(s): Surbhi Palande
  • Date: 2010-09-30 17:46:19 UTC
  • mfrom: (1.4.1 experimental) (1.1.25 sid)
  • Revision ID: package-import@ubuntu.com-20100930174619-txqppxj5vhrrvlhq
Tags: 3.1.4-1+8efb9d1ubuntu1
* Merge from debian unstable. (LP: #603582) 
* Remaining changes
  - Assemble.c, config.c: upgraded to the mdadm-3.1.4 version of these files
    from Debian.
  - debian/control: we need udev and util-linux in the right version. We
    also remove the build dependency from quilt and docbook-to-man as both
    are not used in Ubuntus mdadm.
  - debian/initramfs/hook: kept the Ubuntus version for handling the absence
    of active raid arrays in <initramfs>/etc/mdadm/mdadm.conf
  - debian/initramfs/script.local-top.DEBIAN, debian/mdadm-startall,
    debian/mdadm.raid.DEBIAN: removed. udev does its job now instead.
  - debian/mdadm-startall.sgml, debian/mdadm-startall.8: documentation of
    unused startall script
  - debian/mdadm.config, debian/mdadm.postinst - let udev do the handling
    instead. Resolved merge conflict by keeping Ubuntu's version.
  - debian/rules: kept debian's switch to using dh_lintian
  - debian/mdadm.links, debian/mdadm.manpages: dropped owing to the fact
    that these are not used in Ubuntu. Also dropped the build-dep on docbook
    to man)
  - debian/mdadm.postinst, debian/mdadm.config, initramfs/init-premount:
    boot-degraded enablement; maintain udev starting of RAID devices;
    init-premount hook script for the initramfs, to provide information at
    boot
  - debian/mkconf.in is the older mkconf. Kept the Ubuntus version.
  - debian/rules: Kept Ubuntus version for installing apport hooks, not
    installing un-used startall script and for adding a udev rule
    corresponding to mdadm.
  - debian/install-rc, check.d/_numbers, check.d/root_on_raid: Ubuntu partman
    installer changes
  - debian/presubj: Dropped this unused bug reporting file. Instead use
    source_mdadm.py act as an apport hook for bug handling.
  - rename debian/mdadm.vol_id.udev to debian/mdadm.mdadm-blkid.udev so that
    the rules file ends up with a more reasonable name

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * mdadm - manage Linux "md" devices aka RAID arrays.
3
3
 *
4
 
 * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
 
4
 * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
5
5
 *
6
6
 *
7
7
 *    This program is free software; you can redistribute it and/or modify
19
19
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
20
 *
21
21
 *    Author: Neil Brown
22
 
 *    Email: <neilb@cse.unsw.edu.au>
23
 
 *    Paper: Neil Brown
24
 
 *           School of Computer Science and Engineering
25
 
 *           The University of New South Wales
26
 
 *           Sydney, 2052
27
 
 *           Australia
 
22
 *    Email: <neilb@suse.de>
28
23
 */
29
24
 
30
25
#define HAVE_STDINT_H 1
53
48
}
54
49
 
55
50
 
56
 
void super0_swap_endian(struct mdp_superblock_s *sb)
 
51
static void super0_swap_endian(struct mdp_superblock_s *sb)
57
52
{
58
53
        /* as super0 superblocks are host-endian, it is sometimes
59
54
         * useful to be able to swap the endianness
90
85
        mdp_super_t *sb = st->sb;
91
86
        time_t atime;
92
87
        int d;
 
88
        int delta_extra = 0;
93
89
        char *c;
94
90
 
95
91
        printf("          Magic : %08x\n", sb->md_magic);
96
 
        printf("        Version : %02d.%02d.%02d\n", sb->major_version, sb->minor_version,
 
92
        printf("        Version : %d.%02d.%02d\n", sb->major_version, sb->minor_version,
97
93
               sb->patch_version);
98
94
        if (sb->minor_version >= 90) {
99
95
                printf("           UUID : %08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
117
113
        printf("  Creation Time : %.24s\n", ctime(&atime));
118
114
        c=map_num(pers, sb->level);
119
115
        printf("     Raid Level : %s\n", c?c:"-unknown-");
120
 
        if ((int)sb->level >= 0) {
 
116
        if ((int)sb->level > 0) {
121
117
                int ddsks=0;
122
118
                printf("  Used Dev Size : %d%s\n", sb->size,
123
119
                       human_size((long long)sb->size<<10));
140
136
                printf("  Reshape pos'n : %llu%s\n", (unsigned long long)sb->reshape_position/2, human_size((long long)sb->reshape_position<<9));
141
137
                if (sb->delta_disks) {
142
138
                        printf("  Delta Devices : %d", sb->delta_disks);
143
 
                        if (sb->delta_disks)
144
 
                                printf(" (%d->%d)\n", sb->raid_disks-sb->delta_disks, sb->raid_disks);
145
 
                        else
146
 
                                printf(" (%d->%d)\n", sb->raid_disks, sb->raid_disks+sb->delta_disks);
 
139
                        printf(" (%d->%d)\n", sb->raid_disks-sb->delta_disks, sb->raid_disks);
 
140
                        if (((int)sb->delta_disks) < 0)
 
141
                                delta_extra = - sb->delta_disks;
147
142
                }
148
143
                if (sb->new_level != sb->level) {
149
144
                        c = map_num(pers, sb->new_level);
154
149
                                c = map_num(r5layout, sb->new_layout);
155
150
                                printf("     New Layout : %s\n", c?c:"-unknown-");
156
151
                        }
 
152
                        if (sb->level == 6) {
 
153
                                c = map_num(r6layout, sb->new_layout);
 
154
                                printf("     New Layout : %s\n", c?c:"-unknown-");
 
155
                        }
157
156
                        if (sb->level == 10) {
158
157
                                printf("     New Layout : near=%d, %s=%d\n",
159
158
                                       sb->new_layout&255,
187
186
                c = map_num(r5layout, sb->layout);
188
187
                printf("         Layout : %s\n", c?c:"-unknown-");
189
188
        }
 
189
        if (sb->level == 6) {
 
190
                c = map_num(r6layout, sb->layout);
 
191
                printf("         Layout : %s\n", c?c:"-unknown-");
 
192
        }
190
193
        if (sb->level == 10) {
191
 
                printf("         Layout : near=%d, %s=%d\n",
192
 
                       sb->layout&255,
193
 
                       (sb->layout&0x10000)?"offset":"far",
194
 
                       (sb->layout>>8)&255);
 
194
                printf("         Layout :");
 
195
                print_r10_layout(sb->layout);
 
196
                printf("\n");
195
197
        }
196
198
        switch(sb->level) {
197
199
        case 0:
208
210
        }
209
211
        printf("\n");
210
212
        printf("      Number   Major   Minor   RaidDevice State\n");
211
 
        for (d= -1; d<(signed int)(sb->raid_disks+sb->spare_disks); d++) {
 
213
        for (d= -1; d<(signed int)(sb->raid_disks+delta_extra + sb->spare_disks); d++) {
212
214
                mdp_disk_t *dp;
213
215
                char *dv;
214
216
                char nb[5];
233
235
        }
234
236
}
235
237
 
236
 
static void brief_examine_super0(struct supertype *st)
 
238
static void brief_examine_super0(struct supertype *st, int verbose)
237
239
{
238
240
        mdp_super_t *sb = st->sb;
239
241
        char *c=map_num(pers, sb->level);
241
243
 
242
244
        sprintf(devname, "/dev/md%d", sb->md_minor);
243
245
 
244
 
        printf("ARRAY %s level=%s num-devices=%d UUID=",
245
 
               devname,
246
 
               c?c:"-unknown-", sb->raid_disks);
 
246
        if (verbose) {
 
247
                printf("ARRAY %s level=%s num-devices=%d",
 
248
                       devname,
 
249
                       c?c:"-unknown-", sb->raid_disks);
 
250
        } else
 
251
                printf("ARRAY %s", devname);
 
252
 
247
253
        if (sb->minor_version >= 90)
248
 
                printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
 
254
                printf(" UUID=%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
249
255
                       sb->set_uuid2, sb->set_uuid3);
250
256
        else
251
 
                printf("%08x", sb->set_uuid0);
 
257
                printf(" UUID=%08x", sb->set_uuid0);
252
258
        printf("\n");
253
259
}
254
260
 
301
307
        else
302
308
                printf("%08x", sb->set_uuid0);
303
309
}
304
 
 
305
 
static void export_detail_super0(struct supertype *st)
306
 
{
307
 
        mdp_super_t *sb = st->sb;
308
 
        printf("MD_UUID=");
309
 
        if (sb->minor_version >= 90)
310
 
                printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
311
 
                       sb->set_uuid2, sb->set_uuid3);
312
 
        else
313
 
                printf("%08x", sb->set_uuid0);
314
 
        printf("\n");
315
 
}
316
310
#endif
317
311
 
318
312
static int match_home0(struct supertype *st, char *homehost)
319
313
{
320
314
        mdp_super_t *sb = st->sb;
321
315
        char buf[20];
322
 
        char *hash = sha1_buffer(homehost,
323
 
                                 strlen(homehost),
324
 
                                 buf);
 
316
        char *hash;
 
317
 
 
318
        if (!homehost)
 
319
                return 0;
 
320
        hash = sha1_buffer(homehost,
 
321
                           strlen(homehost),
 
322
                           buf);
325
323
 
326
324
        return (memcmp(&sb->set_uuid2, hash, 8)==0);
327
325
}
369
367
        info->events = md_event(sb);
370
368
        info->data_offset = 0;
371
369
 
 
370
        sprintf(info->text_version, "0.%d", sb->minor_version);
 
371
        info->safe_mode_delay = 200;
 
372
 
372
373
        uuid_from_super0(st, info->uuid);
373
374
 
 
375
        info->recovery_start = MaxSector;
374
376
        if (sb->minor_version > 90 && (sb->reshape_position+1) != 0) {
375
377
                info->reshape_active = 1;
376
378
                info->reshape_progress = sb->reshape_position;
378
380
                info->delta_disks = sb->delta_disks;
379
381
                info->new_layout = sb->new_layout;
380
382
                info->new_chunk = sb->new_chunk;
 
383
                if (info->delta_disks < 0)
 
384
                        info->array.raid_disks -= info->delta_disks;
381
385
        } else
382
386
                info->reshape_active = 0;
383
387
 
385
389
        /* work_disks is calculated rather than read directly */
386
390
        for (i=0; i < MD_SB_DISKS; i++)
387
391
                if ((sb->disks[i].state & (1<<MD_DISK_SYNC)) &&
388
 
                    (sb->disks[i].raid_disk < info->array.raid_disks) &&
 
392
                    (sb->disks[i].raid_disk < (unsigned)info->array.raid_disks) &&
389
393
                    (sb->disks[i].state & (1<<MD_DISK_ACTIVE)) &&
390
394
                    !(sb->disks[i].state & (1<<MD_DISK_FAULTY)))
391
395
                        working ++;
423
427
                                devname, info->array.md_minor);
424
428
        }
425
429
        if (strcmp(update, "summaries") == 0) {
426
 
                int i;
 
430
                unsigned int i;
427
431
                /* set nr_disks, active_disks, working_disks,
428
432
                 * failed_disks, spare_disks based on disks[]
429
433
                 * array in superblock.
475
479
        if (strcmp(update, "assemble")==0) {
476
480
                int d = info->disk.number;
477
481
                int wonly = sb->disks[d].state & (1<<MD_DISK_WRITEMOSTLY);
478
 
                if ((sb->disks[d].state & ~(1<<MD_DISK_WRITEMOSTLY))
479
 
                    != info->disk.state) {
 
482
                int mask = (1<<MD_DISK_WRITEMOSTLY);
 
483
                int add = 0;
 
484
                if (sb->minor_version >= 91)
 
485
                        /* During reshape we don't insist on everything
 
486
                         * being marked 'sync'
 
487
                         */
 
488
                        add = (1<<MD_DISK_SYNC);
 
489
                if (((sb->disks[d].state & ~mask) | add)
 
490
                    != (unsigned)info->disk.state) {
480
491
                        sb->disks[d].state = info->disk.state | wonly;
481
492
                        rv = 1;
482
493
                }
552
563
                       unsigned long long size, char *ignored_name, char *homehost,
553
564
                       int *uuid)
554
565
{
555
 
        mdp_super_t *sb = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
 
566
        mdp_super_t *sb;
556
567
        int spares;
 
568
 
 
569
        if (posix_memalign((void**)&sb, 4096,
 
570
                           MD_SB_BYTES + ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) {
 
571
                fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
 
572
                return 0;
 
573
        }
557
574
        memset(sb, 0, MD_SB_BYTES + sizeof(bitmap_super_t));
558
575
 
559
576
        st->sb = sb;
560
 
        if (info->major_version == -1) {
 
577
        if (info == NULL) {
561
578
                /* zeroing the superblock */
562
579
                return 0;
563
580
        }
576
593
        sb->gvalid_words = 0; /* ignored */
577
594
        sb->ctime = time(0);
578
595
        sb->level = info->level;
579
 
        if (size != info->size)
 
596
        if (size != (unsigned long long)info->size)
580
597
                return 0;
581
598
        sb->size = info->size;
582
599
        sb->nr_disks = info->nr_disks;
623
640
        return 1;
624
641
}
625
642
 
 
643
struct devinfo {
 
644
        int fd;
 
645
        char *devname;
 
646
        mdu_disk_info_t disk;
 
647
        struct devinfo *next;
 
648
};
 
649
 
 
650
#ifndef MDASSEMBLE
626
651
/* Add a device to the superblock being created */
627
 
static void add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo)
 
652
static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
 
653
                          int fd, char *devname)
628
654
{
629
655
        mdp_super_t *sb = st->sb;
630
656
        mdp_disk_t *dk = &sb->disks[dinfo->number];
 
657
        struct devinfo *di, **dip;
631
658
 
632
659
        dk->number = dinfo->number;
633
660
        dk->major = dinfo->major;
634
661
        dk->minor = dinfo->minor;
635
662
        dk->raid_disk = dinfo->raid_disk;
636
663
        dk->state = dinfo->state;
 
664
 
 
665
        sb->this_disk = sb->disks[dinfo->number];
 
666
        sb->sb_csum = calc_sb0_csum(sb);
 
667
 
 
668
        dip = (struct devinfo **)&st->info;
 
669
        while (*dip)
 
670
                dip = &(*dip)->next;
 
671
        di = malloc(sizeof(struct devinfo));
 
672
        di->fd = fd;
 
673
        di->devname = devname;
 
674
        di->disk = *dinfo;
 
675
        di->next = NULL;
 
676
        *dip = di;
 
677
 
 
678
        return 0;
637
679
}
 
680
#endif
638
681
 
639
682
static int store_super0(struct supertype *st, int fd)
640
683
{
661
704
        if (super->state & (1<<MD_SB_BITMAP_PRESENT)) {
662
705
                struct bitmap_super_s * bm = (struct bitmap_super_s*)(super+1);
663
706
                if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC)
664
 
                        if (write(fd, bm, sizeof(*bm)) != sizeof(*bm))
 
707
                        if (write(fd, bm, ROUND_UP(sizeof(*bm),4096)) != 
 
708
                            ROUND_UP(sizeof(*bm),4096))
665
709
                            return 5;
666
710
        }
667
711
 
669
713
        return 0;
670
714
}
671
715
 
672
 
static int write_init_super0(struct supertype *st,
673
 
                             mdu_disk_info_t *dinfo, char *devname)
 
716
#ifndef MDASSEMBLE
 
717
static int write_init_super0(struct supertype *st)
674
718
{
675
719
        mdp_super_t *sb = st->sb;
676
 
        int fd = open(devname, O_RDWR|O_EXCL);
677
 
        int rv;
678
 
 
679
 
        if (fd < 0) {
680
 
                fprintf(stderr, Name ": Failed to open %s to write superblock\n", devname);
681
 
                return -1;
 
720
        int rv = 0;
 
721
        struct devinfo *di;
 
722
 
 
723
        for (di = st->info ; di && ! rv ; di = di->next) {
 
724
 
 
725
                if (di->disk.state == 1)
 
726
                        continue;
 
727
                if (di->fd == -1)
 
728
                        continue;
 
729
                while (Kill(di->devname, NULL, 0, 1, 1) == 0)
 
730
                        ;
 
731
 
 
732
                sb->disks[di->disk.number].state &= ~(1<<MD_DISK_FAULTY);
 
733
 
 
734
                sb->this_disk = sb->disks[di->disk.number];
 
735
                sb->sb_csum = calc_sb0_csum(sb);
 
736
                rv = store_super0(st, di->fd);
 
737
 
 
738
                if (rv == 0 && (sb->state & (1<<MD_SB_BITMAP_PRESENT)))
 
739
                        rv = st->ss->write_bitmap(st, di->fd);
 
740
 
 
741
                if (rv)
 
742
                        fprintf(stderr,
 
743
                                Name ": failed to write superblock to %s\n",
 
744
                                di->devname);
 
745
                close(di->fd);
 
746
                di->fd = -1;
682
747
        }
683
 
 
684
 
        sb->disks[dinfo->number].state &= ~(1<<MD_DISK_FAULTY);
685
 
 
686
 
        sb->this_disk = sb->disks[dinfo->number];
687
 
        sb->sb_csum = calc_sb0_csum(sb);
688
 
        rv = store_super0(st, fd);
689
 
 
690
 
        if (rv == 0 && (sb->state & (1<<MD_SB_BITMAP_PRESENT)))
691
 
                rv = st->ss->write_bitmap(st, fd);
692
 
 
693
 
        close(fd);
694
 
        if (rv)
695
 
                fprintf(stderr, Name ": failed to write superblock to %s\n", devname);
696
748
        return rv;
697
749
}
 
750
#endif
698
751
 
699
752
static int compare_super0(struct supertype *st, struct supertype *tst)
700
753
{
712
765
        if (second->md_magic != MD_SB_MAGIC)
713
766
                return 1;
714
767
        if (!first) {
715
 
                first = malloc(MD_SB_BYTES + sizeof(struct bitmap_super_s));
 
768
                if (posix_memalign((void**)&first, 4096,
 
769
                             MD_SB_BYTES + 
 
770
                             ROUND_UP(sizeof(struct bitmap_super_s), 4096)) != 0) {
 
771
                        fprintf(stderr, Name
 
772
                                ": %s could not allocate superblock\n", __func__);
 
773
                        return 1;
 
774
                }
716
775
                memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s));
717
776
                st->sb = first;
718
777
                return 0;
754
813
 
755
814
        free_super0(st);
756
815
 
 
816
        if (st->subarray[0])
 
817
                return 1;
 
818
 
757
819
        if (!get_dev_size(fd, devname, &dsize))
758
820
                return 1;
759
821
 
778
840
                return 1;
779
841
        }
780
842
 
781
 
        super = malloc(MD_SB_BYTES + sizeof(bitmap_super_t));
 
843
        if (posix_memalign((void**)&super, 4096,
 
844
                           MD_SB_BYTES +
 
845
                           ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) {
 
846
                fprintf(stderr, Name
 
847
                        ": %s could not allocate superblock\n", __func__);
 
848
                return 1;
 
849
        }
782
850
 
783
851
        if (read(fd, super, sizeof(*super)) != MD_SB_BYTES) {
784
852
                if (devname)
812
880
                st->ss = &super0;
813
881
                st->minor_version = super->minor_version;
814
882
                st->max_devs = MD_SB_DISKS;
 
883
                st->info = NULL;
815
884
        }
816
885
 
817
886
        /* Now check on the bitmap superblock */
821
890
         * valid.  If it doesn't clear the bit.  An --assemble --force
822
891
         * should get that written out.
823
892
         */
824
 
        if (read(fd, super+1, sizeof(struct bitmap_super_s))
825
 
            != sizeof(struct bitmap_super_s))
 
893
        if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),4096))
 
894
            != ROUND_UP(sizeof(struct bitmap_super_s),4096))
826
895
                goto no_bitmap;
827
896
 
828
897
        uuid_from_super0(st, uuid);
843
912
        struct supertype *st = malloc(sizeof(*st));
844
913
        if (!st) return st;
845
914
 
 
915
        memset(st, 0, sizeof(*st));
846
916
        st->ss = &super0;
 
917
        st->info = NULL;
847
918
        st->minor_version = 90;
848
919
        st->max_devs = MD_SB_DISKS;
849
920
        st->sb = NULL;
 
921
        /* we sometimes get 00.90 */
 
922
        while (arg[0] == '0' && arg[1] == '0')
 
923
                arg++;
850
924
        if (strcmp(arg, "0") == 0 ||
 
925
#ifdef DEFAULT_OLD_METADATA /* ifndef in super1.c */
 
926
            strcmp(arg, "default") == 0 ||
 
927
#endif /* DEFAULT_OLD_METADATA */
851
928
            strcmp(arg, "0.90") == 0 ||
852
 
            strcmp(arg, "0.91") == 0 ||
853
 
            strcmp(arg, "default") == 0 ||
854
 
            strcmp(arg, "") == 0 /* no metadata */
 
929
            strcmp(arg, "") == 0 /* no metadata  - i.e. non_persistent */
855
930
                )
856
931
                return st;
857
932
 
 
933
        st->minor_version = 91; /* reshape in progress */
 
934
        if (strcmp(arg, "0.91") == 0) /* For dup_super support */
 
935
                return st;
 
936
 
858
937
        st->minor_version = 9; /* flag for 'byte-swapped' */
859
938
        if (strcmp(arg, "0.swap")==0 ||
860
939
            strcmp(arg, "0.9") == 0) /* For dup_super support */
883
962
         * size is in sectors,  chunk is in bytes !!!
884
963
         */
885
964
        unsigned long long bits;
886
 
        unsigned long long max_bits = 60*1024*8;
 
965
        unsigned long long max_bits = (60*1024 - sizeof(bitmap_super_t))*8;
887
966
        unsigned long long min_chunk;
888
967
        int chunk = *chunkp;
889
968
        mdp_super_t *sb = st->sb;
896
975
                min_chunk *= 2;
897
976
                bits = (bits+1)/2;
898
977
        }
899
 
        if (chunk == UnSet)
 
978
        if (chunk == UnSet) {
 
979
                /* A chunk size less than a few Megabytes gives poor
 
980
                 * performance without increasing resync noticeably
 
981
                 */
900
982
                chunk = min_chunk;
901
 
        else if (chunk < min_chunk)
 
983
                if (chunk < 64*1024*1024)
 
984
                        chunk = 64*1024*1024;
 
985
        } else if ((unsigned long long)chunk < min_chunk)
902
986
                return 0; /* chunk size too small */
903
987
 
904
988
        sb->state |= (1<<MD_SB_BITMAP_PRESENT);
916
1000
}
917
1001
 
918
1002
 
919
 
void locate_bitmap0(struct supertype *st, int fd)
 
1003
static void locate_bitmap0(struct supertype *st, int fd)
920
1004
{
921
1005
        unsigned long long dsize;
922
1006
        unsigned long long offset;
936
1020
        lseek64(fd, offset, 0);
937
1021
}
938
1022
 
939
 
int write_bitmap0(struct supertype *st, int fd)
 
1023
static int write_bitmap0(struct supertype *st, int fd)
940
1024
{
941
1025
        unsigned long long dsize;
942
1026
        unsigned long long offset;
945
1029
        int rv = 0;
946
1030
 
947
1031
        int towrite, n;
948
 
        char buf[4096];
 
1032
        char abuf[4096+4096];
 
1033
        char *buf = (char*)(((long)(abuf+4096))&~4095L);
949
1034
 
950
1035
        if (!get_dev_size(fd, NULL, &dsize))
951
1036
                return 1;
961
1046
        if (lseek64(fd, offset + 4096, 0)< 0LL)
962
1047
                return 3;
963
1048
 
964
 
 
965
 
        if (write(fd, ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t)) !=
966
 
            sizeof(bitmap_super_t))
967
 
                return -2;
968
 
        towrite = 64*1024 - MD_SB_BYTES - sizeof(bitmap_super_t);
969
 
        memset(buf, 0xff, sizeof(buf));
 
1049
        memset(buf, 0xff, 4096);
 
1050
        memcpy(buf,  ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t));
 
1051
        towrite = 60*1024;
970
1052
        while (towrite > 0) {
971
1053
                n = towrite;
972
 
                if (n > sizeof(buf))
973
 
                        n = sizeof(buf);
 
1054
                if (n > 4096)
 
1055
                        n = 4096;
974
1056
                n = write(fd, buf, n);
975
1057
                if (n > 0)
976
1058
                        towrite -= n;
977
1059
                else
978
1060
                        break;
 
1061
                memset(buf, 0xff, 4096);
979
1062
        }
980
1063
        fsync(fd);
981
1064
        if (towrite)
991
1074
        st->sb = NULL;
992
1075
}
993
1076
 
 
1077
#ifndef MDASSEMBLE
 
1078
static int validate_geometry0(struct supertype *st, int level,
 
1079
                              int layout, int raiddisks,
 
1080
                              int chunk, unsigned long long size,
 
1081
                              char *subdev, unsigned long long *freesize,
 
1082
                              int verbose)
 
1083
{
 
1084
        unsigned long long ldsize;
 
1085
        int fd;
 
1086
 
 
1087
        if (level == LEVEL_CONTAINER) {
 
1088
                if (verbose)
 
1089
                        fprintf(stderr, Name ": 0.90 metadata does not support containers\n");
 
1090
                return 0;
 
1091
        }
 
1092
        if (raiddisks > MD_SB_DISKS) {
 
1093
                if (verbose)
 
1094
                        fprintf(stderr, Name ": 0.90 metadata supports at most %d devices per array\n",
 
1095
                                MD_SB_DISKS);
 
1096
                return 0;
 
1097
        }
 
1098
        if (size > (0x7fffffffULL<<9)) {
 
1099
                if (verbose)
 
1100
                        fprintf(stderr, Name ": 0.90 metadata supports at most 2 terrabytes per device\n");
 
1101
                return 0;
 
1102
        }
 
1103
        if (!subdev)
 
1104
                return 1;
 
1105
 
 
1106
        fd = open(subdev, O_RDONLY|O_EXCL, 0);
 
1107
        if (fd < 0) {
 
1108
                if (verbose)
 
1109
                        fprintf(stderr, Name ": super0.90 cannot open %s: %s\n",
 
1110
                                subdev, strerror(errno));
 
1111
                return 0;
 
1112
        }
 
1113
 
 
1114
        if (!get_dev_size(fd, subdev, &ldsize)) {
 
1115
                close(fd);
 
1116
                return 0;
 
1117
        }
 
1118
        close(fd);
 
1119
 
 
1120
        if (ldsize < MD_RESERVED_SECTORS * 512)
 
1121
                return 0;
 
1122
        if (size > (0x7fffffffULL<<9))
 
1123
                return 0;
 
1124
        *freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9);
 
1125
        return 1;
 
1126
}
 
1127
#endif /* MDASSEMBLE */
 
1128
 
994
1129
struct superswitch super0 = {
995
1130
#ifndef MDASSEMBLE
996
1131
        .examine_super = examine_super0,
998
1133
        .export_examine_super = export_examine_super0,
999
1134
        .detail_super = detail_super0,
1000
1135
        .brief_detail_super = brief_detail_super0,
1001
 
        .export_detail_super = export_detail_super0,
 
1136
        .write_init_super = write_init_super0,
 
1137
        .validate_geometry = validate_geometry0,
 
1138
        .add_to_super = add_to_super0,
1002
1139
#endif
1003
1140
        .match_home = match_home0,
1004
1141
        .uuid_from_super = uuid_from_super0,
1005
1142
        .getinfo_super = getinfo_super0,
1006
1143
        .update_super = update_super0,
1007
1144
        .init_super = init_super0,
1008
 
        .add_to_super = add_to_super0,
1009
1145
        .store_super = store_super0,
1010
 
        .write_init_super = write_init_super0,
1011
1146
        .compare_super = compare_super0,
1012
1147
        .load_super = load_super0,
1013
1148
        .match_metadata_desc = match_metadata_desc0,
1016
1151
        .locate_bitmap = locate_bitmap0,
1017
1152
        .write_bitmap = write_bitmap0,
1018
1153
        .free_super = free_super0,
1019
 
        .major = 0,
1020
 
        .swapuuid = 0,
 
1154
        .name = "0.90",
1021
1155
};