diff options
-rw-r--r-- | Documentation/md.txt | 6 | ||||
-rw-r--r-- | drivers/md/md.c | 49 |
2 files changed, 55 insertions, 0 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt index 0a2e10a4040d..c5512afd5917 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt | |||
@@ -183,6 +183,12 @@ All md devices contain: | |||
183 | the array if the personality supports it (raid1, raid5, raid6), | 183 | the array if the personality supports it (raid1, raid5, raid6), |
184 | and if the component drives are large enough. | 184 | and if the component drives are large enough. |
185 | 185 | ||
186 | metadata_version | ||
187 | This indicates the format that is being used to record metadata | ||
188 | about the array. It can be 0.90 (traditional format), 1.0, 1.1, | ||
189 | 1.2 (newer format in varying locations) or "none" indicating that | ||
190 | the kernel isn't managing metadata at all. | ||
191 | |||
186 | As component devices are added to an md array, they appear in the 'md' | 192 | As component devices are added to an md array, they appear in the 'md' |
187 | directory as new directories named | 193 | directory as new directories named |
188 | dev-XXX | 194 | dev-XXX |
diff --git a/drivers/md/md.c b/drivers/md/md.c index d568ab4a487f..ecc0166ba779 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1857,6 +1857,54 @@ size_store(mddev_t *mddev, const char *buf, size_t len) | |||
1857 | static struct md_sysfs_entry md_size = | 1857 | static struct md_sysfs_entry md_size = |
1858 | __ATTR(component_size, 0644, size_show, size_store); | 1858 | __ATTR(component_size, 0644, size_show, size_store); |
1859 | 1859 | ||
1860 | |||
1861 | /* Metdata version. | ||
1862 | * This is either 'none' for arrays with externally managed metadata, | ||
1863 | * or N.M for internally known formats | ||
1864 | */ | ||
1865 | static ssize_t | ||
1866 | metadata_show(mddev_t *mddev, char *page) | ||
1867 | { | ||
1868 | if (mddev->persistent) | ||
1869 | return sprintf(page, "%d.%d\n", | ||
1870 | mddev->major_version, mddev->minor_version); | ||
1871 | else | ||
1872 | return sprintf(page, "none\n"); | ||
1873 | } | ||
1874 | |||
1875 | static ssize_t | ||
1876 | metadata_store(mddev_t *mddev, const char *buf, size_t len) | ||
1877 | { | ||
1878 | int major, minor; | ||
1879 | char *e; | ||
1880 | if (!list_empty(&mddev->disks)) | ||
1881 | return -EBUSY; | ||
1882 | |||
1883 | if (cmd_match(buf, "none")) { | ||
1884 | mddev->persistent = 0; | ||
1885 | mddev->major_version = 0; | ||
1886 | mddev->minor_version = 90; | ||
1887 | return len; | ||
1888 | } | ||
1889 | major = simple_strtoul(buf, &e, 10); | ||
1890 | if (e==buf || *e != '.') | ||
1891 | return -EINVAL; | ||
1892 | buf = e+1; | ||
1893 | minor = simple_strtoul(buf, &e, 10); | ||
1894 | if (e==buf || *e != '\n') | ||
1895 | return -EINVAL; | ||
1896 | if (major >= sizeof(super_types)/sizeof(super_types[0]) || | ||
1897 | super_types[major].name == NULL) | ||
1898 | return -ENOENT; | ||
1899 | mddev->major_version = major; | ||
1900 | mddev->minor_version = minor; | ||
1901 | mddev->persistent = 1; | ||
1902 | return len; | ||
1903 | } | ||
1904 | |||
1905 | static struct md_sysfs_entry md_metadata = | ||
1906 | __ATTR(metadata_version, 0644, metadata_show, metadata_store); | ||
1907 | |||
1860 | static ssize_t | 1908 | static ssize_t |
1861 | action_show(mddev_t *mddev, char *page) | 1909 | action_show(mddev_t *mddev, char *page) |
1862 | { | 1910 | { |
@@ -1926,6 +1974,7 @@ static struct attribute *md_default_attrs[] = { | |||
1926 | &md_raid_disks.attr, | 1974 | &md_raid_disks.attr, |
1927 | &md_chunk_size.attr, | 1975 | &md_chunk_size.attr, |
1928 | &md_size.attr, | 1976 | &md_size.attr, |
1977 | &md_metadata.attr, | ||
1929 | NULL, | 1978 | NULL, |
1930 | }; | 1979 | }; |
1931 | 1980 | ||