Browse Source

[PATCH] md: expose md metadata format in sysfs

Allow it to be set to a particular version, or 'none'.

Signed-off-by: Neil Brown <neilb@suse.de>
Acked-by: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
NeilBrown 20 years ago
parent
commit
8bb93aaca2
2 changed files with 55 additions and 0 deletions
  1. 6 0
      Documentation/md.txt
  2. 49 0
      drivers/md/md.c

+ 6 - 0
Documentation/md.txt

@@ -183,6 +183,12 @@ All md devices contain:
      the array if the personality supports it (raid1, raid5, raid6),
      the array if the personality supports it (raid1, raid5, raid6),
      and if the component drives are large enough.
      and if the component drives are large enough.
 
 
+  metadata_version
+     This indicates the format that is being used to record metadata
+     about the array.  It can be 0.90 (traditional format), 1.0, 1.1,
+     1.2 (newer format in varying locations) or "none" indicating that
+     the kernel isn't managing metadata at all.
+
 As component devices are added to an md array, they appear in the 'md'
 As component devices are added to an md array, they appear in the 'md'
 directory as new directories named
 directory as new directories named
       dev-XXX
       dev-XXX

+ 49 - 0
drivers/md/md.c

@@ -1857,6 +1857,54 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
 static struct md_sysfs_entry md_size =
 static struct md_sysfs_entry md_size =
 __ATTR(component_size, 0644, size_show, size_store);
 __ATTR(component_size, 0644, size_show, size_store);
 
 
+
+/* Metdata version.
+ * This is either 'none' for arrays with externally managed metadata,
+ * or N.M for internally known formats
+ */
+static ssize_t
+metadata_show(mddev_t *mddev, char *page)
+{
+	if (mddev->persistent)
+		return sprintf(page, "%d.%d\n",
+			       mddev->major_version, mddev->minor_version);
+	else
+		return sprintf(page, "none\n");
+}
+
+static ssize_t
+metadata_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	int major, minor;
+	char *e;
+	if (!list_empty(&mddev->disks))
+		return -EBUSY;
+
+	if (cmd_match(buf, "none")) {
+		mddev->persistent = 0;
+		mddev->major_version = 0;
+		mddev->minor_version = 90;
+		return len;
+	}
+	major = simple_strtoul(buf, &e, 10);
+	if (e==buf || *e != '.')
+		return -EINVAL;
+	buf = e+1;
+	minor = simple_strtoul(buf, &e, 10);
+	if (e==buf || *e != '\n')
+		return -EINVAL;
+	if (major >= sizeof(super_types)/sizeof(super_types[0]) ||
+	    super_types[major].name == NULL)
+		return -ENOENT;
+	mddev->major_version = major;
+	mddev->minor_version = minor;
+	mddev->persistent = 1;
+	return len;
+}
+
+static struct md_sysfs_entry md_metadata =
+__ATTR(metadata_version, 0644, metadata_show, metadata_store);
+
 static ssize_t
 static ssize_t
 action_show(mddev_t *mddev, char *page)
 action_show(mddev_t *mddev, char *page)
 {
 {
@@ -1926,6 +1974,7 @@ static struct attribute *md_default_attrs[] = {
 	&md_raid_disks.attr,
 	&md_raid_disks.attr,
 	&md_chunk_size.attr,
 	&md_chunk_size.attr,
 	&md_size.attr,
 	&md_size.attr,
+	&md_metadata.attr,
 	NULL,
 	NULL,
 };
 };