Re: md in 1.99.14

Marc ZYNGIER (maz@gloups.fdn.fr)
Sun, 9 Jun 96 22:34 MET DST


Well, swapon hangs because it is not prepared to see a 0 block device!
The md device should be up and running before swap being
activated. Anyway, I've made a patch for this situation to be handled
much more gracefully (see below). It also corrects minor things in
errors handling (whole stuff sent to Linus...).

To summarize :
- IF md personalities are hardwired in the kernel, you do not need
anything more than "/sbin/mdadd -ar" as the first line of your
/etc/rc. Final point. No /proc, no kerneld, no nothing... ;-)

- IF your md personalities are loaded as modules you need to insmod
them by hand (or have kerneld running) BEFORE doing anything that
tries to access any md device. In your particular case, just before
"swapon -a".

Stay tuned !

Marc.

PS: I've uploaded to sweet-smoke md035.tar.gz (nothing more than 034,
just those f***ing raid1 defines blasted out... ;-).
PS2: Patch is against 1.99.14

diff -ru --new-file /usr/src/linux/drivers/block/README.md linux/drivers/block/README.md
--- /usr/src/linux/drivers/block/README.md Fri Jun 7 23:02:50 1996
+++ linux/drivers/block/README.md Sun Jun 9 22:11:01 1996
@@ -1,4 +1,4 @@
Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr
-in public/Linux/md034.tar.gz.
+in public/Linux/md035.tar.gz.

Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
diff -ru --new-file /usr/src/linux/drivers/block/md.c linux/drivers/block/md.c
--- /usr/src/linux/drivers/block/md.c Sat Jun 8 09:16:57 1996
+++ linux/drivers/block/md.c Sun Jun 9 18:29:41 1996
@@ -218,6 +218,7 @@
clear_inode (md_dev[minor].devices[i].inode);

md_dev[minor].nb_dev=md_size[minor]=0;
+ md_hd_struct[minor].nr_sects=0;
md_dev[minor].pers=NULL;

set_ra (); /* calculate new read_ahead */
@@ -259,12 +260,7 @@
md_dev[minor].devices[i].size=gen_real->sizes[MINOR(dev)];
md_dev[minor].devices[i].offset=i ?
(md_dev[minor].devices[i-1].offset + md_dev[minor].devices[i-1].size) : 0;
-
- if (!i)
- md_size[minor]=0;
-
- md_size[minor]+=md_dev[minor].devices[i].size;
-
+
printk ("REGISTER_DEV %s to md%x done\n", partition_name(dev), minor);
return (0);
}
@@ -372,11 +368,33 @@
}


+static int md_read (struct inode *inode, struct file *file,
+ char *buf, int count)
+{
+ int minor=MINOR(inode->i_rdev);
+
+ if (!md_dev[minor].pers) /* Check if device is being run */
+ return -ENXIO;
+
+ return block_read (inode, file, buf, count);
+}
+
+static int md_write (struct inode *inode, struct file *file,
+ const char *buf, int count)
+{
+ int minor=MINOR(inode->i_rdev);
+
+ if (!md_dev[minor].pers) /* Check if device is being run */
+ return -ENXIO;
+
+ return block_write (inode, file, buf, count);
+}
+
static struct file_operations md_fops=
{
NULL,
- block_read,
- block_write,
+ md_read,
+ md_write,
NULL,
NULL,
md_ioctl,
@@ -431,6 +449,7 @@
{
md_blocksizes[i] = 1024;
md_gendisk.part[i].start_sect=-1; /* avoid partition check */
+ md_gendisk.part[i].nr_sects=0;
md_dev[i].pers=NULL;
}

@@ -448,7 +467,7 @@

int get_md_status (char *page)
{
- int sz=0, i, j;
+ int sz=0, i, j, size;

sz+=sprintf( page+sz, "Personalities : ");
for (i=0; i<MAX_PERSONALITY; i++)
@@ -470,12 +489,16 @@
if (md_dev[i].pers)
sz+=sprintf (page+sz, " %s", md_dev[i].pers->name);

+ size=0;
for (j=0; j<md_dev[i].nb_dev; j++)
+ {
sz+=sprintf (page+sz, " %s",
partition_name(md_dev[i].devices[j].dev));
+ size+=md_dev[i].devices[j].size;
+ }

if (md_dev[i].nb_dev)
- sz+=sprintf (page+sz, " %d blocks", md_size[i]);
+ sz+=sprintf (page+sz, " %d blocks", size);

if (!md_dev[i].pers)
{
diff -ru --new-file /usr/src/linux/mm/swapfile.c linux/mm/swapfile.c
--- /usr/src/linux/mm/swapfile.c Sat Jun 8 09:19:04 1996
+++ linux/mm/swapfile.c Sun Jun 9 15:33:57 1996
@@ -16,6 +16,7 @@
#include <linux/swap.h>
#include <linux/fs.h>
#include <linux/swapctl.h>
+#include <linux/blkdev.h> /* for blk_size */

#include <asm/dma.h>
#include <asm/system.h> /* for cli()/sti() */
@@ -457,7 +458,9 @@
if(error)
goto bad_swap_2;
error = -ENODEV;
- if (!p->swap_device)
+ if (!p->swap_device ||
+ (blk_size[MAJOR(p->swap_device)] &&
+ !blk_size[MAJOR(p->swap_device)][MINOR(p->swap_device)]))
goto bad_swap;
error = -EBUSY;
for (i = 0 ; i < nr_swapfiles ; i++) {

-- 
Every day sends future to past,            | Marc ZYNGIER <maz@gloups.fdn.fr>
Every breath leaves me one less to my last |     <zyngier@ufr-info-p7.ibp.fr>