]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super0.c
Manage: Add support for --re-add faulty
[thirdparty/mdadm.git] / super0.c
index 3061ecfe76f41b7e21e3f36a75866f6502114ad8..ecb6b38202c26c9db6fbbd0307aba352bc95782a 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -114,7 +114,7 @@ static void examine_super0(struct supertype *st, char *homehost)
        c=map_num(pers, sb->level);
        printf("     Raid Level : %s\n", c?c:"-unknown-");
        if ((int)sb->level > 0) {
-               int ddsks=0;
+               int ddsks = 0, ddsks_denom = 1;
                printf("  Used Dev Size : %d%s\n", sb->size,
                       human_size((long long)sb->size<<10));
                switch(sb->level) {
@@ -122,11 +122,15 @@ static void examine_super0(struct supertype *st, char *homehost)
                case 4:
                case 5: ddsks = sb->raid_disks-1; break;
                case 6: ddsks = sb->raid_disks-2; break;
-               case 10: ddsks = sb->raid_disks / (sb->layout&255) / ((sb->layout>>8)&255);
+               case 10: ddsks = sb->raid_disks;
+                       ddsks_denom =  (sb->layout&255) * ((sb->layout>>8)&255);
+               }
+               if (ddsks) {
+                       long long asize = sb->size;
+                       asize = (asize << 10) * ddsks / ddsks_denom;
+                       printf("     Array Size : %llu%s\n",
+                              asize >> 10,  human_size(asize));
                }
-               if (ddsks)
-                       printf("     Array Size : %llu%s\n", (unsigned long long)ddsks * sb->size,
-                              human_size(ddsks*(long long)sb->size<<10));
        }
        printf("   Raid Devices : %d\n", sb->raid_disks);
        printf("  Total Devices : %d\n", sb->nr_disks);
@@ -360,6 +364,9 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info, char *map)
        info->array.state = sb->state;
        info->component_size = sb->size*2;
 
+       if (sb->state & (1<<MD_SB_BITMAP_PRESENT))
+               info->bitmap_offset = 8;
+
        info->disk.state = sb->this_disk.state;
        info->disk.major = sb->this_disk.major;
        info->disk.minor = sb->this_disk.minor;
@@ -411,7 +418,7 @@ static struct mdinfo *container_content0(struct supertype *st, char *subarray)
        if (subarray)
                return NULL;
 
-       info = malloc(sizeof(*info));
+       info = xmalloc(sizeof(*info));
        getinfo_super0(st, info, NULL);
        return info;
 }
@@ -438,12 +445,12 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                       sb32+MD_SB_GENERIC_CONSTANT_WORDS+7+1,
                       (MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1))*4);
                if (verbose >= 0)
-                       fprintf (stderr, Name ": adjusting superblock of %s for 2.2/sparc compatability.\n",
-                                devname);
+                       pr_err("adjusting superblock of %s for 2.2/sparc compatibility.\n",
+                              devname);
        } else if (strcmp(update, "super-minor") ==0) {
                sb->md_minor = info->array.md_minor;
                if (verbose > 0)
-                       fprintf(stderr, Name ": updating superblock of %s with minor number %d\n",
+                       pr_err("updating superblock of %s with minor number %d\n",
                                devname, info->array.md_minor);
        } else if (strcmp(update, "summaries") == 0) {
                unsigned int i;
@@ -594,14 +601,19 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
 
 static int init_super0(struct supertype *st, mdu_array_info_t *info,
                       unsigned long long size, char *ignored_name, char *homehost,
-                      int *uuid)
+                      int *uuid, unsigned long long data_offset)
 {
        mdp_super_t *sb;
        int spares;
 
+       if (data_offset != INVALID_SECTORS) {
+               fprintf(stderr, Name ": data-offset not support for 0.90\n");
+               return 0;
+       }
+
        if (posix_memalign((void**)&sb, 4096,
                           MD_SB_BYTES + ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) {
-               fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
+               pr_err("%s could not allocate superblock\n", __func__);
                return 0;
        }
        memset(sb, 0, MD_SB_BYTES + sizeof(bitmap_super_t));
@@ -614,7 +626,7 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info,
 
        spares = info->working_disks - info->active_disks;
        if (info->raid_disks + spares  > MD_SB_DISKS) {
-               fprintf(stderr, Name ": too many devices requested: %d+%d > %d\n",
+               pr_err("too many devices requested: %d+%d > %d\n",
                        info->raid_disks , spares, MD_SB_DISKS);
                return 0;
        }
@@ -626,9 +638,9 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info,
        sb->gvalid_words = 0; /* ignored */
        sb->ctime = time(0);
        sb->level = info->level;
-       if (size != (unsigned long long)info->size)
+       sb->size = size;
+       if (size != (unsigned long long)sb->size)
                return 0;
-       sb->size = info->size;
        sb->nr_disks = info->nr_disks;
        sb->raid_disks = info->raid_disks;
        sb->md_minor = info->md_minor;
@@ -650,7 +662,7 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info,
                if (rfd >= 0)
                        close(rfd);
        }
-       if (homehost) {
+       if (homehost && !uuid) {
                char buf[20];
                char *hash = sha1_buffer(homehost,
                                         strlen(homehost),
@@ -683,7 +695,7 @@ struct devinfo {
 #ifndef MDASSEMBLE
 /* Add a device to the superblock being created */
 static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
-                         int fd, char *devname)
+                        int fd, char *devname, unsigned long long data_offset)
 {
        mdp_super_t *sb = st->sb;
        mdp_disk_t *dk = &sb->disks[dinfo->number];
@@ -703,7 +715,7 @@ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
        dip = (struct devinfo **)&st->info;
        while (*dip)
                dip = &(*dip)->next;
-       di = malloc(sizeof(struct devinfo));
+       di = xmalloc(sizeof(struct devinfo));
        di->fd = fd;
        di->devname = devname;
        di->disk = *dinfo;
@@ -761,7 +773,7 @@ static int write_init_super0(struct supertype *st)
                        continue;
                if (di->fd == -1)
                        continue;
-               while (Kill(di->devname, NULL, 0, 1, 1) == 0)
+               while (Kill(di->devname, NULL, 0, -1, 1) == 0)
                        ;
 
                sb->disks[di->disk.number].state &= ~(1<<MD_DISK_FAULTY);
@@ -774,9 +786,8 @@ static int write_init_super0(struct supertype *st)
                        rv = st->ss->write_bitmap(st, di->fd);
 
                if (rv)
-                       fprintf(stderr,
-                               Name ": failed to write superblock to %s\n",
-                               di->devname);
+                       pr_err("failed to write superblock to %s\n",
+                              di->devname);
        }
        return rv;
 }
@@ -801,8 +812,7 @@ static int compare_super0(struct supertype *st, struct supertype *tst)
                if (posix_memalign((void**)&first, 4096,
                             MD_SB_BYTES + 
                             ROUND_UP(sizeof(struct bitmap_super_s), 4096)) != 0) {
-                       fprintf(stderr, Name
-                               ": %s could not allocate superblock\n", __func__);
+                       pr_err("%s could not allocate superblock\n", __func__);
                        return 1;
                }
                memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s));
@@ -851,9 +861,8 @@ static int load_super0(struct supertype *st, int fd, char *devname)
 
        if (dsize < MD_RESERVED_SECTORS*512) {
                if (devname)
-                       fprintf(stderr, Name
-                           ": %s is too small for md: size is %llu sectors.\n",
-                               devname, dsize);
+                       pr_err("%s is too small for md: size is %llu sectors.\n",
+                              devname, dsize);
                return 1;
        }
 
@@ -865,7 +874,7 @@ static int load_super0(struct supertype *st, int fd, char *devname)
 
        if (lseek64(fd, offset, 0)< 0LL) {
                if (devname)
-                       fprintf(stderr, Name ": Cannot seek to superblock on %s: %s\n",
+                       pr_err("Cannot seek to superblock on %s: %s\n",
                                devname, strerror(errno));
                return 1;
        }
@@ -873,14 +882,13 @@ static int load_super0(struct supertype *st, int fd, char *devname)
        if (posix_memalign((void**)&super, 4096,
                           MD_SB_BYTES +
                           ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) {
-               fprintf(stderr, Name
-                       ": %s could not allocate superblock\n", __func__);
+               pr_err("%s could not allocate superblock\n", __func__);
                return 1;
        }
 
        if (read(fd, super, sizeof(*super)) != MD_SB_BYTES) {
                if (devname)
-                       fprintf(stderr, Name ": Cannot read superblock on %s\n",
+                       pr_err("Cannot read superblock on %s\n",
                                devname);
                free(super);
                return 1;
@@ -891,7 +899,7 @@ static int load_super0(struct supertype *st, int fd, char *devname)
 
        if (super->md_magic != MD_SB_MAGIC) {
                if (devname)
-                       fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n",
+                       pr_err("No super block found on %s (Expected magic %08x, got %08x)\n",
                                devname, MD_SB_MAGIC, super->md_magic);
                free(super);
                return 2;
@@ -899,7 +907,7 @@ static int load_super0(struct supertype *st, int fd, char *devname)
 
        if (super->major_version != 0) {
                if (devname)
-                       fprintf(stderr, Name ": Cannot interpret superblock on %s - version is %d\n",
+                       pr_err("Cannot interpret superblock on %s - version is %d\n",
                                devname, super->major_version);
                free(super);
                return 2;
@@ -939,10 +947,8 @@ static int load_super0(struct supertype *st, int fd, char *devname)
 
 static struct supertype *match_metadata_desc0(char *arg)
 {
-       struct supertype *st = malloc(sizeof(*st));
-       if (!st) return st;
+       struct supertype *st = xcalloc(1, sizeof(*st));
 
-       memset(st, 0, sizeof(*st));
        st->container_dev = NoMdDev;
        st->ss = &super0;
        st->info = NULL;
@@ -974,8 +980,11 @@ static struct supertype *match_metadata_desc0(char *arg)
        return NULL;
 }
 
-static __u64 avail_size0(struct supertype *st, __u64 devsize)
+static __u64 avail_size0(struct supertype *st, __u64 devsize,
+                        unsigned long long data_offset)
 {
+       if (data_offset != 0 && data_offset != INVALID_SECTORS)
+               return 0ULL;
        if (devsize < MD_RESERVED_SECTORS)
                return 0ULL;
        return MD_NEW_SIZE_SECTORS(devsize);
@@ -1062,13 +1071,11 @@ static int write_bitmap0(struct supertype *st, int fd)
        int rv = 0;
 
        int towrite, n;
-       char abuf[4096+4096];
-       char *buf = (char*)(((long)(abuf+4096))&~4095L);
+       void *buf;
 
        if (!get_dev_size(fd, NULL, &dsize))
                return 1;
 
-
        if (dsize < MD_RESERVED_SECTORS*512)
                return -1;
 
@@ -1079,6 +1086,9 @@ static int write_bitmap0(struct supertype *st, int fd)
        if (lseek64(fd, offset + 4096, 0)< 0LL)
                return 3;
 
+       if (posix_memalign(&buf, 4096, 4096))
+               return -ENOMEM;
+
        memset(buf, 0xff, 4096);
        memcpy(buf,  ((char*)sb)+MD_SB_BYTES, sizeof(bitmap_super_t));
        towrite = 60*1024;
@@ -1097,6 +1107,7 @@ static int write_bitmap0(struct supertype *st, int fd)
        if (towrite)
                rv = -2;
 
+       free(buf);
        return rv;
 }
 
@@ -1118,6 +1129,7 @@ static void free_super0(struct supertype *st)
 static int validate_geometry0(struct supertype *st, int level,
                              int layout, int raiddisks,
                              int *chunk, unsigned long long size,
+                             unsigned long long data_offset,
                              char *subdev, unsigned long long *freesize,
                              int verbose)
 {
@@ -1133,19 +1145,19 @@ static int validate_geometry0(struct supertype *st, int level,
 
        if (level == LEVEL_CONTAINER) {
                if (verbose)
-                       fprintf(stderr, Name ": 0.90 metadata does not support containers\n");
+                       pr_err("0.90 metadata does not support containers\n");
                return 0;
        }
        if (raiddisks > MD_SB_DISKS) {
                if (verbose)
-                       fprintf(stderr, Name ": 0.90 metadata supports at most %d devices per array\n",
+                       pr_err("0.90 metadata supports at most %d devices per array\n",
                                MD_SB_DISKS);
                return 0;
        }
-       if (size >= tbmax * 1024*1024*1024*2ULL) {
+       if (size >= tbmax * 2ULL*1024*1024*1024) {
                if (verbose)
-                       fprintf(stderr, Name ": 0.90 metadata supports at most "
-                               "%d terabytes per device\n", tbmax);
+                       pr_err("0.90 metadata supports at most "
+                              "%d terabytes per device\n", tbmax);
                return 0;
        }
        if (chunk && *chunk == UnSet)
@@ -1157,7 +1169,7 @@ static int validate_geometry0(struct supertype *st, int level,
        fd = open(subdev, O_RDONLY|O_EXCL, 0);
        if (fd < 0) {
                if (verbose)
-                       fprintf(stderr, Name ": super0.90 cannot open %s: %s\n",
+                       pr_err("super0.90 cannot open %s: %s\n",
                                subdev, strerror(errno));
                return 0;
        }