From 2f593593b2abd38e4cd95c64ade33f3e9e91ffdc Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Tue, 17 May 2011 22:00:06 +0200 Subject: [PATCH 28/84] lsbd: add support for bootup autodetection This patch adds LSBD autodetection during startup - like Linux Software RAID. The partition must have 0xfa type. --- drivers/block/lsbd.c | 43 ++++++++++++++++++++++++++++++++++++++++++- fs/partitions/msdos.c | 15 +++++++++++++++ include/linux/genhd.h | 1 + init/main.c | 8 ++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/drivers/block/lsbd.c b/drivers/block/lsbd.c index 57de7fe..e0f091e 100644 --- a/drivers/block/lsbd.c +++ b/drivers/block/lsbd.c @@ -2089,6 +2089,7 @@ int __init lsbd_init_module(void) { unsigned int i; + printk(KERN_NOTICE "lsbd: initializing module\n"); for (i = 0; i < LSBD_MAX; i++) { struct lsbd *p = &lsbd_dev[i]; unsigned int j; @@ -2170,7 +2171,47 @@ void lsbd_cleanup_module(void) printk(KERN_WARNING "lsbd: cannot unregister blkdev\n"); } -#if MODULE +#ifndef MODULE + +/* + * Searches all registered partitions for autorun LSBD at boot time. + */ +static kdev_t detected_devices[128]; +static int dev_cnt; + +void lsbd_autodetect_dev(kdev_t dev) +{ + if (dev_cnt >= 0 && dev_cnt < 127) + detected_devices[dev_cnt++] = dev; +} + +void lsbd_autodetect(void) +{ + struct lsbd *p; + unsigned int i, j; + kdev_t dev; + + printk(KERN_INFO "lsbd: autodetecting LSBD devices...\n"); + for (j = 0; j < dev_cnt; j++) { + dev = detected_devices[j]; + for (i = 0; i < LSBD_MAX; i++) { + p = &lsbd_dev[i]; + + if (!down_interruptible(&p->mutex)) { + if (p->tsk == NULL) { + lsbd_set_dev(p, MAJOR(dev), MINOR(dev)); + return; + } + up(&p->mutex); + } + } + } +} + +__initcall(lsbd_init_module); + +#else + module_init(lsbd_init_module); module_exit(lsbd_cleanup_module); diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 1ef6a8f..0b61d3f 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -45,6 +45,9 @@ EXPORT_SYMBOL(ide_xlate_1024_hook); #if CONFIG_BLK_DEV_MD extern void md_autodetect_dev(kdev_t dev); #endif +#if CONFIG_BLK_DEV_LSBD +extern void lsbd_autodetect_dev(kdev_t dev); +#endif /* * Many architectures don't like unaligned accesses, which is @@ -175,6 +178,12 @@ static void extended_partition(struct gendisk *hd, struct block_device *bdev, md_autodetect_dev(MKDEV(hd->major,*current_minor)); } #endif +#if CONFIG_BLK_DEV_LSBD + if (SYS_IND(p) == LINUX_LSBD_PARTITION) { + lsbd_autodetect_dev(MKDEV(hd->major, + *current_minor)); + } +#endif (*current_minor)++; loopct = 0; @@ -605,6 +614,12 @@ int msdos_partition(struct gendisk *hd, struct block_device *bdev, md_autodetect_dev(MKDEV(hd->major,minor)); } #endif +#if CONFIG_BLK_DEV_LSBD + if (SYS_IND(p) == LINUX_LSBD_PARTITION) { + lsbd_autodetect_dev(MKDEV(hd->major, + minor)); + } +#endif if (is_extended_partition(p)) { unsigned long size = hd->part[minor].nr_sects; printk(" <"); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 40ab37d..7115846 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -21,6 +21,7 @@ enum { WIN98_EXTENDED_PARTITION = 0x0f, LINUX_SWAP_PARTITION = 0x82, + LINUX_LSBD_PARTITION = 0xfa, /* autodetect LSBD partition */ LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */ SOLARIS_X86_PARTITION = LINUX_SWAP_PARTITION, diff --git a/init/main.c b/init/main.c index a1d0841..68bf6ef 100644 --- a/init/main.c +++ b/init/main.c @@ -559,6 +559,10 @@ static void run_init_process(char *init_filename) extern void prepare_namespace(void); +#if CONFIG_BLK_DEV_LSBD +extern void lsbd_autodetect(void); +#endif + static int init(void * unused) { struct files_struct *files; @@ -567,6 +571,10 @@ static int init(void * unused) prepare_namespace(); +#if CONFIG_BLK_DEV_LSBD + lsbd_autodetect(); +#endif + /* * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the -- 1.8.4.652.g0d6e0ce