imsm: Allow to specify controller for --detail-platform.

Usually, 'mdadm --detail-platform -e imsm' scans all the controllers
looking for IMSM capabilities. This patch provides the possibility
to specify a controller to scan, enabling custom usage by other
processes - especially with the --export switch.

$ mdadm --detail-platform
       Platform : Intel(R) Matrix Storage Manager
        Version : 9.5.0.1037
    RAID Levels : raid0 raid1 raid10 raid5
    Chunk Sizes : 4k 8k 16k 32k 64k 128k
    2TB volumes : supported
      2TB disks : not supported
      Max Disks : 7
    Max Volumes : 2 per array, 4 per controller
 I/O Controller : /sys/devices/pci0000:00/0000:00:1f.2 (SATA)

$ mdadm --detail-platform /sys/devices/pci0000:00/0000:00:1f.2
       Platform : Intel(R) Matrix Storage Manager
        Version : 9.5.0.1037
    RAID Levels : raid0 raid1 raid10 raid5
    Chunk Sizes : 4k 8k 16k 32k 64k 128k
    2TB volumes : supported
      2TB disks : not supported
      Max Disks : 7
    Max Volumes : 2 per array, 4 per controller
 I/O Controller : /sys/devices/pci0000:00/0000:00:1f.2 (SATA)

$ mdadm --detail-platform /sys/devices/pci0000:00/0000:00:1f.2 --export
MD_FIRMWARE_TYPE=imsm
IMSM_VERSION=9.5.0.1037
IMSM_SUPPORTED_RAID_LEVELS=raid0 raid1 raid10 raid5
IMSM_SUPPORTED_CHUNK_SIZES=4k 8k 16k 32k 64k 128k
IMSM_2TB_VOLUMES=yes
IMSM_2TB_DISKS=no
IMSM_MAX_DISKS=7
IMSM_MAX_VOLUMES_PER_ARRAY=2
IMSM_MAX_VOLUMES_PER_CONTROLLER=4

$ mdadm --detail-platform /sys/devices/pci0000:00/0000:00:1f.0 # This isn't an IMSM-capable controller
mdadm: no active Intel(R) RAID controller found under /sys/devices/pci0000:00/0000:00:1f.0

Signed-off-by: Maciej Naruszewicz <maciej.naruszewicz@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Handles spaces in array names better.

1/ When printing the "name=" entry for --brief output,
   enclose name in quotes if it contains spaces etc.
   Quotes are already supported for reading mdadm.conf

2/ When a name is used as a device name, translate spaces
   and tabs to '_', as well as the current translation of
   '/' to '-'.

Signed-off-by: NeilBrown <neilb@suse.de>
Allow parse_size to return 0.

We will shortly introduce --data-offset= which is allowed to
be zero.  We will want to use parse_size() so it needs to be
able to return '0' without it being an error.

So define INVALID_SECTORS to be an impossible value (currently '1')
and return and test for it consistently.

Signed-off-by: NeilBrown <neilb@suse.de>
Add data_offset arg to ->avail_size

This is currently only useful for 1.x metadata and will allow an
explicit --data-offset request on command line.

Signed-off-by: NeilBrown <neilb@suse.de>
Add data_offset arg to ->validate_geometry.

This is needed to return correct available size.  It isn't
really used yet.

Signed-off-by: NeilBrown <neilb@suse.de>
Add data_offset arg to ->init_super and use it in super1.c

So if ->data_offset is already set, use that rather than
computing one.

Signed-off-by: NeilBrown <neilb@suse.de>
Add --data-offset flag for Create and Grow

This can be used to over-ride the automatic assignment of
data offset.
For --create, it is useful to re-create old arrays where different
   defaults applied.
For --grow it may be able to force a reshape in the reverse direction.

Signed-off-by: NeilBrown <neilb@suse.de>
super1: add new_offset field.

The 'new_offset' is used for reshaping to avoid the need
for a backup file.

For now we only report the value when it is set.

Signed-off-by: NeilBrown <neilb@suse.de>
Add space_before/space_after fields to mdinfo

These will be needed to guide changes to data_offset during reshape.
Only set them for super1 for now.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow: set new_data_offset if appropriate
Split 'GCD' out into a separate function.

It is neater that way.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow: add raid10 reshape.

RAID10 reshape requires that data_offset be changed.
So we only allow it if the new_data_offset attribute is available,
and we compute a suitable change in data offset.

Signed-off-by: NeilBrown <neilb@suse.de>
New RESHAPE_NO_BACKUP flag to track when backup action is needed.

Some arrays (raid10) never need a backup file, so during assembly
we can avoid the whole Grow_continue check in that case.
Achieve this using a flag set by the metadata handler.

Also get "mdadm -I" to fail if a backup process would be
needed.  It currently does fail as the kernel rejects things,
but it is nicer to have this explicit.

Signed-off-by: NeilBrown <neilb@suse.de>
super1: reserve  at least 2 chunks for reshape headroom.

sometimes 0.1% isn't enough, though mostly only in testing.

We need one chunk for a successful reshape, so reserve 2.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow/raid10: support reducing the devices in a RAID10.

When reducing the number of devices in a RAID10, we increase the
data offset to avoid the need for backup area.

If there is no room at the end of the device to allow this, we need
to first reduce the component size of each device.  However if there
is room, we don't want to insist on that, otherwise growing then
shrinking the array would not be idempotent.

So find the min before/after space before analysing a RAID10 for
reshape, and if the after space is insufficient, reduce the total size
of the array and the component size accordingly.

Signed-off-by: NeilBrown <neilb@suse.de>
Allow data-offset to be specified per-device for create

 mdadm --create /dev/md0 .... /dev/sda1:1024 /dev/sdb1:2048 ...

The size is in K unless a suffix: K M G is given.
The suffix 's' means sectors.

Signed-off-by: NeilBrown <neilb@suse.de>
imsm: allow --assume-clean to work.

We must avoid setting IMSM_T_STATE_UNINITIALIZED if the
array was declared to be clean due to --assume-clean.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow: allow --grow --continue to work for native metadata.

As it was the code would crash due to "mdstat" being NULL.
Code is now more sane, but hasn't been tested on an array that
needs to grow.

Signed-off-by: NeilBrown <neilb@suse.de>
Fix up interactions between --assemble and --incremental

If --incremental has partly assembled an array and
--assemble is asked to assemble it, the just finds remaining
devices and makes a new array.  Not good.

So:
1/ modify locking policy so that assemble can be sure that
  no --incremental is running once it locks the map file
2/ Assemble() checks the map file for a duplicate and adds to
   that array instead of creating a new one.

Signed-off-by: NeilBrown <neilb@suse.de>
Replace a lot of leading spaces with tabs.

Signed-off-by: NeilBrown <neilb@suse.de>