/*
 * Linux Software RAID (md) topology
 * -- this is fallback for old systems where the toplogy information are not
 *    exporte dy sysfs
 *
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 *
 */
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "topology.h"

#ifndef MD_MAJOR
#define MD_MAJOR	9
#endif

#define GET_ARRAY_INFO          _IOR (MD_MAJOR, 0x11, struct md_array_info)

struct md_array_info {
	/*
	 * Generic constant information
	 */
	uint32_t major_version;
	uint32_t minor_version;
	uint32_t patch_version;
	uint32_t ctime;
	uint32_t level;
	uint32_t size;
	uint32_t nr_disks;
	uint32_t raid_disks;
	uint32_t md_minor;
	uint32_t not_persistent;

	/*
	 * Generic state information
	 */
	uint32_t utime;	  /*  0 Superblock update time		  */
	uint32_t state;	  /*  1 State bits (clean, ...)		  */
	uint32_t active_disks;  /*  2 Number of currently active disks  */
	uint32_t working_disks; /*  3 Number of working disks		  */
	uint32_t failed_disks;  /*  4 Number of failed disks		  */
	uint32_t spare_disks;	  /*  5 Number of spare disks		  */

	/*
	 * Personality information
	 */
	uint32_t layout;	  /*  0 the array's physical layout	  */
	uint32_t chunk_size;	  /*  1 chunk size in bytes		  */

};

static int is_md_device(dev_t devno)
{
	if (major(devno) == MD_MAJOR)
		return 1;
	return blkid_driver_has_major("md", major(devno));
}

static int probe_md_tp(blkid_probe pr, const struct blkid_idmag *mag)
{
	int fd = -1;
	dev_t disk = 0;
	dev_t devno = blkid_probe_get_devno(pr);
	struct md_array_info md;

	if (!devno)
		goto nothing;		/* probably not a block device */

	if (!is_md_device(devno))
		goto nothing;

	if (blkid_devno_to_wholedisk(devno, NULL, 0, &disk))
		goto nothing;

	if (disk == devno)
		fd = pr->fd;
	else {
		char *diskpath = blkid_devno_to_devname(disk);

		if (!diskpath)
			goto nothing;

		fd = open(diskpath, O_RDONLY);
		free(diskpath);

                if (fd == -1)
			goto nothing;
	}

	memset(&md, 0, sizeof(md));

	if (ioctl(fd, GET_ARRAY_INFO, &md))
		goto nothing;

	if (fd != pr->fd)
		close(fd);

	/*
	 * Ignore levels we don't want aligned (e.g. linear)
	 * and deduct disk(s) from stripe width on RAID4/5/6
	 */
	switch (md.level) {
	case 6:
		md.raid_disks--;
		/* fallthrough */
	case 5:
	case 4:
		md.raid_disks--;
		/* fallthrough */
	case 1:
	case 0:
	case 10:
		break;
	default:
		goto nothing;
	}

	blkid_topology_set_minimum_io_size(pr, md.chunk_size);
	blkid_topology_set_optimal_io_size(pr, md.chunk_size * md.raid_disks);

	return 0;

nothing:
	if (fd != -1 && fd != pr->fd)
		close(fd);
	return 1;
}

const struct blkid_idinfo md_tp_idinfo =
{
	.name		= "md",
	.probefunc	= probe_md_tp,
	.magics		= BLKID_NONE_MAGIC
};

