hal/hald/linux/volume_id volume_id.c, 1.30, 1.31 volume_id.h, 1.17, 1.18

Kay Sievers kay at freedesktop.org
Mon Sep 13 08:11:44 PDT 2004


Update of /cvs/hal/hal/hald/linux/volume_id
In directory gabe:/tmp/cvs-serv26308/hald/linux/volume_id

Modified Files:
	volume_id.c volume_id.h 
Log Message:
2004-09-13  Kay Sievers  <kay.sievers at vrfy.org>

        * hald/linux/volume_id/volume_id.c: (probe_hfs_hfsplus): Add
          support for hfsplus with the physical location of the root node
          specified by a higher extent as the first one. This fixes
          the label reading on David's big hfsplus volume - I always
          expected that the volume was broken :)
          Also add initial support for hfs anf hfsplus uuid's.



Index: volume_id.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/volume_id/volume_id.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- volume_id.c	12 Sep 2004 09:49:28 -0000	1.30
+++ volume_id.c	13 Sep 2004 15:11:42 -0000	1.31
@@ -45,21 +45,21 @@
 #include "volume_id_logging.h"
 
 #define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \
-			   (((__u32)(x) & 0xff00u) >> 8))
+			   (((__u16)(x) & 0xff00u) >> 8))
 
 #define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \
 			   (((__u32)(x) & 0x00ff0000u) >>  8) | \
 			   (((__u32)(x) & 0x0000ff00u) <<  8) | \
 			   (((__u32)(x) & 0x000000ffu) << 24))
 
-#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000u) >> 56) | \
-			   (((__u64)(x) & 0x00ff000000000000u) >> 40) | \
-			   (((__u64)(x) & 0x0000ff0000000000u) >> 24) | \
-			   (((__u64)(x) & 0x000000ff00000000u) >>  8) | \
-			   (((__u64)(x) & 0x00000000ff000000u) <<  8) | \
-			   (((__u64)(x) & 0x0000000000ff0000u) << 24) | \
-			   (((__u64)(x) & 0x000000000000ff00u) << 40) | \
-			   (((__u64)(x) & 0x00000000000000ffu) << 56))
+#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000ull) >> 56) | \
+			   (((__u64)(x) & 0x00ff000000000000ull) >> 40) | \
+			   (((__u64)(x) & 0x0000ff0000000000ull) >> 24) | \
+			   (((__u64)(x) & 0x000000ff00000000ull) >>  8) | \
+			   (((__u64)(x) & 0x00000000ff000000ull) <<  8) | \
+			   (((__u64)(x) & 0x0000000000ff0000ull) << 24) | \
+			   (((__u64)(x) & 0x000000000000ff00ull) << 40) | \
+			   (((__u64)(x) & 0x00000000000000ffull) << 56))
 
 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
 #define le16_to_cpu(x) (x)
@@ -1472,16 +1472,25 @@
 #define HFS_SUPERBLOCK_OFFSET		0x400
 #define HFS_NODE_LEAF			0xff
 #define HFSPLUS_POR_CNID		1
+#define HFSPLUS_EXTENT_COUNT		8
 static int probe_hfs_hfsplus(struct volume_id *id, __u64 off)
 {
-	struct finder_info {
+	union hfs_uuid {
+		char id[8];
+		struct {
+			__u32 high;
+			__u32 low;
+		} __attribute__((__packed__)) v;
+	} __attribute__((__packed__));
+
+	struct hfs_finder_info{
 		__u32	boot_folder;
 		__u32	start_app;
 		__u32	open_folder;
 		__u32	os9_folder;
 		__u32	reserved;
 		__u32	osx_folder;
-		__u8	id[8];
+		union hfs_uuid uuid;
 	} __attribute__((__packed__));
 
 	struct hfs_mdb {
@@ -1508,7 +1517,7 @@
 		__u16	num_root_dirs;
 		__u32	file_count;
 		__u32	dir_count;
-		struct finder_info finfo;
+		struct hfs_finder_info finder_info;
 		__u8	embed_sig[2];
 		__u16	embed_startblock;
 		__u16	embed_blockcount;
@@ -1548,7 +1557,7 @@
 		__u64 total_size;
         	__u32 clump_size;
 		__u32 total_blocks;
-		struct hfsplus_extent extents[8];
+		struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
 	} __attribute__((__packed__));
 
 	struct hfsplus_vol_header {
@@ -1572,7 +1581,7 @@
 		__u32	next_cnid;
 		__u32	write_count;
 		__u64	encodings_bmp;
-		struct finder_info finfo;
+		struct hfs_finder_info finder_info;
 		struct hfsplus_fork alloc_file;
 		struct hfsplus_fork ext_file;
 		struct hfsplus_fork cat_file;
@@ -1580,16 +1589,21 @@
 		struct hfsplus_fork start_file;
 	} __attribute__((__packed__)) *hfsplus;
 
+	union hfs_uuid uuid;
 	unsigned int blocksize;
 	unsigned int cat_block;
-	unsigned int cat_block_count;
-	unsigned int cat_off;
-	unsigned int cat_len;
+	unsigned int ext_block_start;
+	unsigned int ext_block_count;
+	int ext;
 	unsigned int leaf_node_head;
+	unsigned int leaf_node_count;
 	unsigned int leaf_node_size;
+	unsigned int leaf_block;
+	__u64 leaf_off;
 	unsigned int alloc_block_size;
 	unsigned int alloc_first_block;
 	unsigned int embed_first_block;
+	unsigned int record_count;
 	struct hfsplus_bnode_descriptor *descr;
 	struct hfsplus_bheader_record *bnode;
 	struct hfsplus_catalog_key *key;
@@ -1630,6 +1644,11 @@
 		set_label_string(id, hfs->label, hfs->label_len) ;
 	}
 
+	/* convert big endian numbers to byte array (little endian)*/
+	uuid.v.high = bswap32(hfs->finder_info.uuid.v.high);
+	uuid.v.low = bswap32(hfs->finder_info.uuid.v.low);
+	set_uuid(id, uuid.id, 8);
+
 	id->usage_id = VOLUME_ID_FILESYSTEM;
 	id->type_id = VOLUME_ID_HFS;
 	id->type = "hfs";
@@ -1645,14 +1664,18 @@
 	return -1;
 
 hfsplus:
+	/* convert big endian numbers to byte array (little endian)*/
+	uuid.v.high = bswap32(hfsplus->finder_info.uuid.v.high);
+	uuid.v.low = bswap32(hfsplus->finder_info.uuid.v.low);
+	set_uuid(id, uuid.id, 8);
+
 	blocksize = be32_to_cpu(hfsplus->blocksize);
+	dbg("blocksize %u", blocksize);
+
 	cat_block = be32_to_cpu(hfsplus->cat_file.extents[0].start_block);
-	cat_block_count = be32_to_cpu(hfsplus->cat_file.extents[0].block_count);
-	cat_off = (cat_block * blocksize);
-	cat_len = cat_block_count * blocksize;
-	dbg("catalog start 0x%llx, len 0x%x", off + cat_off, cat_len);
+	dbg("catalog start block 0x%x", cat_block);
 
-	buf = get_buffer(id, off + cat_off, 0x2000);
+	buf = get_buffer(id, off + (cat_block * blocksize), 0x2000);
 	if (buf == NULL)
 		goto found;
 
@@ -1660,18 +1683,51 @@
 		&buf[sizeof(struct hfsplus_bnode_descriptor)];
 
 	leaf_node_head = be32_to_cpu(bnode->leaf_head);
+	dbg("catalog leaf node 0x%x", leaf_node_head);
+
 	leaf_node_size = be16_to_cpu(bnode->node_size);
+	dbg("leaf node size 0x%x", leaf_node_size);
 
-	dbg("catalog leaf node 0x%x, size 0x%x",
-	    leaf_node_head, leaf_node_size);
+	leaf_node_count = be32_to_cpu(bnode->leaf_count);
+	dbg("leaf node count 0x%x", leaf_node_count);
+	if (leaf_node_count == 0)
+		goto found;
 
-	buf = get_buffer(id, off + cat_off + (leaf_node_head * leaf_node_size),
-			 leaf_node_size);
+	leaf_block = (leaf_node_head * leaf_node_size) / blocksize;
+
+	/* get physical location */
+	for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) {
+		ext_block_start = be32_to_cpu(hfsplus->cat_file.extents[ext].start_block);
+		ext_block_count = be32_to_cpu(hfsplus->cat_file.extents[ext].block_count);
+		dbg("extent start block 0x%x, count 0x%x", ext_block_start, ext_block_count);
+
+		if (ext_block_count == 0)
+			goto found;
+
+		/* this is our extent */
+		if (leaf_block < ext_block_count)
+			break;
+
+		leaf_block -= ext_block_count;
+	}
+	if (ext == HFSPLUS_EXTENT_COUNT)
+		goto found;
+	dbg("found block in extent %i", ext);
+
+	leaf_off = (ext_block_start + leaf_block) * blocksize;
+
+	buf = get_buffer(id, off + leaf_off, leaf_node_size);
 	if (buf == NULL)
 		goto found;
 
 	descr = (struct hfsplus_bnode_descriptor *) buf;
 	dbg("descriptor type 0x%x", descr->type);
+
+	record_count = be16_to_cpu(descr->num_recs);
+	dbg("number of records %u", record_count);
+	if (record_count == 0)
+		goto found;
+
 	if (descr->type != HFS_NODE_LEAF)
 		goto found;
 

Index: volume_id.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux/volume_id/volume_id.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- volume_id.h	30 Aug 2004 15:13:17 -0000	1.17
+++ volume_id.h	13 Sep 2004 15:11:42 -0000	1.18
@@ -21,7 +21,7 @@
 #ifndef _VOLUME_ID_H_
 #define _VOLUME_ID_H_
 
-#define VOLUME_ID_VERSION		022
+#define VOLUME_ID_VERSION		023
 
 #define VOLUME_ID_LABEL_SIZE		64
 #define VOLUME_ID_UUID_SIZE		16




More information about the hal-commit mailing list