From 4a3ca8acc378a56e9a2b9017a9fcc7cfa6aee0f9 Mon Sep 17 00:00:00 2001 From: "mwilck@arcor.de" Date: Wed, 3 Jul 2013 22:27:58 +0200 Subject: [PATCH] DDF: add_to_super_ddf: allow empty slots in phys disk table The used slots in the phys disk table aren't necessarily the first ones. Rather, unused entries are represented by entries where the GUID is all 0xff. Signed-off-by: Martin Wilck Signed-off-by: NeilBrown --- super-ddf.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/super-ddf.c b/super-ddf.c index 617f83f..028229f 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -2245,6 +2245,8 @@ static int init_super_ddf(struct supertype *st, pd->used_pdes = __cpu_to_be16(0); pd->max_pdes = __cpu_to_be16(max_phys_disks); memset(pd->pad, 0xff, 52); + for (i = 0; i < max_phys_disks; i++) + memset(pd->entries[i].guid, 0xff, DDF_GUID_LEN); if (posix_memalign((void**)&vd, 512, vdsize) != 0) { pr_err("%s could not allocate vd\n", __func__); @@ -2541,6 +2543,16 @@ static void add_to_super_ddf_bvd(struct supertype *st, ddf_set_updates_pending(ddf); } +static unsigned int find_unused_pde(const struct ddf_super *ddf) +{ + unsigned int i; + for (i = 0; i < __be16_to_cpu(ddf->phys->max_pdes); i++) { + if (all_ff(ddf->phys->entries[i].guid)) + return i; + } + return DDF_NOTFOUND; +} + /* add a device to a container, either while creating it or while * expanding a pre-existing container */ @@ -2567,6 +2579,14 @@ static int add_to_super_ddf(struct supertype *st, * a phys_disk entry and a more detailed disk_data entry. */ fstat(fd, &stb); + n = find_unused_pde(ddf); + if (n == DDF_NOTFOUND) { + pr_err("%s: No free slot in array, cannot add disk\n", + __func__); + return 1; + } + pde = &ddf->phys->entries[n]; + if (posix_memalign((void**)&dd, 512, sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part) != 0) { pr_err("%s could allocate buffer for new disk, aborting\n", @@ -2605,8 +2625,6 @@ static int add_to_super_ddf(struct supertype *st, for (i = 0; i < ddf->max_part ; i++) dd->vlist[i] = NULL; - n = __be16_to_cpu(ddf->phys->used_pdes); - pde = &ddf->phys->entries[n]; dd->pdnum = n; if (st->update_tail) { @@ -2619,10 +2637,9 @@ static int add_to_super_ddf(struct supertype *st, pd->used_pdes = __cpu_to_be16(n); pde = &pd->entries[0]; dd->mdupdate = pd; - } else { - n++; - ddf->phys->used_pdes = __cpu_to_be16(n); - } + } else + ddf->phys->used_pdes = __cpu_to_be16( + 1 + __be16_to_cpu(ddf->phys->used_pdes)); memcpy(pde->guid, dd->disk.guid, DDF_GUID_LEN); pde->refnum = dd->disk.refnum;