hal/hald/linux/volume_id volume_id.c,1.12,1.13 volume_id.h,1.4,1.5
David Zeuthen
david at pdx.freedesktop.org
Sat Jul 10 07:52:21 PDT 2004
Update of /cvs/hal/hal/hald/linux/volume_id
In directory pdx:/tmp/cvs-serv26381/hald/linux/volume_id
Modified Files:
volume_id.c volume_id.h
Log Message:
2004-07-10 David Zeuthen <david at fubar.dk>
Patch from Kay Sievers <kay.sievers at vrfy.org>.
* hald/linux/volume_id/volume_id.[ch]: Update to discover hfs
wrapped hfs+ partitions, mac_partition_maps and udf
Index: volume_id.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/volume_id/volume_id.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- volume_id.c 6 Jul 2004 17:07:08 -0000 1.12
+++ volume_id.c 10 Jul 2004 14:52:19 -0000 1.13
@@ -726,9 +726,213 @@
return 0;
}
+#define UFS_MAGIC 0x00011954
+#define UFS2_MAGIC 0x19540119
+#define UFS_MAGIC_FEA 0x00195612
+#define UFS_MAGIC_LFN 0x00095014
+
+
+static int probe_ufs(struct volume_id *id)
+{
+ struct ufs_super_block {
+ __u32 fs_link;
+ __u32 fs_rlink;
+ __u32 fs_sblkno;
+ __u32 fs_cblkno;
+ __u32 fs_iblkno;
+ __u32 fs_dblkno;
+ __u32 fs_cgoffset;
+ __u32 fs_cgmask;
+ __u32 fs_time;
+ __u32 fs_size;
+ __u32 fs_dsize;
+ __u32 fs_ncg;
+ __u32 fs_bsize;
+ __u32 fs_fsize;
+ __u32 fs_frag;
+ __u32 fs_minfree;
+ __u32 fs_rotdelay;
+ __u32 fs_rps;
+ __u32 fs_bmask;
+ __u32 fs_fmask;
+ __u32 fs_bshift;
+ __u32 fs_fshift;
+ __u32 fs_maxcontig;
+ __u32 fs_maxbpg;
+ __u32 fs_fragshift;
+ __u32 fs_fsbtodb;
+ __u32 fs_sbsize;
+ __u32 fs_csmask;
+ __u32 fs_csshift;
+ __u32 fs_nindir;
+ __u32 fs_inopb;
+ __u32 fs_nspf;
+ __u32 fs_optim;
+ __u32 fs_npsect_state;
+ __u32 fs_interleave;
+ __u32 fs_trackskew;
+ __u32 fs_id[2];
+ __u32 fs_csaddr;
+ __u32 fs_cssize;
+ __u32 fs_cgsize;
+ __u32 fs_ntrak;
+ __u32 fs_nsect;
+ __u32 fs_spc;
+ __u32 fs_ncyl;
+ __u32 fs_cpg;
+ __u32 fs_ipg;
+ __u32 fs_fpg;
+ struct ufs_csum {
+ __u32 cs_ndir;
+ __u32 cs_nbfree;
+ __u32 cs_nifree;
+ __u32 cs_nffree;
+ } __attribute__((__packed__)) fs_cstotal;
+ __s8 fs_fmod;
+ __s8 fs_clean;
+ __s8 fs_ronly;
+ __s8 fs_flags;
+ union {
+ struct {
+ __s8 fs_fsmnt[512];
+ __u32 fs_cgrotor;
+ __u32 fs_csp[31];
+ __u32 fs_maxcluster;
+ __u32 fs_cpc;
+ __u16 fs_opostbl[16][8];
+ } __attribute__((__packed__)) fs_u1;
+ struct {
+ __s8 fs_fsmnt[468];
+ __u8 fs_volname[32];
+ __u64 fs_swuid;
+ __s32 fs_pad;
+ __u32 fs_cgrotor;
+ __u32 fs_ocsp[28];
+ __u32 fs_contigdirs;
+ __u32 fs_csp;
+ __u32 fs_maxcluster;
+ __u32 fs_active;
+ __s32 fs_old_cpc;
+ __s32 fs_maxbsize;
+ __s64 fs_sparecon64[17];
+ __s64 fs_sblockloc;
+ struct ufs2_csum_total {
+ __u64 cs_ndir;
+ __u64 cs_nbfree;
+ __u64 cs_nifree;
+ __u64 cs_nffree;
+ __u64 cs_numclusters;
+ __u64 cs_spare[3];
+ } __attribute__((__packed__)) fs_cstotal;
+ struct ufs_timeval {
+ __s32 tv_sec;
+ __s32 tv_usec;
+ } __attribute__((__packed__)) fs_time;
+ __s64 fs_size;
+ __s64 fs_dsize;
+ __u64 fs_csaddr;
+ __s64 fs_pendingblocks;
+ __s32 fs_pendinginodes;
+ } __attribute__((__packed__)) fs_u2;
+ } fs_u11;
+ union {
+ struct {
+ __s32 fs_sparecon[53];
+ __s32 fs_reclaim;
+ __s32 fs_sparecon2[1];
+ __s32 fs_state;
+ __u32 fs_qbmask[2];
+ __u32 fs_qfmask[2];
+ } __attribute__((__packed__)) fs_sun;
+ struct {
+ __s32 fs_sparecon[53];
+ __s32 fs_reclaim;
+ __s32 fs_sparecon2[1];
+ __u32 fs_npsect;
+ __u32 fs_qbmask[2];
+ __u32 fs_qfmask[2];
+ } __attribute__((__packed__)) fs_sunx86;
+ struct {
+ __s32 fs_sparecon[50];
+ __s32 fs_contigsumsize;
+ __s32 fs_maxsymlinklen;
+ __s32 fs_inodefmt;
+ __u32 fs_maxfilesize[2];
+ __u32 fs_qbmask[2];
+ __u32 fs_qfmask[2];
+ __s32 fs_state;
+ } __attribute__((__packed__)) fs_44;
+ } fs_u2;
+ __s32 fs_postblformat;
+ __s32 fs_nrpos;
+ __s32 fs_postbloff;
+ __s32 fs_rotbloff;
+ __u32 fs_magic;
+ __u8 fs_space[1];
+ } __attribute__((__packed__)) *ufs;
+
+ __u32 magic;
+ int i;
+ int offsets[] = {0, 8, 64, 256, -1};
+
+ for (i = 0; offsets[i] >= 0; i++) {
+ ufs = (struct ufs_super_block *)
+ get_buffer(id, offsets[i] * 0x400, 0x800);
+ if (ufs == NULL)
+ return -1;
+
+ dbg("offset 0x%x", offsets[i] * 0x400);
+ magic = be32_to_cpu(ufs->fs_magic);
+ if ((magic == UFS_MAGIC) ||
+ (magic == UFS2_MAGIC) ||
+ (magic == UFS_MAGIC_FEA) ||
+ (magic == UFS_MAGIC_LFN)) {
+ dbg("magic 0x%08x(be)", magic);
+ goto found;
+ }
+ magic = le32_to_cpu(ufs->fs_magic);
+ if ((magic == UFS_MAGIC) ||
+ (magic == UFS2_MAGIC) ||
+ (magic == UFS_MAGIC_FEA) ||
+ (magic == UFS_MAGIC_LFN)) {
+ dbg("magic 0x%08x(le)", magic);
+ goto found;
+ }
+ }
+ return -1;
+
+found:
+ id->fs_type = UFS;
+ id->fs_name = "ufs";
+
+ return 0;
+}
+
+
#define HFS_SUPERBLOCK_OFFSET 0x400
-static int probe_hfs(struct volume_id *id)
+#define HFS_NODE_LEAF 0xff
+#define HFSPLUS_POR_CNID 1
+static int probe_hfs_hfsplus(struct volume_id *id)
{
+ struct mac_partition {
+ __u8 signature[2];
+ __u16 res1;
+ __u32 map_count;
+ __u32 start_block;
+ __u32 block_count;
+ __u8 name[32];
+ } __attribute__((__packed__)) *part;
+
+ struct finder_info {
+ __u32 boot_folder;
+ __u32 start_app;
+ __u32 open_folder;
+ __u32 os9_folder;
+ __u32 reserved;
+ __u32 osx_folder;
+ __u8 id[8];
+ } __attribute__((__packed__));
+
struct hfs_mdb {
__u8 signature[2];
__u32 cr_date;
@@ -753,42 +957,12 @@
__u16 num_root_dirs;
__u32 file_count;
__u32 dir_count;
- struct finder_info {
- __u32 boot_folder;
- __u32 start_app;
- __u32 open_folder;
- __u32 os9_folder;
- __u32 reserved;
- __u32 osx_folder;
- __u8 id[8];
- } __attribute__((__packed__)) finfo;
-
+ struct finder_info finfo;
+ __u8 embed_sig[2];
+ __u16 embed_startblock;
+ __u16 embed_blockcount;
} __attribute__((__packed__)) *hfs;
- hfs = (struct hfs_mdb *) get_buffer(id, HFS_SUPERBLOCK_OFFSET, 0x200);
- if (hfs == NULL)
- return -1;
-
- if (strncmp(hfs->signature, "BD", 2) != 0)
- return -1;
-
- if (hfs->label_len > 0 && hfs->label_len < 28) {
- set_label_raw(id, hfs->label, hfs->label_len);
- set_label_string(id, hfs->label, hfs->label_len) ;
- }
-
- set_uuid(id, hfs->finfo.id, 8);
-
- id->fs_type = HFS;
- id->fs_name = "hfs";
-
- return 0;
-}
-
-#define HFS_NODE_LEAF 0xff
-#define HFSPLUS_POR_CNID 1
-static int probe_hfsplus(struct volume_id *id)
-{
struct hfsplus_bnode_descriptor {
__u32 next;
__u32 prev;
@@ -847,15 +1021,7 @@
__u32 next_cnid;
__u32 write_count;
__u64 encodings_bmp;
- struct finder_info {
- __u32 boot_folder;
- __u32 start_app;
- __u32 open_folder;
- __u32 os9_folder;
- __u32 reserved;
- __u32 osx_folder;
- __u8 id[8];
- } __attribute__((__packed__)) finfo;
+ struct finder_info finfo;
struct hfsplus_fork alloc_file;
struct hfsplus_fork ext_file;
struct hfsplus_fork cat_file;
@@ -870,28 +1036,80 @@
unsigned int cat_len;
unsigned int leaf_node_head;
unsigned int leaf_node_size;
+ unsigned int alloc_block_size;
+ unsigned int alloc_first_block;
+ unsigned int embed_first_block;
+ unsigned int embed_off = 0;
struct hfsplus_bnode_descriptor *descr;
struct hfsplus_bheader_record *bnode;
struct hfsplus_catalog_key *key;
unsigned int label_len;
const __u8 *buf;
- hfsplus = (struct hfsplus_vol_header *)
- get_buffer(id, HFS_SUPERBLOCK_OFFSET, 0x200);
- if (hfsplus == NULL)
+ buf = get_buffer(id, 0, 0x200);
+ if (buf == NULL)
+ return -1;
+
+ part = (struct mac_partition *) buf;
+ if ((strncmp(part->signature, "PM", 2) == 0) &&
+ (strncmp(part->name, "Apple", 5) == 0)) {
+ id->fs_type = MACPARTMAP;
+ id->fs_name = "mac_partition_map";
+ return 0;
+ }
+
+ buf = get_buffer(id, HFS_SUPERBLOCK_OFFSET, 0x200);
+ if (buf == NULL)
return -1;
+ hfs = (struct hfs_mdb *) buf;
+ if (strncmp(hfs->signature, "BD", 2) != 0)
+ goto checkplus;
+
+ /* it may be just a hfs wrapper for hfs+ */
+ if (strncmp(hfs->embed_sig, "H+", 2) == 0) {
+ alloc_block_size = be32_to_cpu(hfs->al_blk_size);
+ dbg("alloc_block_size 0x%x", alloc_block_size);
+
+ alloc_first_block = be16_to_cpu(hfs->al_bl_st);
+ dbg("alloc_first_block 0x%x", alloc_first_block);
+
+ embed_first_block = be16_to_cpu(hfs->embed_startblock);
+ dbg("embed_first_block 0x%x", embed_first_block);
+
+ embed_off = (alloc_first_block * 512) +
+ (embed_first_block * alloc_block_size);
+ dbg("hfs wrapped hfs+ found at offset 0x%x", embed_off);
+
+ buf = get_buffer(id, embed_off + HFS_SUPERBLOCK_OFFSET, 0x200);
+ if (buf == NULL)
+ return -1;
+ goto checkplus;
+ }
+
+ if (hfs->label_len > 0 && hfs->label_len < 28) {
+ set_label_raw(id, hfs->label, hfs->label_len);
+ set_label_string(id, hfs->label, hfs->label_len) ;
+ }
+
+ id->fs_type = HFS;
+ id->fs_name = "hfs";
+
+ return 0;
+
+checkplus:
+ hfsplus = (struct hfsplus_vol_header *) buf;
if (strncmp(hfsplus->signature, "H+", 2) == 0)
- goto label;
+ goto hfsplus;
if (strncmp(hfsplus->signature, "HX", 2) == 0)
- goto label;
+ goto hfsplus;
return -1;
-label:
+hfsplus:
blocksize = be32_to_cpu(hfsplus->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_off = (cat_block * blocksize) + embed_off;
cat_len = cat_block_count * blocksize;
dbg("catalog start 0x%x, len 0x%x", cat_off, cat_len);
@@ -1151,10 +1369,12 @@
rc = probe_iso9660(id);
break;
case HFS:
- rc = probe_hfs(id);
- break;
case HFSPLUS:
- rc = probe_hfsplus(id);
+ case MACPARTMAP:
+ rc = probe_hfs_hfsplus(id);
+ break;
+ case UFS:
+ rc = probe_ufs(id);
break;
case NTFS:
rc = probe_ntfs(id);
@@ -1199,10 +1419,10 @@
rc = probe_ntfs(id);
if (rc == 0)
break;
- rc = probe_hfsplus(id);
+ rc = probe_hfs_hfsplus(id);
if (rc == 0)
break;
- rc = probe_hfs(id);
+ rc = probe_ufs(id);
if (rc == 0)
break;
rc = -1;
Index: volume_id.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux/volume_id/volume_id.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- volume_id.h 5 Jul 2004 19:27:25 -0000 1.4
+++ volume_id.h 10 Jul 2004 14:52:19 -0000 1.5
@@ -31,6 +31,7 @@
enum filesystem_type {
ALL,
+ SWAP,
EXT2,
EXT3,
REISER,
@@ -43,7 +44,8 @@
NTFS,
HFS,
HFSPLUS,
- SWAP
+ MACPARTMAP,
+ UFS
};
struct volume_id {
More information about the hal-commit
mailing list