super-ddf.c (mdadm-4.1) | : | super-ddf.c (mdadm-4.2) | ||
---|---|---|---|---|
skipping to change at line 1733 | skipping to change at line 1733 | |||
goto err; | goto err; | |||
written += n; | written += n; | |||
} | } | |||
free(buf); | free(buf); | |||
return 0; | return 0; | |||
err: | err: | |||
free(buf); | free(buf); | |||
return 1; | return 1; | |||
} | } | |||
static void detail_super_ddf(struct supertype *st, char *homehost) | static void detail_super_ddf(struct supertype *st, char *homehost, | |||
char *subarray) | ||||
{ | { | |||
struct ddf_super *sb = st->sb; | struct ddf_super *sb = st->sb; | |||
int cnt = be16_to_cpu(sb->virt->populated_vdes); | int cnt = be16_to_cpu(sb->virt->populated_vdes); | |||
printf(" Container GUID : "); print_guid(sb->anchor.guid, 1); | printf(" Container GUID : "); print_guid(sb->anchor.guid, 1); | |||
printf("\n"); | printf("\n"); | |||
printf(" Seq : %08x\n", be32_to_cpu(sb->active->seq)); | printf(" Seq : %08x\n", be32_to_cpu(sb->active->seq)); | |||
printf(" Virtual Disks : %d\n", cnt); | printf(" Virtual Disks : %d\n", cnt); | |||
printf("\n"); | printf("\n"); | |||
} | } | |||
skipping to change at line 1790 | skipping to change at line 1791 | |||
p += DDF_GUID_LEN; | p += DDF_GUID_LEN; | |||
memcpy(p, ddf->virt->entries[vcnum].name, 16); | memcpy(p, ddf->virt->entries[vcnum].name, 16); | |||
p += 16; | p += 16; | |||
*((__u16 *) p) = vcnum; | *((__u16 *) p) = vcnum; | |||
sha1_init_ctx(&ctx); | sha1_init_ctx(&ctx); | |||
sha1_process_bytes(buf, sizeof(buf), &ctx); | sha1_process_bytes(buf, sizeof(buf), &ctx); | |||
sha1_finish_ctx(&ctx, sha); | sha1_finish_ctx(&ctx, sha); | |||
memcpy(uuid, sha, 4*4); | memcpy(uuid, sha, 4*4); | |||
} | } | |||
static void brief_detail_super_ddf(struct supertype *st) | static void brief_detail_super_ddf(struct supertype *st, char *subarray) | |||
{ | { | |||
struct mdinfo info; | struct mdinfo info; | |||
char nbuf[64]; | char nbuf[64]; | |||
struct ddf_super *ddf = st->sb; | struct ddf_super *ddf = st->sb; | |||
unsigned int vcnum = get_vd_num_of_subarray(st); | unsigned int vcnum = get_vd_num_of_subarray(st); | |||
if (vcnum == DDF_CONTAINER) | if (vcnum == DDF_CONTAINER) | |||
uuid_from_super_ddf(st, info.uuid); | uuid_from_super_ddf(st, info.uuid); | |||
else if (vcnum == DDF_NOTFOUND) | else if (vcnum == DDF_NOTFOUND) | |||
return; | return; | |||
else | else | |||
skipping to change at line 1903 | skipping to change at line 1904 | |||
} | } | |||
if (!find_index_in_bvd(ddf, conf, | if (!find_index_in_bvd(ddf, conf, | |||
n - nsec*conf->sec_elmnt_count, n_bvd)) | n - nsec*conf->sec_elmnt_count, n_bvd)) | |||
goto bad; | goto bad; | |||
dprintf("found disk %u as member %u in bvd %d of array %u\n", | dprintf("found disk %u as member %u in bvd %d of array %u\n", | |||
n, *n_bvd, ibvd, inst); | n, *n_bvd, ibvd, inst); | |||
*vcl = v; | *vcl = v; | |||
return conf; | return conf; | |||
} | } | |||
bad: | bad: | |||
pr_err("Could't find disk %d in array %u\n", n, inst); | pr_err("Couldn't find disk %d in array %u\n", n, inst); | |||
return NULL; | return NULL; | |||
} | } | |||
static int find_phys(const struct ddf_super *ddf, be32 phys_refnum) | static int find_phys(const struct ddf_super *ddf, be32 phys_refnum) | |||
{ | { | |||
/* Find the entry in phys_disk which has the given refnum | /* Find the entry in phys_disk which has the given refnum | |||
* and return it's index | * and return it's index | |||
*/ | */ | |||
unsigned int i; | unsigned int i; | |||
for (i = 0; i < be16_to_cpu(ddf->phys->max_pdes); i++) | for (i = 0; i < be16_to_cpu(ddf->phys->max_pdes); i++) | |||
skipping to change at line 2639 | skipping to change at line 2640 | |||
ve->guid_crc._v16 = crc32(0, (unsigned char *)ddf->anchor.guid, | ve->guid_crc._v16 = crc32(0, (unsigned char *)ddf->anchor.guid, | |||
DDF_GUID_LEN); | DDF_GUID_LEN); | |||
ve->type = cpu_to_be16(0); | ve->type = cpu_to_be16(0); | |||
ve->state = DDF_state_degraded; /* Will be modified as devices are added */ | ve->state = DDF_state_degraded; /* Will be modified as devices are added */ | |||
if (info->state & 1) /* clean */ | if (info->state & 1) /* clean */ | |||
ve->init_state = DDF_init_full; | ve->init_state = DDF_init_full; | |||
else | else | |||
ve->init_state = DDF_init_not; | ve->init_state = DDF_init_not; | |||
memset(ve->pad1, 0xff, 14); | memset(ve->pad1, 0xff, 14); | |||
memset(ve->name, ' ', 16); | memset(ve->name, '\0', sizeof(ve->name)); | |||
if (name) | if (name) { | |||
strncpy(ve->name, name, 16); | int l = strnlen(name, sizeof(ve->name)); | |||
memcpy(ve->name, name, l); | ||||
} | ||||
ddf->virt->populated_vdes = | ddf->virt->populated_vdes = | |||
cpu_to_be16(be16_to_cpu(ddf->virt->populated_vdes)+1); | cpu_to_be16(be16_to_cpu(ddf->virt->populated_vdes)+1); | |||
/* Now create a new vd_config */ | /* Now create a new vd_config */ | |||
if (posix_memalign((void**)&vcl, 512, | if (posix_memalign((void**)&vcl, 512, | |||
(offsetof(struct vcl, conf) + ddf->conf_rec_len * 512) ) != 0) { | (offsetof(struct vcl, conf) + ddf->conf_rec_len * 512) ) != 0) { | |||
pr_err("could not allocate vd_config\n"); | pr_err("could not allocate vd_config\n"); | |||
return 0; | return 0; | |||
} | } | |||
vcl->vcnum = venum; | vcl->vcnum = venum; | |||
skipping to change at line 3465 | skipping to change at line 3468 | |||
int verbose) | int verbose) | |||
{ | { | |||
int fd; | int fd; | |||
unsigned long long ldsize; | unsigned long long ldsize; | |||
if (level != LEVEL_CONTAINER) | if (level != LEVEL_CONTAINER) | |||
return 0; | return 0; | |||
if (!dev) | if (!dev) | |||
return 1; | return 1; | |||
fd = open(dev, O_RDONLY|O_EXCL, 0); | fd = dev_open(dev, O_RDONLY|O_EXCL); | |||
if (fd < 0) { | if (fd < 0) { | |||
if (verbose) | if (verbose) | |||
pr_err("ddf: Cannot open %s: %s\n", | pr_err("ddf: Cannot open %s: %s\n", | |||
dev, strerror(errno)); | dev, strerror(errno)); | |||
return 0; | return 0; | |||
} | } | |||
if (!get_dev_size(fd, dev, &ldsize)) { | if (!get_dev_size(fd, dev, &ldsize)) { | |||
close(fd); | close(fd); | |||
return 0; | return 0; | |||
} | } | |||
close(fd); | close(fd); | |||
if (freesize) { | ||||
*freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); | *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); | |||
if (*freesize == 0) | if (*freesize == 0) | |||
return 0; | return 0; | |||
} | ||||
return 1; | return 1; | |||
} | } | |||
static int validate_geometry_ddf_bvd(struct supertype *st, | static int validate_geometry_ddf_bvd(struct supertype *st, | |||
int level, int layout, int raiddisks, | int level, int layout, int raiddisks, | |||
int *chunk, unsigned long long size, | int *chunk, unsigned long long size, | |||
unsigned long long data_offset, | unsigned long long data_offset, | |||
char *dev, unsigned long long *freesize, | char *dev, unsigned long long *freesize, | |||
int verbose) | int verbose) | |||
skipping to change at line 3916 | skipping to change at line 3920 | |||
memset(buf, 0, 512); | memset(buf, 0, 512); | |||
lseek64(fd, dsize-512, 0); | lseek64(fd, dsize-512, 0); | |||
rc = write(fd, buf, 512); | rc = write(fd, buf, 512); | |||
free(buf); | free(buf); | |||
if (rc < 0) | if (rc < 0) | |||
return 1; | return 1; | |||
return 0; | return 0; | |||
} | } | |||
static int compare_super_ddf(struct supertype *st, struct supertype *tst) | static int compare_super_ddf(struct supertype *st, struct supertype *tst, | |||
int verbose) | ||||
{ | { | |||
/* | /* | |||
* return: | * return: | |||
* 0 same, or first was empty, and second was copied | * 0 same, or first was empty, and second was copied | |||
* 1 second had wrong magic number - but that isn't possible | * 1 second had wrong magic number - but that isn't possible | |||
* 2 wrong uuid | * 2 wrong uuid | |||
* 3 wrong other info | * 3 wrong other info | |||
*/ | */ | |||
struct ddf_super *first = st->sb; | struct ddf_super *first = st->sb; | |||
struct ddf_super *second = tst->sb; | struct ddf_super *second = tst->sb; | |||
skipping to change at line 4057 | skipping to change at line 4062 | |||
return 0; | return 0; | |||
} | } | |||
/* | /* | |||
* A new array 'a' has been started which claims to be instance 'inst' | * A new array 'a' has been started which claims to be instance 'inst' | |||
* within container 'c'. | * within container 'c'. | |||
* We need to confirm that the array matches the metadata in 'c' so | * We need to confirm that the array matches the metadata in 'c' so | |||
* that we don't corrupt any metadata. | * that we don't corrupt any metadata. | |||
*/ | */ | |||
static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst) | static int ddf_open_new(struct supertype *c, struct active_array *a, int inst) | |||
{ | { | |||
struct ddf_super *ddf = c->sb; | struct ddf_super *ddf = c->sb; | |||
int n = atoi(inst); | ||||
struct mdinfo *dev; | struct mdinfo *dev; | |||
struct dl *dl; | struct dl *dl; | |||
static const char faulty[] = "faulty"; | static const char faulty[] = "faulty"; | |||
if (all_ff(ddf->virt->entries[n].guid)) { | if (all_ff(ddf->virt->entries[inst].guid)) { | |||
pr_err("subarray %d doesn't exist\n", n); | pr_err("subarray %d doesn't exist\n", inst); | |||
return -ENODEV; | return -ENODEV; | |||
} | } | |||
dprintf("new subarray %d, GUID: %s\n", n, | dprintf("new subarray %d, GUID: %s\n", inst, | |||
guid_str(ddf->virt->entries[n].guid)); | guid_str(ddf->virt->entries[inst].guid)); | |||
for (dev = a->info.devs; dev; dev = dev->next) { | for (dev = a->info.devs; dev; dev = dev->next) { | |||
for (dl = ddf->dlist; dl; dl = dl->next) | for (dl = ddf->dlist; dl; dl = dl->next) | |||
if (dl->major == dev->disk.major && | if (dl->major == dev->disk.major && | |||
dl->minor == dev->disk.minor) | dl->minor == dev->disk.minor) | |||
break; | break; | |||
if (!dl || dl->pdnum < 0) { | if (!dl || dl->pdnum < 0) { | |||
pr_err("device %d/%d of subarray %d not found in meta dat a\n", | pr_err("device %d/%d of subarray %d not found in meta dat a\n", | |||
dev->disk.major, dev->disk.minor, n); | dev->disk.major, dev->disk.minor, inst); | |||
return -1; | return -1; | |||
} | } | |||
if ((be16_to_cpu(ddf->phys->entries[dl->pdnum].state) & | if ((be16_to_cpu(ddf->phys->entries[dl->pdnum].state) & | |||
(DDF_Online|DDF_Missing|DDF_Failed)) != DDF_Online) { | (DDF_Online|DDF_Missing|DDF_Failed)) != DDF_Online) { | |||
pr_err("new subarray %d contains broken device %d/%d (%02 x)\n", | pr_err("new subarray %d contains broken device %d/%d (%02 x)\n", | |||
n, dl->major, dl->minor, | inst, dl->major, dl->minor, | |||
be16_to_cpu(ddf->phys->entries[dl->pdnum].state)); | be16_to_cpu(ddf->phys->entries[dl->pdnum].state)); | |||
if (write(dev->state_fd, faulty, sizeof(faulty)-1) != | if (write(dev->state_fd, faulty, sizeof(faulty)-1) != | |||
sizeof(faulty) - 1) | sizeof(faulty) - 1) | |||
pr_err("Write to state_fd failed\n"); | pr_err("Write to state_fd failed\n"); | |||
dev->curr_state = DS_FAULTY; | dev->curr_state = DS_FAULTY; | |||
} | } | |||
} | } | |||
a->info.container_member = n; | a->info.container_member = inst; | |||
return 0; | return 0; | |||
} | } | |||
static void handle_missing(struct ddf_super *ddf, struct active_array *a, int in st) | static void handle_missing(struct ddf_super *ddf, struct active_array *a, int in st) | |||
{ | { | |||
/* This member array is being activated. If any devices | /* This member array is being activated. If any devices | |||
* are missing they must now be marked as failed. | * are missing they must now be marked as failed. | |||
*/ | */ | |||
struct vd_config *vc; | struct vd_config *vc; | |||
unsigned int n_bvd; | unsigned int n_bvd; | |||
skipping to change at line 4448 | skipping to change at line 4452 | |||
for (i = 0; i < ddf->max_part; i++) | for (i = 0; i < ddf->max_part; i++) | |||
if (dl->vlist[i] != NULL && | if (dl->vlist[i] != NULL && | |||
!memcmp(dl->vlist[i]->conf.guid, guid, | !memcmp(dl->vlist[i]->conf.guid, guid, | |||
DDF_GUID_LEN)) | DDF_GUID_LEN)) | |||
dl->vlist[i] = NULL; | dl->vlist[i] = NULL; | |||
memset(ddf->virt->entries[vdnum].guid, 0xff, DDF_GUID_LEN); | memset(ddf->virt->entries[vdnum].guid, 0xff, DDF_GUID_LEN); | |||
dprintf("deleted %s\n", guid_str(guid)); | dprintf("deleted %s\n", guid_str(guid)); | |||
return 0; | return 0; | |||
} | } | |||
static int kill_subarray_ddf(struct supertype *st) | static int kill_subarray_ddf(struct supertype *st, char *subarray_id) | |||
{ | { | |||
struct ddf_super *ddf = st->sb; | struct ddf_super *ddf = st->sb; | |||
/* | /* | |||
* currentconf is set in container_content_ddf, | * currentconf is set in container_content_ddf, | |||
* called with subarray arg | * called with subarray arg | |||
*/ | */ | |||
struct vcl *victim = ddf->currentconf; | struct vcl *victim = ddf->currentconf; | |||
struct vd_config *conf; | struct vd_config *conf; | |||
unsigned int vdnum; | unsigned int vdnum; | |||
skipping to change at line 4913 | skipping to change at line 4917 | |||
found = xmalloc(n_bvds); | found = xmalloc(n_bvds); | |||
if (found == NULL) | if (found == NULL) | |||
return ret; | return ret; | |||
memset(found, 0, n_bvds); | memset(found, 0, n_bvds); | |||
for (d = info->devs; d; d = d->next) { | for (d = info->devs; d; d = d->next) { | |||
i = d->disk.raid_disk / n_prim; | i = d->disk.raid_disk / n_prim; | |||
if (i >= n_bvds) { | if (i >= n_bvds) { | |||
pr_err("BUG: invalid raid disk\n"); | pr_err("BUG: invalid raid disk\n"); | |||
goto out; | goto out; | |||
} | } | |||
if (d->state_fd > 0) | if (is_fd_valid(d->state_fd)) | |||
found[i]++; | found[i]++; | |||
} | } | |||
ret = 2; | ret = 2; | |||
for (i = 0; i < n_bvds; i++) | for (i = 0; i < n_bvds; i++) | |||
if (!found[i]) { | if (!found[i]) { | |||
dprintf("BVD %d/%d failed\n", i, n_bvds); | dprintf("BVD %d/%d failed\n", i, n_bvds); | |||
ret = 0; | ret = 0; | |||
goto out; | goto out; | |||
} else if (found[i] < n_prim) { | } else if (found[i] < n_prim) { | |||
dprintf("BVD %d/%d degraded\n", i, n_bvds); | dprintf("BVD %d/%d degraded\n", i, n_bvds); | |||
End of changes. 16 change blocks. | ||||
23 lines changed or deleted | 27 lines changed or added |