Changes by: flatcap
Update of /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions
In directory usw-pr-cvs1:/tmp/cvs-serv27847/linux/fs/partitions
Modified Files:
ldm.c ldm.h
Log Message:
clean up and paranoid bulletproofing
Index: ldm.c
===================================================================
RCS file: /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions/ldm.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -U2 -r1.2 -r1.3
--- ldm.c 2001/06/17 13:46:16 1.2
+++ ldm.c 2001/06/18 02:53:19 1.3
@@ -25,21 +25,17 @@
#include <asm/types.h>
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include "check.h"
#include "ldm.h"
#include "msdos.h"
-#define SWAB16(x) (__u16) __arch__swab16 (*((__u16 *) (x)))
-#define SWAB32(x) (__u32) __arch__swab32 (*((__u32 *) (x)))
-#define SWAB64(x) (__u64) __arch__swab64 (*((__u64 *) (x)))
-
/* Get a variable-width number
- * The width is stored in a byte before the number
- */
-__u64 get_vnum (__u8 *block)
+ * The width is stored in a byte before the number */
+static u64 get_vnum (u8 *block)
{
- __u64 value = 0;
- int length;
- int i;
+ u8 length;
if (!block)
@@ -47,25 +43,16 @@
length = block[0];
- if (length > 8)
+ if ((length < 1) || (length > 8))
return 0;
- for (i = 1; i <= length; i++)
- {
- value <<= 8;
- value += block[i];
- }
-
- return value;
+ return BE64(block+1) >> (64 - (length<<3));
}
/* Extract a non-null-terminated ASCII string.
- * The length is stored in a byte before the string
- */
-__u8 * get_vstr (__u8 *block)
+ * The length is stored in a byte before the string */
+static u8 * get_vstr (u8 *block)
{
- static __u8 buffer[256];
- int length = 0;
-
- memset (buffer, 0, sizeof (buffer));
+ static u8 buffer[256];
+ u8 length = 0;
if (block)
@@ -74,12 +61,11 @@
memcpy (buffer, block+1, length);
}
-
+ buffer[length] = 0;
return buffer;
}
/* We're looking for an MSDOS-style partition table with one entry in it:
- * 0x42, which works like an extended partition. Detail will be placed in pt.
- */
-int parse_part_table (__u8 *buffer, struct ldmpart *pt)
+ * 0x42, which works like an extended partition. Detail will be placed in pt.*/
+int parse_part_table (u8 *buffer, struct ldmpart *pt)
{
struct partition *p;
@@ -88,5 +74,5 @@
return 0;
- if (*(__u16*) (buffer + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC))
+ if (*(u16*) (buffer + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC))
return 0;
@@ -102,40 +88,33 @@
}
-int parse_privhead (__u8 *buffer, struct privhead *ph)
+int parse_privhead (u8 *buffer, struct privhead *ph)
{
if (!buffer || !ph)
return 0;
- /* le to cpu */
- if (MAGIC_PRIVHEAD != *((__u64*) buffer))
+ if (MAGIC_PRIVHEAD != BE64 (buffer))
return 0;
- /* get unaligned? */ /* BIG ENDIAN */
- ph->log_disk_start = SWAB64 (buffer + 0x011B);
- ph->log_disk_size = SWAB64 (buffer + 0x0123);
- ph->config_start = SWAB64 (buffer + 0x012B);
- ph->config_size = SWAB64 (buffer + 0x0133);
-
- memcpy (ph->disk_id, buffer + 0x0030, 64);
+ ph->ver_major = BE16 (buffer + 0x000C);
+ ph->ver_minor = BE16 (buffer + 0x000E);
+ if ((ph->ver_major != 2) || (ph->ver_minor != 11))
+ return 0;
- /*
- printk ("log_disk_start = %lld\n", ph->log_disk_start);
- printk ("log_disk_size = %lld\n", ph->log_disk_size);
- printk ("config_start = %lld\n", ph->config_start);
- printk ("config_size = %lld\n", ph->config_size);
+ ph->log_disk_start = BE64 (buffer + 0x011B);
+ ph->log_disk_size = BE64 (buffer + 0x0123);
+ ph->config_start = BE64 (buffer + 0x012B);
+ ph->config_size = BE64 (buffer + 0x0133);
- printk ("disk_id = %s\n", ph->disk_id);
- */
+ memcpy (ph->disk_id, buffer + 0x0030, 64);
return 1;
}
-int parse_tocblock (__u8 *buffer, struct tocblock *toc)
+int parse_tocblock (u8 *buffer, struct tocblock *toc)
{
if (!buffer || !toc)
return 0;
-
- /* le to cpu */
- if (MAGIC_TOCBLOCK != *((__u64*) buffer))
+
+ if (MAGIC_TOCBLOCK != BE64 (buffer))
return 0;
@@ -143,25 +122,25 @@
}
-int parse_vmdb (__u8 *buffer, struct vmdb *vm)
+int parse_vmdb (u8 *buffer, struct vmdb *vm)
{
if (!buffer || !vm)
+ return 0;
+
+ if (MAGIC_VMDB != BE32 (buffer))
return 0;
-
- //printk ("parse_vmdb\n");
- /* le to cpu */
- if (MAGIC_VMDB != *((__u32*) buffer))
+ vm->ver_major = BE16 (buffer + 0x12);
+ vm->ver_minor = BE16 (buffer + 0x14);
+ if ((vm->ver_major != 4) || (vm->ver_minor != 10))
return 0;
- vm->ver_major = SWAB16 (buffer + 0x12);
- vm->ver_minor = SWAB16 (buffer + 0x14);
- vm->vblk_size = SWAB32 (buffer + 0x08);
- vm->vblk_offset = SWAB32 (buffer + 0x0C);
- vm->last_vblk_seq = SWAB32 (buffer + 0x04);
+ vm->vblk_size = BE32 (buffer + 0x08);
+ vm->vblk_offset = BE32 (buffer + 0x0C);
+ vm->last_vblk_seq = BE32 (buffer + 0x04);
return 1;
}
-int parse_partition (__u8 *buffer, struct vblk *vb)
+int parse_partition (u8 *buffer, struct vblk *vb)
{
int rel_objid;
@@ -179,5 +158,5 @@
vb->obj_id = get_vnum (buffer+0x18);
vb->disk_id = get_vnum (buffer+0x34+rel_parent);
- vb->start_sector = SWAB64 (buffer+0x24+rel_name);
+ vb->start_sector = BE64 (buffer+0x24+rel_name);
vb->num_sectors = get_vnum (buffer+0x34+rel_name);
strcpy (vb->name, get_vstr (buffer+0x18+rel_objid));
@@ -186,16 +165,13 @@
}
-int parse_vblk (struct privhead *ph, __u8 *buffer, struct vblk *vb)
+int parse_vblk (struct privhead *ph, u8 *buffer, struct vblk *vb)
{
if (!buffer || !vb)
return 0;
-
- //printk ("parse_vblk\n");
- /* le to cpu */
- if (MAGIC_VBLK != *((__u32*) buffer))
+ if (MAGIC_VBLK != BE32 (buffer))
return 0;
- if (SWAB16 (buffer+14) == 0) /* record not in use */
+ if (BE16 (buffer+14) == 0) /* record not in use */
return 0;
@@ -215,9 +191,20 @@
}
+/* find the three copies of the private header
+ * and verify that they are identical */
+int get_privhead (struct privhead *ph)
+{
+ return 0;
+}
+
+int get_device_block (kdev_t dev)
+{
+ return 0;
+}
+
/* 1 = match, 0 = no match, -1 = error */
int ldm_partition(struct gendisk *hd, kdev_t dev,
unsigned long first_sector, int first_part_minor)
{
- //int sector_size; sector_size = get_hardsect_size (dev);
struct buffer_head *bh;
struct ldmpart pt;
@@ -232,17 +219,18 @@
struct vblk vb;
struct ldmdisk dk;
- __u8 *data;
- int ret = -1;
- int blocksize;
- int size;
+ u8 *data;
+ int ret = 0;
int i;
int j;
int k;
int minor = first_part_minor;
+
+ if (1024 != get_ptable_blocksize (dev))
+ goto end;
- blocksize = get_ptable_blocksize (dev);
- size = (0x1000 / blocksize) * blocksize; /* need at least 3.5K */
+ if (512 != get_hardsect_size (dev))
+ goto end;
- if (!(bh = bread (dev, 0, size)))
+ if (!(bh = bread (dev, 0, 1024)))
{
if (warn_no_part)
@@ -250,52 +238,53 @@
goto end;
}
-
- data = bh->b_data;
-
- if (!parse_part_table (data, &pt))
- {
- ret = 0;
- goto free;
- }
- if (!parse_privhead (data+0x0C00, &ph1)) /* Fixed offset */
+ if (!parse_part_table (bh->b_data, &pt))
goto free;
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start, 2*blocksize)))
- goto end;
- data = bh->b_data;
+ ret = -1; /* Anything after here is OUR problem */
- if (!parse_tocblock (data + 0x0200, &toc1))
- goto free;
+ /*-----------------------------------------------------*/
+ if (!(bh = bread (dev, 6, 1024)))
+ goto end;
- if (!parse_tocblock (data + 0x0400, &toc2))
+ data = bh->b_data;
+ if (!parse_privhead (data+0x0000, &ph1))
goto free;
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+17, blocksize)))
+ if (!(bh = bread (dev, ph1.config_start+1856, 1024)))
goto end;
data = bh->b_data;
+ if (!parse_privhead (data, &ph2))
+ goto free;
- if (!parse_vmdb (data, &vm))
+ brelse (bh);
+ if (!(bh = bread (dev, ph1.config_start+2046, 1024)))
goto end;
+ data = bh->b_data;
+ if (!parse_privhead (data + 0x0200, &ph3))
+ goto free;
+
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+1856, blocksize)))
+ /*-----------------------------------------------------*/
+ if (!(bh = bread (dev, ph1.config_start+1, 1024)))
goto end;
data = bh->b_data;
+ if (!parse_tocblock (data + 0x0000, &toc1))
+ goto free;
- if (!parse_privhead (data, &ph2))
+ if (!parse_tocblock (data + 0x0200, &toc2))
goto free;
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+2045, blocksize)))
+ if (!(bh = bread (dev, ph1.config_start+2045, 1024)))
goto end;
data = bh->b_data;
-
if (!parse_tocblock (data + 0x0000, &toc3))
goto free;
@@ -305,13 +294,11 @@
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+2046, blocksize)))
+ /*-----------------------------------------------------*/
+ if (!(bh = bread (dev, ph1.config_start+17, 1024)))
goto end;
data = bh->b_data;
-
- if (!parse_privhead (data + 0x0200, &ph3))
- goto free;
-
- //printk ("LDM (%d entries)\n", vm.last_vblk_seq - 4);
+ if (!parse_vmdb (data, &vm))
+ goto end;
// take into account size and offset in vmdb
@@ -322,12 +309,13 @@
{
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+18+i, blocksize)))
+ if (!(bh = bread (dev, ph1.config_start+18+i, 1024)))
goto end;
+ //if (data)...
data = bh->b_data;
for (k = 0; k < 4; k++)
{
- __u8 *block;
+ u8 *block;
block = data + 0x80*k;
@@ -340,4 +328,5 @@
char *disk_id;
+ /* remove the +1's */
/* Calculate relative offsets */
rel_objid = 1 + block[0x18];
@@ -347,11 +336,4 @@
disk_id = get_vstr (block+0x18+rel_name);
- //printk ("block = %p\n", block);
- //printk ("0x%06X: [%06X] <Disk>\n", SWAB32 (block+0x04), SWAB32 (block+0x08));
- //printk (" Name : %s\n", get_vstr (block+0x18+rel_objid));
- //printk (" Object Id : 0x%04llx\n", get_vnum (block+0x18));
- //printk (" Disk Id : %s\n", disk_id);
-
- //printk ("<%s>, <%s>\n", disk_id, ph1.disk_id);
if (strcmp (disk_id, ph1.disk_id) == 0)
{
@@ -373,5 +355,5 @@
{
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+18+i, blocksize)))
+ if (!(bh = bread (dev, ph1.config_start+18+i, 1024)))
goto end;
@@ -380,5 +362,5 @@
for (k = 0; k < 4; k++)
{
- __u8 *block;
+ u8 *block;
block = data + 0x80*k;
Index: ldm.h
===================================================================
RCS file: /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions/ldm.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -U2 -r1.1.1.1 -r1.2
--- ldm.h 2001/06/16 20:29:39 1.1.1.1
+++ ldm.h 2001/06/18 02:53:19 1.2
@@ -27,10 +27,13 @@
*/
+#include <asm/types.h>
#include <asm/unaligned.h>
+#include <asm/byteorder.h>
-#define MAGIC_VMDB 0x42444D56 /* "VMDB" */
-#define MAGIC_VBLK 0x4B4C4256 /* "VBLK" */
-#define MAGIC_PRIVHEAD 0x4441454856495250 /* "PRIVHEAD" */
-#define MAGIC_TOCBLOCK 0x4B434F4C42434F54 /* "TOCBLOCK" */
+/* Magic numbers in big-endian format */
+#define MAGIC_VMDB 0x564D4442 /* "VMDB" */
+#define MAGIC_VBLK 0x56424C4B /* "VBLK" */
+#define MAGIC_PRIVHEAD 0x5052495648454144 /* "PRIVHEAD" */
+#define MAGIC_TOCBLOCK 0x544F43424C4F434B /* "TOCBLOCK" */
#define VBLK_COMP 0x32 /* Component */
@@ -54,4 +57,21 @@
})
+/* Most numbers we deal with are big-endian and won't be aligned */
+#define BE16(x) (u16) be16_to_cpu (get_unaligned ((u16*)(x)))
+#define BE32(x) (u32) be32_to_cpu (get_unaligned ((u32*)(x)))
+#define BE64(x) (u64) be64_to_cpu (get_unaligned ((u64*)(x)))
+
+/* Borrowed from msdos.c */
+#define SYS_IND(p) (get_unaligned(&p->sys_ind))
+#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \
+ get_unaligned(&p->nr_sects); \
+ le32_to_cpu(__a); \
+ })
+
+#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \
+ get_unaligned(&p->start_sect); \
+ le32_to_cpu(__a); \
+ })
+
struct ldmpart
{
@@ -68,4 +88,6 @@
struct privhead /* Offsets and sizes in sectors */
{
+ __u16 ver_major;
+ __u16 ver_minor;
__u64 log_disk_start;
__u64 log_disk_size;
|