Changes by: jkemi
Update of /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions
In directory usw-pr-cvs1:/tmp/cvs-serv24391
Modified Files:
ldm.c
Log Message:
Big cleanup. ldm_create_db_partition() obsolete.
ldm_validate_partition_table() rewritten. Commenting ( esp. in
ldm_combine_vblks() )
Index: ldm.c
===================================================================
RCS file: /cvsroot/linux-ntfs/dynamic-disk/linux/fs/partitions/ldm.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -U2 -r1.56 -r1.57
--- ldm.c 9 Feb 2002 16:39:33 -0000 1.56
+++ ldm.c 9 Feb 2002 18:10:08 -0000 1.57
@@ -350,48 +350,38 @@
u8 *data;
struct partition *p;
- int i, nr_sfs;
- BOOL result = FALSE;
-
- BUG_ON (!bdev);
+ int i;
- data = read_dev_sector (bdev, 0, §);
- if (!data)
+ if ((data = read_dev_sector (bdev, 0, §)) == 0)
return FALSE; // FIXME error message?
if (*(u16*) (data + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC)) {
ldm_debug ("No MS-DOS partition found.\n");
- goto out;
+ put_dev_sector(sect);
+ return FALSE;
}
- nr_sfs = 0;
+
p = (struct partition*)(data + 0x01BE);
- for (i = 0; i < 4; i++, p++) {
- if (!SYS_IND (p) || SYS_IND (p) == WIN2K_EXTENDED_PARTITION)
- continue;
- if (SYS_IND (p) == WIN2K_DYNAMIC_PARTITION) {
- nr_sfs++;
- continue;
- }
- break;
- }
- if (nr_sfs) {
- result = TRUE;
- ldm_debug ("Parsed partition table successfully.\n");
- } else {
- ldm_debug ("Found a basic MS-DOS partition, not a dynamic "
- "disk.\n");
+ for (i = 0; i < 4; i++, p++)
+ if (SYS_IND(p) == WIN2K_DYNAMIC_PARTITION)
+ break;
+
+ put_dev_sector(sect);
+ if (i == 4) {
+ ldm_debug(
+ "Found a basic MS-DOS partition, not a dynamic disk.\n");
+ return FALSE;
}
-out:
- put_dev_sector (sect);
- return result;
+
+ ldm_debug ("Parsed partition table successfully.\n");
+ return TRUE;
}
/**
* ldm_validate_privheads - Compare the primary privhead with its backups
- * @bdev: Partition device holding the LDM Database
- * @base: The offset into the device
- * @ph1: First privhead which we have already validated
+ * @bdev: Partition device holding the LDM Database
+ * @first_sector: First sector within the device
+ * @ph1: Memory struct to fill with ph contents
*
- * We already have the primary privhead from the beginning of the disk.
- * Now we compare the two other copies for safety.
+ * Read and compare all three privheads from disk.
*
* Return: TRUE Success
@@ -399,18 +389,23 @@
*/
static BOOL ldm_validate_privheads (struct block_device *bdev,
- unsigned long base, const struct privhead *ph1)
+ unsigned long first_sector, struct privhead *ph1)
{
Sector sect;
u8 *data;
struct privhead ph2, ph3;
- struct privhead *ph[3] = {NULL, &ph2, &ph3};
+ struct privhead *ph[3] = {ph1, &ph2, &ph3};
const int off[3] = {OFF_PRIVHEAD1, OFF_PRIVHEAD2, OFF_PRIVHEAD3};
int i;
- /* Read and parse ph 2 & 3 */
+ /* off[1 & 2] are relative to ph[0]->config_start */
+ ph[0]->config_start = 0;
+
+ /* Read and parse privheads */
// FIXME can ph 3 fail on odd-sized disks?
- for (i = 1; i < 3; i++) {
- int r;
- if (!(data = read_dev_sector (bdev, base + off[i], §))) {
+ for (i = 0; i < 3; i++) {
+ BOOL r;
+ data = read_dev_sector (bdev,
+ first_sector + ph[0]->config_start + off[i], §);
+ if (!data) {
printk (LDM_CRIT "Disk read failed.\n");
return FALSE;
@@ -424,6 +419,6 @@
/* Compare privheads */
- if (!ldm_compare_privheads (ph1, ph[1]) ||
- !ldm_compare_privheads (ph1, ph[2])) {
+ if (!ldm_compare_privheads (ph[0], ph[1]) ||
+ !ldm_compare_privheads (ph[0], ph[2])) {
printk (LDM_CRIT "Primary and backup PRIVHEADs don't match.\n");
return FALSE;
@@ -460,5 +455,5 @@
for (i = 0; i < 4; i++)
{
- int r;
+ BOOL r;
if (!(data = read_dev_sector (bdev, base + off[i], §))) {
printk (LDM_CRIT "Disk read failed.\n");
@@ -503,8 +498,5 @@
BOOL result;
- BUG_ON (!bdev || !vm);
-
- data = read_dev_sector (bdev, base + OFF_VMDB, §);
- if (!data) {
+ if ((data = read_dev_sector (bdev, base + OFF_VMDB, §)) == 0) {
printk (LDM_CRIT "Disk read failed.\n");
return FALSE;
@@ -527,10 +519,7 @@
{
list_t *item;
- struct vblk *vb;
-
- BUG_ON (!lh_vl);
list_for_each (item, lh_vl) {
- vb = list_entry (item, struct vblk, list);
+ struct vblk *vb = list_entry (item, struct vblk, list);
if (vb->obj_id == id)
return vb;
@@ -576,49 +565,4 @@
/**
- * ldm_create_db_partition - Create a dedicated partition for our database
- * @hd: gendisk structure in which to create partition
- * @bdev: Device to be partitioned
- * @first_sector: First sector of data on the device
- * @first_minor: Device minor to be used
- * @ph: privhead structure to save the Primary PRIVHEAD in
- *
- * Find the primary private header, locate the LDM Database, then create a
- * partition to wrap it.
- *
- * Return: TRUE The device is a dynamic disk
- * FALSE Error, the device may or may not be a dynamic disk
- */
-static BOOL ldm_create_db_partition (struct gendisk *hd,
- struct block_device *bdev, unsigned long first_sector,
- int first_minor, struct privhead *ph)
-{
- Sector sect;
- u8 *data;
- BOOL result = FALSE;
-
- BUG_ON (!hd || !bdev || !ph);
-
- data = read_dev_sector (bdev, OFF_PRIVHEAD1, §);
- if (!data) {
- printk (LDM_CRIT "Device read failed.\n");
- return FALSE;
- }
- if (BE64 (data) != MAGIC_PRIVHEAD) {
- printk (LDM_ERR "Cannot find PRIVHEAD structure. "
- "Not a dynamic disk or corrupt LDM Database.\n");
- goto out;
- }
- if (!ldm_parse_privhead (data, ph))
- goto out; /* Already logged */
-
- result = ldm_create_partition (hd, first_minor,
- first_sector + ph->config_start, ph->config_size);
-out:
- put_dev_sector (sect);
- //FIXME ldm_debug here?
- return result;
-}
-
-/**
* ldm_create_data_partitions - Create data partitions for this device
* @hd: gendisk structure in which to create the data partitions
@@ -958,8 +902,6 @@
ldm_get_vstr (buffer + 0x18 + rel_diskid, disk->alt_name,
sizeof (disk->alt_name));
- if (!ldm_parse_guid (buffer + 0x19 + rel_name, disk->disk_id)) {
- printk ("failed\n"); // FIXME
+ if (!ldm_parse_guid (buffer + 0x19 + rel_name, disk->disk_id))
return FALSE;
- }
return TRUE;
@@ -1096,5 +1038,5 @@
* @vb: In-memory vblk in which to return information
* @page: Disk sector page
- * @recycled: Reset record number and count if 1
+ * @recycled: Reset record number and count if TRUE
*
* Read a raw VBLK Component object into a more usable vblk structure.
@@ -1110,7 +1052,7 @@
*/
static BOOL ldm_parse_vblk (const u8 *buffer, int buflen, struct vblk *vb,
- struct page *page, int recycled)
+ struct page *page, BOOL recycled)
{
- BOOL result = FALSE;
+ BOOL result;
BUG_ON (!buffer || !vb);
@@ -1120,5 +1062,5 @@
if (MAGIC_VBLK != BE32 (buffer)) {
- printk (LDM_CRIT "Cannot find VBLK, database may be corrupt.\n");
+ ldm_debug("Not a valid VBLK, missing magic number.\n");
return FALSE;
}
@@ -1133,57 +1075,58 @@
if (vb->rec_count == 0) {
- printk (LDM_ERR "VBLK record count 0 !!\n");
+ ldm_debug("record count is 0, skipping.\n");
return FALSE;
}
- if (vb->rec_num == 0 && vb->rec_count == 1) { /* First record */
- vb->flags = buffer[0x12];
- vb->type = buffer[0x13];
- vb->obj_id = ldm_get_vnum (buffer + 0x18);
- ldm_get_vstr (buffer+0x19+buffer[0x18], vb->name,
- sizeof (vb->name));
-
- switch (vb->type) {
- case VBLK_COMP:
- result = ldm_parse_comp (buffer, buflen, vb); break;
- case VBLK_DSK1:
- result = ldm_parse_disk (buffer, buflen, vb); break;
- case VBLK_DSK2:
- result = ldm_parse_disk2(buffer, buflen, vb); break;
- case VBLK_DGR1:
- result = ldm_parse_dgrp (buffer, buflen, vb); break;
- case VBLK_DGR2:
- result = ldm_parse_dgrp2(buffer, buflen, vb); break;
- case VBLK_PART:
- result = ldm_parse_part (buffer, buflen, vb); break;
- case VBLK_VOLU:
- result = ldm_parse_volu (buffer, buflen, vb); break;
- default:
- //printk(LDM_ERR "Unknown VBLK type 0x%02x.\n", vb->type);
- //result = FALSE; not nec
+ /* If this is part of a multipart vblk, we increase ref. count, and
+ add pointers to raw data */
+ if (vb->rec_count > 1) {
+ get_page (page); /* Inc ref. count */
+ vb->vblk.ext.page = page;
+ if (vb->rec_num == 0) {
+ vb->vblk.ext.data = buffer;
+ vb->vblk.ext.size = buflen;
+ } else {
+ vb->vblk.ext.data = buffer + 0x10; /* Skip header */
+ vb->vblk.ext.size = buflen - 0x10;
}
+ return TRUE;
+ }
- if (!result)
- printk (LDM_ERR "Failed to parse a VBLK of type "
- "0x%02x.\n", vb->type);
- else
- //ldm_debug ("Parsed VBLK #%llu (type: 0x%02x) ok.\n",
- ldm_debug ("Parsed VBLK 0x%llx (type: 0x%02x) ok.\n",
- (unsigned long long) vb->obj_id, vb->type);
-
- return result;
- }
-
- get_page (page); /* Increase the ref count */
- vb->vblk.ext.page = page;
- if (vb->rec_num == 0) {
- vb->vblk.ext.data = buffer;
- vb->vblk.ext.size = buflen;
- } else {
- vb->vblk.ext.data = buffer + 0x10;
- vb->vblk.ext.size = buflen - 0x10;
+ /* the vblk is in one fragment and ready for processing */
+ vb->flags = buffer[0x12];
+ vb->type = buffer[0x13];
+ vb->obj_id = ldm_get_vnum (buffer + 0x18);
+ ldm_get_vstr (buffer+0x19+buffer[0x18], vb->name, sizeof (vb->name));
+
+ switch (vb->type) {
+ case VBLK_COMP:
+ result = ldm_parse_comp (buffer, buflen, vb); break;
+ case VBLK_DSK1:
+ result = ldm_parse_disk (buffer, buflen, vb); break;
+ case VBLK_DSK2:
+ result = ldm_parse_disk2(buffer, buflen, vb); break;
+ case VBLK_DGR1:
+ result = ldm_parse_dgrp (buffer, buflen, vb); break;
+ case VBLK_DGR2:
+ result = ldm_parse_dgrp2(buffer, buflen, vb); break;
+ case VBLK_PART:
+ result = ldm_parse_part (buffer, buflen, vb); break;
+ case VBLK_VOLU:
+ result = ldm_parse_volu (buffer, buflen, vb); break;
+ default:
+ ldm_debug("Unknown VBLK type: 0x%02x.\n", vb->type);
+ result = FALSE;
}
- return TRUE;
+
+ if (!result)
+ printk (LDM_ERR "Failed to parse VBLK 0x%llx (type: 0x%02x).\n",
+ vb->obj_id, vb->type);
+ else
+ ldm_debug ("Parsed VBLK 0x%llx (type: 0x%02x) ok.\n",
+ (unsigned long long) vb->obj_id, vb->type);
+
+ return result;
}
@@ -1196,9 +1139,9 @@
* Place vblk in correct list by examining type.
* All extended vblk's are placed in a special list for later processing.
- * Some types gets sorted into it's list.
+ * Partitions and fragments is added in sorted order.
*
* Strange vblk's should've been removed in ldm_parse_vblk
+ * This function returns void because it currently can't fail.
*
- * FIXME return values? void none
*/
static void ldm_ldmdb_add(struct vblk *vb, struct ldmdb *ldb)
@@ -1206,9 +1149,7 @@
list_t *item;
- //FIXME ldm_debugs?
-
- /* If vb is part of a multiple-record vblk, we sort it into the pool */
- // FIXME sorted by group and recnum
- if (vb->rec_count != 1) {
+ /* If vb is part of a multiple-record vblk, we sort it into the pool by
+ group and record number */
+ if (vb->rec_count > 1) {
list_for_each (item, &ldb->v_extpool) {
struct vblk *v = list_entry (item, struct vblk, list);
@@ -1223,5 +1164,6 @@
}
- /* Put vblk into the correct list */
+ /* Put vblk into the correct list. A default case is not needed since
+ vb is already sanity-checked in ldm_parse_vblk() */
switch (vb->type) {
case VBLK_DGR1:
@@ -1251,8 +1193,4 @@
list_add_tail(&vb->list, &ldb->v_part);
return;
- /* This can't happen, gets checked in ldm_parse_vblk()!! */
- default:
- // FIXME BUG?
- return;
}
}
@@ -1272,9 +1210,9 @@
static int ldm_combine_vblks (struct ldmdb *ldb)
{
- struct vblk *vb = NULL;
+ struct vblk *vb;
list_t *item;
int rec, nrec, group;
u8 *data = NULL;
- u8 *tptr;
+ u8 *ptr;
if (list_empty(&ldb->v_extpool))
@@ -1286,23 +1224,20 @@
group = list_entry(ldb->v_extpool.next, struct vblk, list)->group;
- /* Sanity check records */
+ /* Count number of continuous fragments in first group found */
list_for_each (item, &ldb->v_extpool) {
struct vblk *v = list_entry (item, struct vblk, list);
- if (v->rec_num!=rec || v->rec_count!=nrec || v->group!=group) {
- // FIXME log? no, implies found next group
+ if (v->rec_num!=rec || v->rec_count!=nrec || v->group!=group)
break;
- }
rec++;
}
- /* Sanity check records */
- /* Remove from list if not sane */
+ /* If the number of continuous fragments in group isn't equal to the
+ expected number, we remove all fragments in the group from the list */
if (rec != nrec) {
ldm_debug("Group: %d (%d records) is corrupt\n", group, nrec);
list_for_each (item, &ldb->v_extpool) {
struct vblk *v = list_entry (item, struct vblk, list);
- if (v->group != group) {
+ if (v->group != group)
break;
- }
list_del(&v->list);
put_page(v->vblk.ext.page);/* Decrease the ref count */
@@ -1312,33 +1247,30 @@
}
- /* Allocate memory buffer */
- data = kmalloc (ldb->vm.vblk_size * nrec, GFP_KERNEL);
- if (!data) {
+ /* Allocate memory buffer to hold the concatenated data */
+ if ((data = kmalloc (ldb->vm.vblk_size * nrec, GFP_KERNEL)) == 0) {
printk (LDM_CRIT "Out of memory in combine vblks.\n");
return -1;
}
- /* Concatenate data */
- tptr = data;
+ /* The first fragment will become the new vblk entry */
+ vb = list_entry (ldb->v_extpool.next, struct vblk, list);
+
+ /* Concatenate data. Processed fragments are removed from list and
+ freed (except for the first one which we keep). */
+ ptr = data;
list_for_each (item, &ldb->v_extpool) {
struct vblk *v = list_entry (item, struct vblk, list);
- if (v->group != group) {
- // FIXME error condition? log?
- break;
- }
+ memcpy(ptr, v->vblk.ext.data, v->vblk.ext.size);
+ ptr += v->vblk.ext.size;
- memcpy(tptr, v->vblk.ext.data, v->vblk.ext.size);
- tptr += v->vblk.ext.size;
list_del(&v->list);
put_page(v->vblk.ext.page);/* Decrease the ref count */
- if (v->rec_num == 0)
- vb = v;
- else
+ if (v != vb)
kfree(v);
}
/* Add record to ldmdb */
- if (ldm_parse_vblk(data, (int)(tptr-data), vb, NULL, 1))
+ if (ldm_parse_vblk(data, (int)(ptr-data), vb, NULL, TRUE))
ldm_ldmdb_add(vb, ldb);
@@ -1379,5 +1311,5 @@
}
- /* Loop through every entry in sector */
+ /* Loop through all entries in sector */
for (i = 0; i < perbuf; i++) {
const u8 *block = data + i*ldb->vm.vblk_size;
@@ -1399,5 +1331,6 @@
}
- if (ldm_parse_vblk (block, ldb->vm.vblk_size, vl, sect.v, 0))
+ if (ldm_parse_vblk (block, ldb->vm.vblk_size,
+ vl, sect.v, FALSE))
ldm_ldmdb_add(vl, ldb);
@@ -1405,5 +1338,4 @@
}
- //FIXME any vblks we need will have addref'd the page
put_dev_sector(sect);
if (failed)
@@ -1412,6 +1344,8 @@
/* Combine and parse vblk entries with multiple records */
- while (ldm_combine_vblks(ldb) == 0);
- // FIXME doesn't bail out on failure
+ while ( (i = ldm_combine_vblks(ldb)) == 0 ) {}
+
+ if (i < 0) /* already logged */
+ return 0;
return TRUE;
@@ -1432,14 +1366,9 @@
{
list_t *item;
- struct vblk *vb;
-
- BUG_ON (!ldb);
list_for_each (item, &ldb->v_disk) {
- vb = list_entry (item, struct vblk, list);
- if (memcmp (vb->vblk.disk.disk_id, ldb->ph.disk_id, GUID_SIZE))
- continue;
-
- return vb;
+ struct vblk *v = list_entry (item, struct vblk, list);
+ if (!memcmp(v->vblk.disk.disk_id, ldb->ph.disk_id, GUID_SIZE))
+ return v;
}
@@ -1456,12 +1385,9 @@
{
list_t *item;
- struct vblk *vl;
- if (!lh_vl)
- return;
list_for_each (item, lh_vl) {
- vl = list_entry (item, struct vblk, list);
+ struct vblk *v = list_entry (item, struct vblk, list);
list_del (item);
- kfree (vl);
+ kfree (v);
}
}
@@ -1503,18 +1429,24 @@
return 0;
- /* Create the LDM database device. */
- if (!ldm_create_db_partition (hd, bdev, first_sector, first_minor, &ldb.ph))
- goto cleanup; /* Already logged */
+ /* Parse and check privheads. */
+ if (!ldm_validate_privheads (bdev, first_sector, &ldb.ph))
+ return -1;
/* All further references are relative to base (database start). */
- base = hd->part[first_minor].start_sect;
+ base = first_sector + ldb.ph.config_start;
+
+ /* Parse and check tocs and vmdb. */
+ if (!ldm_validate_tocblocks (bdev, base, &toc) ||
+ !ldm_validate_vmdb (bdev, base, &ldb.vm))
+ return -1;
- /* Parse and check: backup privheads; tables of contents; vmdb. */
- if ((!ldm_validate_privheads (bdev, base, &ldb.ph)) ||
- (!ldm_validate_tocblocks (bdev, base, &toc)) ||
- (!ldm_validate_vmdb (bdev, base, &ldb.vm)))
+#if 1
+ // FIXME: Why do we wan't this partition ??
+ /* Create the LDM database device. */
+ if (!ldm_create_partition (hd, first_minor++, base, ldb.ph.config_size))
goto cleanup;
+#endif
- /* Initialize vblk list in ldmdb struct */
+ /* Initialize vblk lists in ldmdb struct */
INIT_LIST_HEAD(&ldb.v_dgrp);
INIT_LIST_HEAD(&ldb.v_disk);
@@ -1536,5 +1468,5 @@
/* Finally, create the data partition devices. */
- if (ldm_create_data_partitions (hd, first_sector, first_minor + 1,
+ if (ldm_create_data_partitions (hd, first_sector, first_minor,
&ldb, disk)) {
ldm_debug ("Parsed LDM database successfully.\n");
|