Changes by: flatcap
Update of /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions
In directory usw-pr-cvs1:/tmp/cvs-serv19705/linux/fs/partitions
Modified Files:
ldm.c ldm.h
Log Message:
it works, it works, it works! the kernel now supports dynamic disks!
Index: ldm.c
===================================================================
RCS file: /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions/ldm.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -U2 -r1.3 -r1.4
--- ldm.c 2001/06/18 02:53:19 1.3
+++ ldm.c 2001/06/20 02:55:42 1.4
@@ -101,9 +101,12 @@
return 0;
- 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);
+ if (ph->config_size != 2048) /* 1 Mb */
+ return 0;
+ ph->log_disk_start = BE64 (buffer + 0x011B);
+ ph->log_disk_size = BE64 (buffer + 0x0123);
+
memcpy (ph->disk_id, buffer + 0x0030, 64);
@@ -115,8 +118,6 @@
if (!buffer || !toc)
return 0;
-
if (MAGIC_TOCBLOCK != BE64 (buffer))
return 0;
-
return 1;
}
@@ -126,5 +127,4 @@
if (!buffer || !vm)
return 0;
-
if (MAGIC_VMDB != BE32 (buffer))
return 0;
@@ -191,20 +191,66 @@
}
-/* find the three copies of the private header
- * and verify that they are identical */
-int get_privhead (struct privhead *ph)
+/* validate the range, then put an entry into the kernel's partition table
+ * start and size are numbers of sectors */
+int create_partition (struct gendisk *hd, int minor, int start, int size)
{
- return 0;
+ int disk_minor;
+ if (!hd || !hd->part)
+ return 0;
+
+ disk_minor = (minor >> hd->minor_shift) << hd->minor_shift;
+ if ((start < 1) || ((start + size) > hd->part[disk_minor].nr_sects))
+ return 0;
+
+ add_gd_partition (hd, minor, start, size);
+ return 1;
}
-int get_device_block (kdev_t dev)
+#if 0
+struct buffer_head * get_device_block (kdev_t dev, int sector)
{
- return 0;
+ return NULL;
}
+#endif
+
+/* find the primary private header, locate the LDM database,
+ * then create a partition to wrap it */
+int create_db_partition (struct gendisk *hd, kdev_t dev, struct privhead *ph)
+{
+ struct buffer_head *bh;
+ int ret = 0;
+
+ if (!ph)
+ goto cdp_end;
+ if (!(bh = bread (dev, OFF_PRIVHEAD1, 1024)))
+ goto cdp_end;
+
+ if (!parse_privhead (bh->b_data, ph))
+ goto cdp_free;
+
+ if (create_partition (hd, MINOR(dev)+LDM_DB_PART, ph->config_start, ph->config_size));
+ ret = 1;
+cdp_free:
+ brelse (bh);
+cdp_end:
+ return ret;
+}
+
+#ifdef XXX
+static inline struct buffer_head *
+get_partition_table_block(struct gendisk *hd, int minor, int blocknr)
+{
+ kdev_t dev = MKDEV(hd->major, minor);
+ return bread(dev, blocknr, get_ptable_blocksize(dev));
+}
+#endif
+
/* 1 = match, 0 = no match, -1 = error */
int ldm_partition(struct gendisk *hd, kdev_t dev,
unsigned long first_sector, int first_part_minor)
{
+ /* what about first_sector, first_part_minor? */
+ /* demote the "sector counts" to ints? -- limit of 1Tb */
struct buffer_head *bh;
struct ldmpart pt;
@@ -224,10 +270,11 @@
int j;
int k;
- int minor = first_part_minor;
+ int minor = first_part_minor + LDM_FIRST_PART;
+ kdev_t devdb;
- if (1024 != get_ptable_blocksize (dev))
+ if (get_ptable_blocksize (dev) != 1024)
goto end;
- if (512 != get_hardsect_size (dev))
+ if (get_hardsect_size (dev) != 512)
goto end;
@@ -244,64 +291,60 @@
brelse (bh);
- ret = -1; /* Anything after here is OUR problem */
+ ret = -1; /* Any problem after here are OUR problem */
- /*-----------------------------------------------------*/
- if (!(bh = bread (dev, 6, 1024)))
- goto end;
-
- data = bh->b_data;
- if (!parse_privhead (data+0x0000, &ph1))
+ if (!create_db_partition (hd, dev, &ph1))
goto free;
- brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+1856, 1024)))
- goto end;
+ /* we now have a dedicated partition for our database */
+ devdb = MKDEV (MAJOR(dev), MINOR(dev)+LDM_DB_PART);
- data = bh->b_data;
- if (!parse_privhead (data, &ph2))
+ if (!(bh = bread (devdb, OFF_PRIVHEAD2, 1024)))
+ goto end;
+ if (!parse_privhead (data = bh->b_data, &ph2))
goto free;
-
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+2046, 1024)))
- goto end;
- data = bh->b_data;
- if (!parse_privhead (data + 0x0200, &ph3))
+ if (!(bh = bread (devdb, OFF_PRIVHEAD3, 1024)))
+ goto end;
+ if (!parse_privhead (data = bh->b_data + 0x0200, &ph3))
goto free;
-
brelse (bh);
+
/*-----------------------------------------------------*/
- if (!(bh = bread (dev, ph1.config_start+1, 1024)))
+ if (!(bh = bread (devdb, OFF_TOCBLOCK1, 1024)))
goto end;
-
- data = bh->b_data;
- if (!parse_tocblock (data + 0x0000, &toc1))
+ if (!parse_tocblock (data = bh->b_data + 0x0200, &toc1))
goto free;
+ brelse (bh);
- if (!parse_tocblock (data + 0x0200, &toc2))
+ if (!(bh = bread (devdb, OFF_TOCBLOCK2, 1024)))
+ goto end;
+ if (!parse_tocblock (data = bh->b_data, &toc2))
goto free;
-
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+2045, 1024)))
- goto end;
- data = bh->b_data;
- if (!parse_tocblock (data + 0x0000, &toc3))
+ if (!(bh = bread (devdb, OFF_TOCBLOCK3, 1024)))
+ goto end;
+ if (!parse_tocblock (data = bh->b_data + 0x0200, &toc3))
goto free;
+ brelse (bh);
- if (!parse_tocblock (data + 0x0200, &toc4))
+ if (!(bh = bread (devdb, OFF_TOCBLOCK4, 1024)))
+ goto end;
+ if (!parse_tocblock (data = bh->b_data, &toc4))
goto free;
-
brelse (bh);
+
/*-----------------------------------------------------*/
- if (!(bh = bread (dev, ph1.config_start+17, 1024)))
- goto end;
- data = bh->b_data;
- if (!parse_vmdb (data, &vm))
+ if (!(bh = bread (devdb, OFF_VMDB, 1024)))
+ goto end;
+ if (!parse_vmdb (data = bh->b_data + 0x200, &vm))
goto end;
+ /*-----------------------------------------------------*/
+
// take into account size and offset in vmdb
- j = vm.last_vblk_seq / 4;
+ j = vm.last_vblk_seq / 8;
// first find the correct disk
@@ -309,38 +352,34 @@
{
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+18+i, 1024)))
+ if (!(bh = bread (devdb, OFF_VBLK+i, 1024)))
goto end;
- //if (data)...
data = bh->b_data;
- for (k = 0; k < 4; k++)
+ for (k = 0; k < 8; k++)
{
+ int rel_objid;
+ int rel_name;
+ int rel_diskid;
+ char *disk_id;
u8 *block;
block = data + 0x80*k;
+ if (block[19] != VBLK_DISK)
+ continue;
- if (block[19] == VBLK_DISK)
- {
- int rel_objid;
- int rel_name;
- int rel_diskid;
- char *disk_id;
-
- /* remove the +1's */
- /* Calculate relative offsets */
- rel_objid = 1 + block[0x18];
- rel_name = 1 + block[0x18+rel_objid] + rel_objid;
- rel_diskid = 1 + block[0x18+rel_name] + rel_name;
-
- disk_id = get_vstr (block+0x18+rel_name);
-
- if (strcmp (disk_id, ph1.disk_id) == 0)
- {
- dk.obj_id = get_vnum (block+0x18);
- strcpy (dk.disk_id, disk_id);
- goto found;
- }
+ /* remove the +1's */
+ /* Calculate relative offsets */
+ rel_objid = 1 + block[0x18];
+ rel_name = 1 + block[0x18+rel_objid] + rel_objid;
+ rel_diskid = 1 + block[0x18+rel_name] + rel_name;
+
+ disk_id = get_vstr (block+0x18+rel_name);
+ if (strcmp (disk_id, ph1.disk_id) == 0)
+ {
+ dk.obj_id = get_vnum (block+0x18);
+ strcpy (dk.disk_id, disk_id);
+ goto found;
}
}
@@ -350,40 +389,32 @@
goto free;
found:
-
- printk (" Dynamic disks <");
+ printk (" <");
for (i = 0; i < j; i++)
{
brelse (bh);
- if (!(bh = bread (dev, ph1.config_start+18+i, 1024)))
+ if (!(bh = bread (devdb, OFF_VBLK+i, 1024)))
goto end;
data = bh->b_data;
- for (k = 0; k < 4; k++)
+ for (k = 0; k < 8; k++)
{
u8 *block;
block = data + 0x80*k;
+ if (block[19] != VBLK_PART)
+ continue;
- if (block[19] == VBLK_PART)
- {
- if (!parse_vblk (&ph1, data+(0x80*k), &vb))
- goto free;
- if (dk.obj_id == vb.disk_id)
- {
- printk (" %s", vb.name);
-
- hd->part[minor].start_sect = vb.start_sector + ph1.log_disk_start;
- hd->part[minor].nr_sects = vb.num_sectors;
- minor++;
- }
- }
+ if (!parse_vblk (&ph1, data+(0x80*k), &vb))
+ goto free;
+
+ if (dk.obj_id != vb.disk_id)
+ continue;
+
+ if (create_partition (hd, minor, vb.start_sector + ph1.log_disk_start, vb.num_sectors))
+ minor++;
}
}
- minor = ((minor + hd->max_p) & ~(hd->max_p - 1)) - 1; /* round up */
- hd->part[minor].start_sect = ph1.config_start;
- hd->part[minor].nr_sects = ph1.config_size;
-
printk (" >\n");
ret = 1; /* We've dealt with it */
@@ -395,10 +426,52 @@
#if 0
+ minor = ((minor + hd->max_p) & ~(hd->max_p - 1)) - 1; /* round up */
+ hd->part[minor].start_sect = ph1.config_start;
+ hd->part[minor].nr_sects = ph1.config_size;
+
+ //if (data)...?
+ /* find the three copies of the private header
+ * and verify that they are identical */
+ //LDM_FIRST_PART
+
+#define isprint(a) ((a >=' ')&&(a <= '~'))
+ if (0)
{
int offset = 0;
- printk ("0 %02x %02x %02x %02x %02x %02x %02x %02x - %c%c%c%c%c%c%c%c\n", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5], data[offset+6], data[offset+7], isprint (data[offset+0]) ? data[offset+0] : '.', isprint (data[offset+1]) ? data[offset+1] : '.', isprint (data[offset+2]) ? data[offset+2] : '.', isprint (data[offset+3]) ? data[offset+3] : '.', isprint (data[offset+4]) ? data[offset+4] : '.', isprint (data[offset+5]) ? data[offset+5] : '.', isprint (data[offset+6]) ? data[offset+6] : '.', isprint (data[offset+7]) ? data[offset+7] : '.');
- offset += 512;
+ printk ("%02x %02x %02x %02x %02x %02x %02x %02x - %c%c%c%c%c%c%c%c\n", data[offset+0], data[offset+1], data[offset+2], data[offset+3], data[offset+4], data[offset+5], data[offset+6], data[offset+7], isprint (data[offset+0]) ? data[offset+0] : '.', isprint (data[offset+1]) ? data[offset+1] : '.', isprint (data[offset+2]) ? data[offset+2] : '.', isprint (data[offset+3]) ? data[offset+3] : '.', isprint (data[offset+4]) ? data[offset+4] : '.', isprint (data[offset+5]) ? data[offset+5] : '.', isprint (data[offset+6]) ? data[offset+6] : '.', isprint (data[offset+7]) ? data[offset+7] : '.');
+ offset += 128;
printk ("\n");
}
+
+void dump_sectors (kdev_t dev, int block, int size)
+{
+ struct buffer_head *bh;
+ u8 *data;
+ int i, off = 0;
+
+ if (!(bh = bread (dev, block, size)))
+ return;
+
+ printk ("block = %d, size = %d\n", block, size);
+
+ data = bh->b_data;
+
+ for (i = 0; i < size/512; i++, off+=512)
+ {
+ printk ("%d %02x %02x %02x %02x\n", i, data[off+0], data[off+1], data[off+2], data[off+3]);
+ }
+ printk ("\n");
+
+ bforget (bh);
+}
+
+ set_blocksize (dev, 512);
+ if (!(bh = bread (dev, 1, 512)))
+ return -1;
+
+ if (bh->b_data[0] != 1)
+ return 0;
+ bforget (bh);
+
#endif
Index: ldm.h
===================================================================
RCS file: /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions/ldm.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -U2 -r1.2 -r1.3
--- ldm.h 2001/06/18 02:53:19 1.2
+++ ldm.h 2001/06/20 02:55:42 1.3
@@ -43,7 +43,23 @@
#define VBLK_VOLU 0x51 /* Volume */
+#define LDM_DB_PART 1 /* hd?1, LDM Database */
+#define LDM_FIRST_PART 5 /* hd?5, first LDM partition */
+
+/* Offsets to structures within the LDM Database */
+#define OFF_PRIVHEAD1 3 /* Private Headers */
+#define OFF_PRIVHEAD2 928
+#define OFF_PRIVHEAD3 1023
+
+#define OFF_TOCBLOCK1 0 /* Table of Contents */
+#define OFF_TOCBLOCK2 1
+#define OFF_TOCBLOCK3 1022
+#define OFF_TOCBLOCK4 1023
+
+#define OFF_VMDB 8 /* The list of partitions */
+#define OFF_VBLK 9
+
#define WIN2K_DYNAMIC_PARTITION 0x42 /* Formerly SFS */
-/* borrowed from msdos.c */
+/* Borrowed from msdos.c */
#define SYS_IND(p) (get_unaligned(&p->sys_ind))
#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \
@@ -76,23 +92,23 @@
struct ldmpart
{
- __u64 start_sector;
- __u64 num_sectors;
+ u64 start_sector;
+ u64 num_sectors;
};
struct ldmdisk
{
- __u64 obj_id;
- __u8 disk_id[64];
+ u64 obj_id;
+ u8 disk_id[64];
};
struct privhead /* Offsets and sizes in sectors */
{
- __u16 ver_major;
- __u16 ver_minor;
- __u64 log_disk_start;
- __u64 log_disk_size;
- __u64 config_start;
- __u64 config_size;
- __u8 disk_id[64];
+ u16 ver_major;
+ u16 ver_minor;
+ u64 log_disk_start;
+ u64 log_disk_size;
+ u64 config_start;
+ u64 config_size;
+ u8 disk_id[64];
};
@@ -104,19 +120,19 @@
struct vmdb
{
- __u16 ver_major;
- __u16 ver_minor;
- __u32 vblk_size;
- __u32 vblk_offset;
- __u32 last_vblk_seq;
+ u16 ver_major;
+ u16 ver_minor;
+ u32 vblk_size;
+ u32 vblk_offset;
+ u32 last_vblk_seq;
};
struct vblk
{
- __u8 name[64];
- __u8 vblk_type;
- __u64 obj_id;
- __u64 disk_id;
- __u64 start_sector;
- __u64 num_sectors;
+ u8 name[64];
+ u8 vblk_type;
+ u64 obj_id;
+ u64 disk_id;
+ u64 start_sector;
+ u64 num_sectors;
};
|