Skip to content

Commit

Permalink
[PATCH] md: allow array level to be set textually via sysfs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Jan 6, 2006
1 parent 8bb93aa commit d9d166c
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 14 deletions.
8 changes: 8 additions & 0 deletions Documentation/md.txt
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ All md devices contain:
1.2 (newer format in varying locations) or "none" indicating that
the kernel isn't managing metadata at all.

level
The raid 'level' for this array. The name will often (but not
always) be the same as the name of the module that implements the
level. To be auto-loaded the module must have an alias
md-$LEVEL e.g. md-raid5
This can be written only while the array is being assembled, not
after it is started.

As component devices are added to an md array, they appear in the 'md'
directory as new directories named
dev-XXX
Expand Down
1 change: 1 addition & 0 deletions drivers/md/faulty.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,5 @@ module_init(raid_init);
module_exit(raid_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-10"); /* faulty */
MODULE_ALIAS("md-faulty");
MODULE_ALIAS("md-level--5");
3 changes: 2 additions & 1 deletion drivers/md/linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,5 +376,6 @@ static void linear_exit (void)
module_init(linear_init);
module_exit(linear_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-1"); /* LINEAR - degrecated*/
MODULE_ALIAS("md-personality-1"); /* LINEAR - deprecated*/
MODULE_ALIAS("md-linear");
MODULE_ALIAS("md-level--1");
61 changes: 48 additions & 13 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,15 @@ static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev)
return NULL;
}

static struct mdk_personality *find_pers(int level)
static struct mdk_personality *find_pers(int level, char *clevel)
{
struct mdk_personality *pers;
list_for_each_entry(pers, &pers_list, list)
if (pers->level == level)
list_for_each_entry(pers, &pers_list, list) {
if (level != LEVEL_NONE && pers->level == level)
return pers;
if (strcmp(pers->name, clevel)==0)
return pers;
}
return NULL;
}

Expand Down Expand Up @@ -715,6 +718,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->ctime = sb->ctime;
mddev->utime = sb->utime;
mddev->level = sb->level;
mddev->clevel[0] = 0;
mddev->layout = sb->layout;
mddev->raid_disks = sb->raid_disks;
mddev->size = sb->size;
Expand Down Expand Up @@ -1051,6 +1055,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1);
mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1);
mddev->level = le32_to_cpu(sb->level);
mddev->clevel[0] = 0;
mddev->layout = le32_to_cpu(sb->layout);
mddev->raid_disks = le32_to_cpu(sb->raid_disks);
mddev->size = le64_to_cpu(sb->size)/2;
Expand Down Expand Up @@ -1774,15 +1779,36 @@ static ssize_t
level_show(mddev_t *mddev, char *page)
{
struct mdk_personality *p = mddev->pers;
if (p == NULL && mddev->raid_disks == 0)
return 0;
if (mddev->level >= 0)
return sprintf(page, "raid%d\n", mddev->level);
else
if (p)
return sprintf(page, "%s\n", p->name);
else if (mddev->clevel[0])
return sprintf(page, "%s\n", mddev->clevel);
else if (mddev->level != LEVEL_NONE)
return sprintf(page, "%d\n", mddev->level);
else
return 0;
}

static ssize_t
level_store(mddev_t *mddev, const char *buf, size_t len)
{
int rv = len;
if (mddev->pers)
return -EBUSY;
if (len == 0)
return 0;
if (len >= sizeof(mddev->clevel))
return -ENOSPC;
strncpy(mddev->clevel, buf, len);
if (mddev->clevel[len-1] == '\n')
len--;
mddev->clevel[len] = 0;
mddev->level = LEVEL_NONE;
return rv;
}

static struct md_sysfs_entry md_level = __ATTR_RO(level);
static struct md_sysfs_entry md_level =
__ATTR(level, 0644, level_show, level_store);

static ssize_t
raid_disks_show(mddev_t *mddev, char *page)
Expand Down Expand Up @@ -2158,7 +2184,10 @@ static int do_md_run(mddev_t * mddev)
}

#ifdef CONFIG_KMOD
request_module("md-level-%d", mddev->level);
if (mddev->level != LEVEL_NONE)
request_module("md-level-%d", mddev->level);
else if (mddev->clevel[0])
request_module("md-%s", mddev->clevel);
#endif

/*
Expand All @@ -2180,15 +2209,21 @@ static int do_md_run(mddev_t * mddev)
return -ENOMEM;

spin_lock(&pers_lock);
pers = find_pers(mddev->level);
pers = find_pers(mddev->level, mddev->clevel);
if (!pers || !try_module_get(pers->owner)) {
spin_unlock(&pers_lock);
printk(KERN_WARNING "md: personality for level %d is not loaded!\n",
mddev->level);
if (mddev->level != LEVEL_NONE)
printk(KERN_WARNING "md: personality for level %d is not loaded!\n",
mddev->level);
else
printk(KERN_WARNING "md: personality for level %s is not loaded!\n",
mddev->clevel);
return -EINVAL;
}
mddev->pers = pers;
spin_unlock(&pers_lock);
mddev->level = pers->level;
strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));

mddev->recovery = 0;
mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
Expand Down
1 change: 1 addition & 0 deletions drivers/md/multipath.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,4 +578,5 @@ module_init(multipath_init);
module_exit(multipath_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-7"); /* MULTIPATH */
MODULE_ALIAS("md-multipath");
MODULE_ALIAS("md-level--4");
1 change: 1 addition & 0 deletions drivers/md/raid0.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,4 +536,5 @@ module_init(raid0_init);
module_exit(raid0_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-2"); /* RAID0 */
MODULE_ALIAS("md-raid0");
MODULE_ALIAS("md-level-0");
1 change: 1 addition & 0 deletions drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -2092,4 +2092,5 @@ module_init(raid_init);
module_exit(raid_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-3"); /* RAID1 */
MODULE_ALIAS("md-raid1");
MODULE_ALIAS("md-level-1");
1 change: 1 addition & 0 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -2117,4 +2117,5 @@ module_init(raid_init);
module_exit(raid_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-9"); /* RAID10 */
MODULE_ALIAS("md-raid10");
MODULE_ALIAS("md-level-10");
2 changes: 2 additions & 0 deletions drivers/md/raid5.c
Original file line number Diff line number Diff line change
Expand Up @@ -2240,5 +2240,7 @@ module_init(raid5_init);
module_exit(raid5_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-4"); /* RAID5 */
MODULE_ALIAS("md-raid5");
MODULE_ALIAS("md-raid4");
MODULE_ALIAS("md-level-5");
MODULE_ALIAS("md-level-4");
1 change: 1 addition & 0 deletions drivers/md/raid6main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2341,4 +2341,5 @@ module_init(raid6_init);
module_exit(raid6_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS("md-personality-8"); /* RAID6 */
MODULE_ALIAS("md-raid6");
MODULE_ALIAS("md-level-6");
1 change: 1 addition & 0 deletions include/linux/raid/md_k.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct mddev_s
int chunk_size;
time_t ctime, utime;
int level, layout;
char clevel[16];
int raid_disks;
int max_disks;
sector_t size; /* used size of component devices */
Expand Down

0 comments on commit d9d166c

Please sign in to comment.