Subject: Problems creating ext2fs on ICS partition

From: Mark Seaborn <[email-masked]>
Date: Wed, 7 Apr 1999 20:15:08 +0100 (BST)

I'm having trouble creating an ext2 filesystem on a hard disc partitioned
with the ICS scheme.  When I run mke2fs on the partition without any extra
arguments, I get:

  [root@localhost /root]# mke2fs /dev/hde7
  mke2fs 1.04, 16-May-96 for EXT2 FS 0.5b, 95/08/09
  /dev/hde7: Out of memory while setting up superblock

I've also grabbed a later copy of the ext2fs utils and compiled that.  (I
can compile stuff on this ARM Linux box because I've got another hard disc
attached, partitioned under the DOS BIOS scheme, but I want to be able to
connect a CD-ROM instead of this disc.) That gives the same error:

  [root@localhost /root]# mke2fs ./sw/e2fsprogs-1.12/misc/mke2fs /dev/hde7
  mke2fs 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
  /dev/hde7: Memory allocation failed while setting up superblock

Now, the /dev/hde* files are set correctly because I can mount the Filecore
partitions on /dev/hde[1-5].  Linux recognises the partitions correctly as
being there on boot.  And if I run fdisk on it (arm-fdisk-3.0 from the ftp
site), it seems to list the partitions correctly:

  [root@localhost /root]# ./sw/arm-fdisk-3.0/fdisk /dev/hde
  
  Device /dev/hde is partitioned using ICSIDEFS scheme
  
  Command (m for help): p
  
  Disk /dev/hde: 15 heads, 63 sectors, 13328 cylinders
  Units = cylinders of 945 * 512 bytes
  
     Device Boot   Begin    Start      End   Blocks    Id  System
  /dev/hde1            0        1     2059   972800   100  Filecore
  /dev/hde2         2059     2059     4118   972800   100  Filecore
  /dev/hde3         4118     4118     6827  1280000   100  Filecore
  /dev/hde4         6827     6827     9536  1280000   100  Filecore
  /dev/hde5         9536     9536    10513   461704   100  Filecore
  /dev/hde0        10513    10513    10513        0+  101  Linux Table
  /dev/hde6        10513    10513    10572    27695+   82  Linux Swap
  /dev/hde0        10572    10572    10572        0+  101  Linux Table
  /dev/hde7        10572    10572    13328  1302478+   83  Linux Native

(Not sure what those /dev/hde0 things are, though.)

However, if I do `cat /dev/hde7', it returns without printing anything. 
Catting `/dev/hde[1-5]' prints junk, as you would expect.  Does this mean
Linux isn't reading the size of hde7 correctly?  This would seem to be the
case when I run mkswap on hde6:

  [root@localhost /root]# mkswap /dev/hde6
  Page size: 4kB
  mkswap: error: swap area needs to be at least 40kB
  Usage: mkswap [-c] /dev/name [blocks]

If I give mkswap the number of blocks given by fdisk, it works.

Looking at the source of mke2fs, and adding a few test messages, it seems
that it's reading the size of the partition wrongly (it thinks its
negative), and tries to allocate such a large block of memory it fails. 
Giving it a number of blocks gives this (the older version of mke2fs gives
an incomprehensible error code):

  [root@localhost /root]# ./sw/e2fsprogs-1.12/misc/mke2fs /dev/hde7 1000
  mke2fs 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
  Linux ext2 filesystem format
  Filesystem label=
  256 inodes, 1000 blocks
  50 blocks (5.00%) reserved for the super user
  First data block=1
  Block size=1024 (log=0)
  Fragment size=1024 (log=0)
  1 block group
  8192 blocks per group, 8192 fragments per group
  256 inodes per group
  
  Writing inode tables:    0/   1 done     
  actual 0, size 1024
  ext2fs_mkdir: Attempt to read block from filesystem resulted in short read
while creating root dir

Which indicates that read() isn't returning as many bytes as it was asked
to.  I believe it's allowed to do this, but is there a reason why it
shouldn't?

Any ideas why this is failing?  I'm using a 2.0.36 kernel.  The partitions
were created with PartMan version 1.13a7, I think.

FYI, the contents of fdisk's debug file are:

  [root@localhost /root]# cat /tmp/part.debug 
  part_open(dev_name=/dev/hde, part_scheme=)
    blkio_open(/dev/hde)
      -geometry: [secsz=512, sec/tk=63, hds=15, cyls=13328]
    ret=0x26000
    powertec_detect()
      blkio_setblocksize(512)
      ret=512
      blkio_read(0x3fffba0 0x0 +0x1)
        -blocksize=0x200
      ret=1
      -powertec disc checksum: 50
      -powertec calc checksum: 62
    ret not detected
    icside_detect()
      blkio_setblocksize(512)
      ret=512
      blkio_read(0x3fffb98 0x0 +0x1)
        -blocksize=0x200
      ret=1
      -icside disc checksum: 50617FE6
      -icside calc checksum: 50617FE6
    ret detected
    icside_readinfo()
      blkio_read(0x3fffb98 0x0 +0x1)
        -blocksize=0x200
      ret=1
      part_add(parn=1, pinfo=[bs=0x0, be=0x1DAFFF, type=0x100])
        part_updatechs([bs=0x0, be=0x1DAFFF, type=0x100])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=0,H=0,S=0] end=[C=2058,H=12,S=33]
        ret ok
      ret ok
      part_add(parn=2, pinfo=[bs=0x1DB000, be=0x3B5FFF, type=0x100])
        part_updatechs([bs=0x1DB000, be=0x3B5FFF, type=0x100])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=2058,H=12,S=34] end=[C=4117,H=10,S=4]
        ret ok
      ret ok
      part_add(parn=3, pinfo=[bs=0x3B6000, be=0x626FFF, type=0x100])
        part_updatechs([bs=0x3B6000, be=0x626FFF, type=0x100])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=4117,H=10,S=5] end=[C=6826,H=9,S=62]
        ret ok
      ret ok
      part_add(parn=4, pinfo=[bs=0x627000, be=0x897FFF, type=0x100])
        part_updatechs([bs=0x627000, be=0x897FFF, type=0x100])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=6826,H=10,S=0] end=[C=9535,H=9,S=57]
        ret ok
      ret ok
      part_add(parn=5, pinfo=[bs=0x898000, be=0x97970F, type=0x100])
        part_updatechs([bs=0x898000, be=0x97970F, type=0x100])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=9535,H=9,S=58] end=[C=10512,H=12,S=11]
        ret ok
      ret ok
      blkio_read(0x3fff964 0x979710 +0x1)
        -blocksize=0x200
      ret=1
      part_add(parn=6, pinfo=[bs=0x979710, be=0x979710, type=0x101])
        part_updatechs([bs=0x979710, be=0x979710, type=0x101])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=10512,H=12,S=12] end=[C=10512,H=12,S=12]
        ret ok
      ret ok
      part_add(parn=7, pinfo=[bs=0x979711, be=0x986F6F, type=0x82])
        part_updatechs([bs=0x979711, be=0x986F6F, type=0x82])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=10512,H=12,S=13] end=[C=10571,H=6,S=26]
        ret ok
      ret ok
      blkio_read(0x3fff964 0x986F71 +0x1)
        -blocksize=0x200
      ret=1
      part_add(parn=8, pinfo=[bs=0x986F71, be=0x986F71, type=0x101])
        part_updatechs([bs=0x986F71, be=0x986F71, type=0x101])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=10571,H=6,S=28] end=[C=10571,H=6,S=28]
        ret ok
      ret ok
      part_add(parn=9, pinfo=[bs=0x986F72, be=0xC02F0E, type=0x83])
        part_updatechs([bs=0x986F72, be=0xC02F0E, type=0x83])
          blkio_getgeometry()
          ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
          start=[C=10571,H=6,S=29] end=[C=13327,H=14,S=61]
        ret ok
      ret ok
    ret ok
  ret=0x24f80
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=0)
  ret ok, pinfo=[bs=0x0, be=0x0, type=0x0]
  part_getpartinfo(parn=1)
  ret ok, pinfo=[bs=0x0, be=0x1DAFFF, type=0x100]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=2)
  ret ok, pinfo=[bs=0x1DB000, be=0x3B5FFF, type=0x100]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=3)
  ret ok, pinfo=[bs=0x3B6000, be=0x626FFF, type=0x100]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=4)
  ret ok, pinfo=[bs=0x627000, be=0x897FFF, type=0x100]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=5)
  ret ok, pinfo=[bs=0x898000, be=0x97970F, type=0x100]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=6)
  ret ok, pinfo=[bs=0x979710, be=0x979710, type=0x101]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=7)
  ret ok, pinfo=[bs=0x979711, be=0x986F6F, type=0x82]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=8)
  ret ok, pinfo=[bs=0x986F71, be=0x986F71, type=0x101]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=9)
  ret ok, pinfo=[bs=0x986F72, be=0xC02F0E, type=0x83]
  part_getgeometry()
    blkio_getgeometry()
    ret=[sector_size=512, sectors=63, heads=15, cylinders=13328]
  ret ok
  part_getpartinfo(parn=10)
  ret error

-- 
         Mark Seaborn
  - [email-masked] - http://www.argonet.co.uk/users/mseaborn/ -
 
    ``What does this mean, `mailer daemon'?  Satan, are
        you messing with the e-mail system already?'' -- (Herb Stern)

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Mark Seaborn <[email-masked]>
Date: Fri, 9 Apr 1999 20:49:32 +0100 (BST)

In <URL:news:local.armlinux> on Wed 07 Apr, Mark Seaborn wrote:

> with the ICS scheme.
[snip]
> Linux isn't reading the size of hde7 correctly?

Well, I've been looking through the sources for the kernel and for fdisk,
and I've managed to solve this, although I'm not sure how reliably.  Linux
was giving the size of the partition wrongly -- it falls down on the
partitions created by PartMan.

Take a look at part of adfspart_check_ICS() in adfspart.c:

> 	for (p = (struct ics_part *)bh->b_data; p->size; p++) {
> 		if ((minor & mask) == 0)
> 			break;
> 
> 		if (p->size < 0 && adfspart_check_ICSLinux (dev, p->start)) {
                    ^^^^^^^^^^^
This will never be true because `size' is defined as an unsigned long. 
Change the definition of struct ics_part and it's okay.

> 			/*
> 			 * We use the first sector to identify what type
> 			 * this partition is...
> 			 */
> 			if (p->size > 1)
> 				add_partition (hd, minor, first_sector + p->start + 1, p->size - 1);

In these two lines above, ``p->size'' must be changed into ``-p->size''.

> 		} else
> 			add_partition (hd, minor, first_sector + p->start, p->size);
> 		minor++;
> 	}

Once this is done, adfspart_check_ICSLinux() never returns true for me (it
never matches the string `LinuxPart').  However, the fdisk code does match
this, but seems to be doing the same thing, so I don't know what's going on
there.  I can't find this string when I look at the disc with Zap.

For the moment I've set adfspart_check_ICSLinux() to return true all the
time.  This seems to work:  I've created an ext2 fs on the partition, copied
everything across and I can boot from it.

Do these changes sound right?  I can't see how it could have worked before,
unless people used the ICS partitioning program instead of PartMan to create
Linux partitions (which would have been easier, surely?).

           A big hello to all sentient life forms out there!

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Fri, 9 Apr 1999 21:16:45 +0100 (BST)

> > 		if (p->size < 0 && adfspart_check_ICSLinux (dev, p->start)) {

Ok, fixed.

> In these two lines above, ``p->size'' must be changed into ``-p->size''.

Fixed as well.

> there.  I can't find this string when I look at the disc with Zap.

Have you checked the sectors that are specified in the debug file
(Pipe:$.C_Debug.*) which are passed to blkio_read during the icside_readinfo()
function?
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Mark Seaborn <[email-masked]>
Date: Sun, 11 Apr 1999 17:47:55 +0100 (BST)

In <URL:news:local.armlinux> on Fri 09 Apr, Russell King - ARM Linux Admin
wrote:

[snip]
> > Once this is done, adfspart_check_ICSLinux() never returns true for me
> > (it never matches the string `LinuxPart').  However, the fdisk code does
> > match this, but seems to be doing the same thing, so I don't know what's
> > going on there.  I can't find this string when I look at the disc with
> > Zap.
> 
> (Pipe:$.C_Debug.*) which are passed to blkio_read during the
> icside_readinfo() function?

Yes.  I've got a theory why they're not there.

I've downloaded the newest arm-fdisk (3.0.2) and PartMan (1.13a13).  Running
the new fdisk under Linux gives a different result to version 3.0:  It lists
all the partitions as being there, but it no longer recognises the last two
as Linux partitions; it doesn't match the `LinuxPart' string.

I notice in the ChangeLog that >2Gb drives are now supported in fdisk
3.0.2.  I'm using a 6Gb drive, and the Linux partitions are well above the
2Gb mark.  It seems that the old fdisk was probably matching the `LinuxPart'
string much lower down on the disc (some wraparound going on); the new one
looks in the right place and doesn't find it.  The newest PartMan behaves
the same as the old fdisk, because as far as I can tell the RISC OS code in
fdisk hasn't changed (it would be nice to have the full PartMan source).

I'd suggest that the kernel not be too fussed about that `LinuxPart' string,
since it doesn't do anything at the moment.  Just do, in
adfspart_check_ICS(), something like:

	if (p->size < 0) {
		/*
		 * Don't be too fussed if we don't find the string
		 * that PartMan wrote.
		 */
		if(adfspart_check_ICSLinux(dev, p->start))
			printk(" Linux partition:");
			else printk(" Linux partition (probably):");
		add_partition(hd, minor, first_sector + -p->start + 1, -p->size - 1);
	} else
		add_partition(hd, minor, first_sector + p->start, p->size);

I'm guessing you used negative sizes so that the RISC OS IDEFS would think
the partition table had ended.

           So foul and fair a tagline I have not seen.