From: Neil Brown Date: Sat, 12 Jul 2008 10:27:39 +0000 (+1000) Subject: Remove getinfo_super_n and do some other cleaning up. X-Git-Tag: mdadm-3.0-devel1~145 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=d2ca644994d642c31b41242140e1fe819711c8f7 Remove getinfo_super_n and do some other cleaning up. Getting close to a sensible description of what some of the superswitch methods are supposed to do! --- diff --git a/Assemble.c b/Assemble.c index d9b9b810..7efa2b8c 100644 --- a/Assemble.c +++ b/Assemble.c @@ -914,14 +914,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, if (j >= 0 /* && devices[j].uptodate */) { #ifndef MDASSEMBLE - if (st->ss->external) { - devices[j].i.disk.number = - devices[j].i.disk.raid_disk; - st->ss->getinfo_super_n(st, - &devices[j].i); - rv = sysfs_add_disk(sra, - &devices[j].i); - } else + if (st->ss->external) + rv = sysfs_add_disk(sra, &devices[j].i); + else #endif rv = ioctl(mdfd, ADD_NEW_DISK, &devices[j].i.disk); diff --git a/Create.c b/Create.c index 495cf39a..71871f68 100644 --- a/Create.c +++ b/Create.c @@ -66,6 +66,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, int second_missing = subdevs * 2; int missing_disks = 0; int insert_point = subdevs * 2; /* where to insert a missing drive */ + int total_slots; int pass; int vers; int rv; @@ -75,7 +76,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, int need_mdmon = 0; unsigned long long bitmapsize; struct mdinfo *sra; - struct mdinfo info; + struct mdinfo info, *infos; int did_default = 0; int major_num = BITMAP_MAJOR_HI; @@ -515,6 +516,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, if (!st->ss->init_super(st, &info.array, size, name, homehost, uuid)) return 1; + total_slots = info.array.nr_disks; st->ss->getinfo_super(st, &info); if (did_default) @@ -625,6 +627,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, } } + infos = malloc(sizeof(*infos) * total_slots); for (pass=1; pass <=2 ; pass++) { mddev_dev_t moved_disk = NULL; /* the disk that was moved out of the insert point */ @@ -633,58 +636,66 @@ int Create(struct supertype *st, char *mddev, int mdfd, dv=(dv->next)?(dv->next):moved_disk, dnum++) { int fd; struct stat stb; + struct mdinfo *inf = &infos[dnum]; - info.disk.number = dnum; + if (dnum >= total_slots) + abort(); if (dnum == insert_point) { moved_disk = dv; } - info.disk.raid_disk = info.disk.number; - if (info.disk.raid_disk < raiddisks) - info.disk.state = (1<writemostly) - info.disk.state |= (1<devname, "missing")==0) continue; - if (st->ss->external && st->subarray[0]) - fd = open(dv->devname, O_RDWR, 0); - else - fd = open(dv->devname, O_RDWR|O_EXCL,0); + switch(pass) { + case 1: + *inf = info; - if (fd < 0) { - fprintf(stderr, Name ": failed to open %s " - "after earlier success - aborting\n", - dv->devname); - return 1; - } - fstat(fd, &stb); - info.disk.major = major(stb.st_rdev); - info.disk.minor = minor(stb.st_rdev); + inf->disk.number = dnum; + inf->disk.raid_disk = dnum; + if (inf->disk.raid_disk < raiddisks) + inf->disk.state = (1<disk.state = 0; + + if (dv->writemostly) + inf->disk.state |= (1<ss->external && st->subarray[0]) + fd = open(dv->devname, O_RDWR, 0); + else + fd = open(dv->devname, O_RDWR|O_EXCL,0); + + if (fd < 0) { + fprintf(stderr, Name ": failed to open %s " + "after earlier success - aborting\n", + dv->devname); + return 1; + } + fstat(fd, &stb); + inf->disk.major = major(stb.st_rdev); + inf->disk.minor = minor(stb.st_rdev); - switch(pass){ - case 1: remove_partitions(fd); - st->ss->add_to_super(st, &info.disk, + st->ss->add_to_super(st, &inf->disk, fd, dv->devname); + st->ss->getinfo_super(st, inf); + + /* getinfo_super might have lost these ... */ + inf->disk.major = major(stb.st_rdev); + inf->disk.minor = minor(stb.st_rdev); break; case 2: - close(fd); - info.component_size = info.array.size * 2; - info.errors = 0; + inf->errors = 0; rv = 0; - if (st->ss->external) { - st->ss->getinfo_super_n(st, &info); - rv = sysfs_add_disk(sra, &info); - } else { + if (st->ss->external) + rv = sysfs_add_disk(sra, inf); + else rv = ioctl(mdfd, ADD_NEW_DISK, - &info.disk); - } + &inf->disk); + if (rv) { fprintf(stderr, Name ": ADD_NEW_DISK for %s " @@ -700,6 +711,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, if (pass == 1) st->ss->write_init_super(st); } + free(infos); st->ss->free_super(st); /* param is not actually used */ diff --git a/mdadm.h b/mdadm.h index c728badc..e23a7033 100644 --- a/mdadm.h +++ b/mdadm.h @@ -429,10 +429,12 @@ extern struct superswitch { * The determination is made either by: * load_super being given a 'component' string. * validate_geometry determining what to create. - * getinfo_super_n really needs to be removed.. + * The info includes both array information and device information. + * The particular device should be: + * The last device added by add_to_super + * The device the metadata was loaded from by load_super */ void (*getinfo_super)(struct supertype *st, struct mdinfo *info); - void (*getinfo_super_n)(struct supertype *st, struct mdinfo *info); /* Check if the given metadata is flagged as belonging to "this" * host. For arrays that don't determine a minor-number, this diff --git a/super-ddf.c b/super-ddf.c index 50fd16b4..a5470062 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -401,6 +401,7 @@ struct ddf_super { struct virtual_disk *virt; int pdsize, vdsize; int max_part, mppe, conf_rec_len; + int currentdev; struct vcl { struct vcl *next; __u64 *lba_offset; /* location in 'conf' of @@ -408,13 +409,14 @@ struct ddf_super { int vcnum; /* index into ->virt */ __u64 *block_sizes; /* NULL if all the same */ struct vd_config conf; - } *conflist, *newconf; + } *conflist, *currentconf; struct dl { struct dl *next; struct disk_data disk; int major, minor; char *devname; int fd; + unsigned long long size; /* sectors */ int pdnum; /* index in ->phys */ struct spare_assign *spare; struct vcl *vlist[0]; /* max_part in size */ @@ -628,6 +630,7 @@ static int load_ddf_local(int fd, struct ddf_super *super, int i; int vnum; int max_virt_disks = __be16_to_cpu(super->active->max_vd_entries); + unsigned long long dsize; /* First the local disk info */ dl = malloc(sizeof(*dl) + @@ -644,6 +647,10 @@ static int load_ddf_local(int fd, struct ddf_super *super, dl->minor = minor(stb.st_rdev); dl->next = super->dlist; dl->fd = keep ? fd : -1; + + dl->size = 0; + if (get_dev_size(fd, devname, &dsize)) + dl->size = dsize >> 9; dl->spare = NULL; for (i=0 ; i < super->max_part ; i++) dl->vlist[i] = NULL; @@ -1206,17 +1213,17 @@ static void uuid_from_super_ddf(struct supertype *st, int uuid[4]) * The first 16 bytes of the sha1 of these is used. */ struct ddf_super *ddf = st->sb; - struct vd_config *vd = &ddf->newconf->conf; + struct vcl *vcl = ddf->currentconf; - if (!vd) + if (!vcl) memset(uuid, 0, sizeof (uuid)); else { char buf[20]; struct sha1_ctx ctx; sha1_init_ctx(&ctx); - sha1_process_bytes(&vd->guid, DDF_GUID_LEN, &ctx); - if (vd->sec_elmnt_count > 1) - sha1_process_bytes(&vd->sec_elmnt_seq, 1, &ctx); + sha1_process_bytes(&vcl->conf.guid, DDF_GUID_LEN, &ctx); + if (vcl->conf.sec_elmnt_count > 1) + sha1_process_bytes(&vcl->conf.sec_elmnt_seq, 1, &ctx); sha1_finish_ctx(&ctx, buf); memcpy(uuid, buf, sizeof(uuid)); } @@ -1235,20 +1242,24 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) info->array.utime = 0; info->array.chunk_size = 0; -// info->data_offset = ???; -// info->component_size = ???; info->disk.major = 0; info->disk.minor = 0; if (ddf->dlist) { info->disk.number = __be32_to_cpu(ddf->dlist->disk.refnum); info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum); + + info->data_offset = __be64_to_cpu(ddf->phys-> + entries[info->disk.raid_disk]. + config_size); + info->component_size = ddf->dlist->size - info->data_offset; } else { info->disk.number = -1; // info->disk.raid_disk = find refnum in the table and use index; } info->disk.state = (1 << MD_DISK_SYNC); + info->reshape_active = 0; strcpy(info->text_version, "ddf"); @@ -1258,36 +1269,33 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) // info->name[] ?? ; } -static void getinfo_super_n_container(struct supertype *st, struct mdinfo *info) -{ - /* just need offset and size */ - struct ddf_super *ddf = st->sb; - int n = info->disk.number; - - info->data_offset = __be64_to_cpu(ddf->phys->entries[n].config_size); - info->component_size = 32*1024*1024 / 512; -} - static int rlq_to_layout(int rlq, int prl, int raiddisks); static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info) { struct ddf_super *ddf = st->sb; - struct vd_config *vd = find_vdcr(ddf, info->container_member); + struct vcl *vc = ddf->currentconf; + int cd = ddf->currentdev; /* FIXME this returns BVD info - what if we want SVD ?? */ - info->array.raid_disks = __be16_to_cpu(vd->prim_elmnt_count); - info->array.level = map_num1(ddf_level_num, vd->prl); - info->array.layout = rlq_to_layout(vd->rlq, vd->prl, + info->array.raid_disks = __be16_to_cpu(vc->conf.prim_elmnt_count); + info->array.level = map_num1(ddf_level_num, vc->conf.prl); + info->array.layout = rlq_to_layout(vc->conf.rlq, vc->conf.prl, info->array.raid_disks); info->array.md_minor = -1; - info->array.ctime = DECADE + __be32_to_cpu(*(__u32*)(vd->guid+16)); - info->array.utime = DECADE + __be32_to_cpu(vd->timestamp); - info->array.chunk_size = 512 << vd->chunk_shift; - -// info->data_offset = ???; -// info->component_size = ???; + info->array.ctime = DECADE + + __be32_to_cpu(*(__u32*)(vc->conf.guid+16)); + info->array.utime = DECADE + __be32_to_cpu(vc->conf.timestamp); + info->array.chunk_size = 512 << vc->conf.chunk_shift; + + if (cd >= 0 && cd < ddf->mppe) { + info->data_offset = __be64_to_cpu(vc->lba_offset[cd]); + if (vc->block_sizes) + info->component_size = vc->block_sizes[cd]; + else + info->component_size = __be64_to_cpu(vc->conf.blocks); + } info->disk.major = 0; info->disk.minor = 0; @@ -1312,17 +1320,6 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info) // info->name[] ?? ; } -static void getinfo_super_n_bvd(struct supertype *st, struct mdinfo *info) -{ - /* Find the particular details for info->disk.raid_disk. - * This includes data_offset, component_size, - */ - struct ddf_super *ddf = st->sb; - __u64 *lba_offset = ddf->newconf->lba_offset; - struct vd_config *conf = &ddf->newconf->conf; - info->data_offset = __be64_to_cpu(lba_offset[info->disk.raid_disk]); - info->component_size = __be64_to_cpu(conf->blocks); -} static int update_super_ddf(struct supertype *st, struct mdinfo *info, char *update, @@ -1868,7 +1865,7 @@ static int init_super_ddf_bvd(struct supertype *st, vcl->next = ddf->conflist; ddf->conflist = vcl; - ddf->newconf = vcl; + ddf->currentconf = vcl; return 1; } @@ -1898,8 +1895,8 @@ static void add_to_super_ddf_bvd(struct supertype *st, if (!dl || ! (dk->state & (1<newconf->conf; - lba_offset = ddf->newconf->lba_offset; + vc = &ddf->currentconf->conf; + lba_offset = ddf->currentconf->lba_offset; ex = get_extents(ddf, dl); if (!ex) @@ -1907,8 +1904,8 @@ static void add_to_super_ddf_bvd(struct supertype *st, i = 0; pos = 0; blocks = __be64_to_cpu(vc->blocks); - if (ddf->newconf->block_sizes) - blocks = ddf->newconf->block_sizes[dk->raid_disk]; + if (ddf->currentconf->block_sizes) + blocks = ddf->currentconf->block_sizes[dk->raid_disk]; do { esize = ex[i].start - pos; @@ -1922,6 +1919,7 @@ static void add_to_super_ddf_bvd(struct supertype *st, if (esize < blocks) return; + ddf->currentdev = dk->raid_disk; vc->phys_refnum[dk->raid_disk] = dl->disk.refnum; lba_offset[dk->raid_disk] = __cpu_to_be64(pos); @@ -1930,7 +1928,7 @@ static void add_to_super_ddf_bvd(struct supertype *st, break; if (i == ddf->max_part) return; - dl->vlist[i] = ddf->newconf; + dl->vlist[i] = ddf->currentconf; dl->fd = fd; dl->devname = devname; @@ -1945,7 +1943,7 @@ static void add_to_super_ddf_bvd(struct supertype *st, working++; /* Find which virtual_entry */ - i = ddf->newconf->vcnum; + i = ddf->currentconf->vcnum; if (working == __be16_to_cpu(vc->prim_elmnt_count)) ddf->virt->entries[i].state = (ddf->virt->entries[i].state & ~DDF_state_mask) @@ -2030,6 +2028,7 @@ static void add_to_super_ddf(struct supertype *st, sprintf(pde->path, "%17.17s","Information: nil") ; memset(pde->pad, 0xff, 6); + dd->size = size >> 9; ddf->dlist = dd; } @@ -2451,8 +2450,8 @@ static int load_super_ddf_all(struct supertype *st, int fd, for (v = super->conflist; v; v = v->next) if (v->vcnum == atoi(st->subarray)) - super->newconf = v; - if (!super->newconf) + super->currentconf = v; + if (!super->currentconf) return 1; } *sbp = super; @@ -3120,9 +3119,7 @@ struct superswitch super_ddf = { .store_super = store_zero_ddf, .free_super = free_super_ddf, .match_metadata_desc = match_metadata_desc_ddf, - .getinfo_super_n = getinfo_super_n_container, - .swapuuid = 0, .external = 1, /* for mdmon */ @@ -3152,9 +3149,7 @@ static struct superswitch super_ddf_container = { .free_super = free_super_ddf, .container_content = container_content_ddf, - .getinfo_super_n = getinfo_super_n_container, - .swapuuid = 0, .external = 1, }; @@ -3169,13 +3164,11 @@ static struct superswitch super_ddf_bvd = { .init_super = init_super_ddf_bvd, .add_to_super = add_to_super_ddf_bvd, .getinfo_super = getinfo_super_ddf_bvd, - .getinfo_super_n = getinfo_super_n_bvd, .load_super = load_super_ddf, .free_super = free_super_ddf, .match_metadata_desc = match_metadata_desc_ddf_bvd, - .swapuuid = 0, .external = 2, }; @@ -3192,6 +3185,5 @@ static struct superswitch super_ddf_svd = { .free_super = free_super_ddf, .match_metadata_desc = match_metadata_desc_ddf_svd, - .swapuuid = 0, .external = 2, }; diff --git a/super-intel.c b/super-intel.c index eb963df3..dee107cd 100644 --- a/super-intel.c +++ b/super-intel.c @@ -499,6 +499,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info) struct intel_super *super = st->sb; struct imsm_super *mpb = super->mpb; struct imsm_disk *disk; + int sect = mpb_sectors(mpb); __u32 s; info->array.raid_disks = mpb->num_disks; @@ -517,6 +518,11 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info) info->disk.number = -1; info->disk.state = 0; + info->data_offset = __le32_to_cpu(get_imsm_disk(super->mpb, + super->disks->index) + ->total_blocks) - (2 + sect - 1); + info->component_size = sect; + if (super->disks) { info->disk.number = super->disks->index; info->disk.raid_disk = super->disks->index; @@ -1286,38 +1292,9 @@ static int store_zero_imsm(struct supertype *st, int fd) memset(buf, 0, sizeof(buf)); if (write(fd, buf, sizeof(buf)) != sizeof(buf)) return 1; - return 0; } -static void getinfo_super_n_imsm_container(struct supertype *st, struct mdinfo *info) -{ - /* just need offset and size... - * of the metadata - */ - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->mpb; - struct imsm_disk *disk = get_imsm_disk(mpb, info->disk.number); - - info->data_offset = __le32_to_cpu(disk->total_blocks) - - (MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS); - info->component_size = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS; -} - -static void getinfo_super_n_imsm_volume(struct supertype *st, struct mdinfo *info) -{ - /* Find the particular details for info->disk.raid_disk. - * This includes data_offset, component_size, - */ - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->mpb; - struct imsm_dev *dev = get_imsm_dev(mpb, super->creating_dev); - struct imsm_map *map = &dev->vol.map[0]; - - info->data_offset = __le32_to_cpu(map->pba_of_lba0); - info->component_size = __le32_to_cpu(map->blocks_per_member); -} - static int validate_geometry_imsm(struct supertype *st, int level, int layout, int raiddisks, int chunk, unsigned long long size, char *dev, unsigned long long *freesize) @@ -1871,10 +1848,8 @@ struct superswitch super_imsm = { .store_super = store_zero_imsm, .free_super = free_super_imsm, .match_metadata_desc = match_metadata_desc_imsm, - .getinfo_super_n = getinfo_super_n_imsm_container, .validate_geometry = validate_geometry_imsm, - .swapuuid = 0, .external = 1, /* for mdmon */ @@ -1895,7 +1870,6 @@ struct superswitch super_imsm_container = { .add_to_super = add_to_super_imsm, .write_init_super = write_init_super_imsm, .getinfo_super = getinfo_super_imsm, - .getinfo_super_n = getinfo_super_n_imsm_container, .load_super = load_super_imsm, #ifndef MDASSEMBLE @@ -1909,7 +1883,6 @@ struct superswitch super_imsm_container = { .container_content = container_content_imsm, - .swapuuid = 0, .external = 1, }; @@ -1918,7 +1891,6 @@ static struct superswitch super_imsm_volume = { .init_super = init_super_imsm_volume, .add_to_super = add_to_super_imsm_volume, .getinfo_super = getinfo_super_imsm_volume, - .getinfo_super_n = getinfo_super_n_imsm_volume, .write_init_super = write_init_super_imsm, .load_super = load_super_imsm, @@ -1927,6 +1899,5 @@ static struct superswitch super_imsm_volume = { .validate_geometry = validate_geometry_imsm_volume, - .swapuuid = 0, .external = 2, }; diff --git a/super0.c b/super0.c index 99847126..27999d99 100644 --- a/super0.c +++ b/super0.c @@ -645,6 +645,9 @@ static void add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo, dk->raid_disk = dinfo->raid_disk; dk->state = dinfo->state; + sb->this_disk = sb->disks[dinfo->number]; + sb->sb_csum = calc_sb0_csum(sb); + dip = (struct devinfo **)&st->info; while (*dip) dip = &(*dip)->next; @@ -1092,5 +1095,4 @@ struct superswitch super0 = { .write_bitmap = write_bitmap0, .free_super = free_super0, .validate_geometry = validate_geometry0, - .swapuuid = 0, }; diff --git a/super1.c b/super1.c index a6a308a6..bd9d1c93 100644 --- a/super1.c +++ b/super1.c @@ -789,6 +789,9 @@ static void add_to_super1(struct supertype *st, mdu_disk_info_t *dk, else *rp = 0xfffe; + sb->dev_number = __cpu_to_le32(dk->number); + sb->sb_csum = calc_sb_1_csum(sb); + dip = (struct devinfo **)&st->info; while (*dip) dip = &(*dip)->next; diff --git a/util.c b/util.c index 3a5daa26..4cecd6d0 100644 --- a/util.c +++ b/util.c @@ -858,6 +858,8 @@ struct supertype *dup_super(struct supertype *orig) { struct supertype *st; + if (!orig) + return orig; st = malloc(sizeof(*st)); if (!st) return st;