From a19c88b83db3cc25affb75fe2d5531c964379d96 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 15 May 2008 16:48:18 +1000 Subject: [PATCH] Start on --assemble support for DDF --- Assemble.c | 36 ++++++++++++++++++++++++++++++++++-- super-ddf.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Assemble.c b/Assemble.c index 86212032..16dec246 100644 --- a/Assemble.c +++ b/Assemble.c @@ -843,6 +843,24 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, /* Almost ready to actually *do* something */ if (!old_linux) { int rv; + +#ifndef MDASSEMBLE + struct mdinfo *sra; + if (st->ss->external) { + char ver[100]; + strcat(strcpy(ver, "external:"), st->ss->text_version); + sra = sysfs_read(mdfd, 0, 0); + if ((vers % 100) < 2 || + sra == NULL || + sysfs_set_str(sra, NULL, "metadata_version", + ver) < 0) { + fprintf(stderr, Name ": This kernel does not " + "support external metadata.\n"); + return 1; + } + rv = sysfs_set_array(sra, &info); + } else +#endif if ((vers % 100) >= 1) { /* can use different versions */ mdu_array_info_t inf; memset(&inf, 0, sizeof(inf)); @@ -893,8 +911,22 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, j = chosen_drive; if (j >= 0 /* && devices[j].uptodate */) { - if (ioctl(mdfd, ADD_NEW_DISK, - &devices[j].i.disk)!=0) { +#ifndef MDASSEMBLE + if (st->ss->external) { + int fd = dev_open(devices[j].devname, + O_RDONLY); + if (fd < 0) + rv = 1; + else { + rv = sysfs_add_disk(sra, fd, + &devices[j].i); + close(fd); + } + } else +#endif + rv = ioctl(mdfd, ADD_NEW_DISK, + &devices[j].i.disk); + if (rv) { fprintf(stderr, Name ": failed to add " "%s to %s: %s\n", devices[j].devname, diff --git a/super-ddf.c b/super-ddf.c index 457470d7..b0ed7394 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -1149,6 +1149,7 @@ static void uuid_from_super_ddf(struct supertype *st, int uuid[4]) static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) { struct ddf_super *ddf = st->sb; + int i; info->array.major_version = 1000; info->array.minor_version = 0; /* FIXME use ddf->revision somehow */ @@ -1167,9 +1168,17 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) info->disk.major = 0; info->disk.minor = 0; -// info->disk.number = __be32_to_cpu(ddf->disk.refnum); + info->disk.number = __be32_to_cpu(ddf->dlist->disk.refnum); // info->disk.raid_disk = find refnum in the table and use index; -// info->disk.state = ???; + info->disk.raid_disk = -1; + for (i = 0; i < __be16_to_cpu(ddf->phys->max_pdes) ; i++) + if (ddf->phys->entries[i].refnum == ddf->dlist->disk.refnum) { + info->disk.raid_disk = i; + break; + } + info->disk.state = (1 << MD_DISK_SYNC); + + info->reshape_active = 0; // uuid_from_super_ddf(info->uuid, sbv); @@ -2248,6 +2257,31 @@ static int store_zero_ddf(struct supertype *st, int fd) return 0; } +static int compare_super_ddf(struct supertype *st, struct supertype *tst) +{ + /* + * return: + * 0 same, or first was empty, and second was copied + * 1 second had wrong number + * 2 wrong uuid + * 3 wrong other info + */ + struct ddf_super *first = st->sb; + struct ddf_super *second = tst->sb; + + if (!first) { + st->sb = tst->sb; + tst->sb = NULL; + return 0; + } + + if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0) + return 2; + + /* FIXME should I look at anything else? */ + return 0; +} + struct superswitch super_ddf = { #ifndef MDASSEMBLE .examine_super = examine_super_ddf, @@ -2263,6 +2297,8 @@ struct superswitch super_ddf = { .avail_size = avail_size_ddf, + .compare_super = compare_super_ddf, + .load_super = load_super_ddf, .init_super = init_zero_ddf, .store_super = store_zero_ddf, -- 2.39.2