*/
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
-#include <stdlib.h>
#include <stdio.h>
-#include <string.h>
+#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <asm/types.h>
#include "volume_id.h"
-
-#ifdef DEBUG
-#define dbg(format, arg...) \
- do { \
- printf("%s: " format "\n", __FUNCTION__ , ## arg); \
- } while (0)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif /* DEBUG */
+#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)
/* size of superblock buffer, reiserfs block is at 64k */
#define SB_BUFFER_SIZE 0x11000
/* size of seek buffer 4k */
-#define SEEK_BUFFER_SIZE 0x1000
+#define SEEK_BUFFER_SIZE 0x10000
static void set_label_raw(struct volume_id *id,
}
}
-static void set_uuid(struct volume_id *id,
- const __u8 *buf, unsigned int count)
+enum uuid_format {
+ UUID_DCE,
+ UUID_DOS,
+ UUID_NTFS,
+ UUID_HFS,
+};
+
+static void set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format)
{
unsigned int i;
+ unsigned int count = 0;
+ switch(format) {
+ case UUID_DOS:
+ count = 4;
+ break;
+ case UUID_NTFS:
+ case UUID_HFS:
+ count = 8;
+ break;
+ case UUID_DCE:
+ count = 16;
+ }
memcpy(id->uuid_raw, buf, count);
- /* create string if uuid is set */
+ /* if set, create string in the same format, the native platform uses */
for (i = 0; i < count; i++)
if (buf[i] != 0)
goto set;
return;
set:
- switch(count) {
- case 4:
+ switch(format) {
+ case UUID_DOS:
sprintf(id->uuid, "%02X%02X-%02X%02X",
buf[3], buf[2], buf[1], buf[0]);
break;
- case 8:
- sprintf(id->uuid,"%02X%02X-%02X%02X-%02X%02X-%02X%02X",
+ case UUID_NTFS:
+ sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X",
buf[7], buf[6], buf[5], buf[4],
buf[3], buf[2], buf[1], buf[0]);
break;
- case 16:
+ case UUID_HFS:
+ sprintf(id->uuid,"%02X%02X%02X%02X%02X%02X%02X%02X",
+ buf[0], buf[1], buf[2], buf[3],
+ buf[4], buf[5], buf[6], buf[7]);
+ break;
+ case UUID_DCE:
sprintf(id->uuid,
- "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
- "%02x%02x%02x%02x%02x%02x",
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5],
buf[6], buf[7],
return &(id->sbbuf[off]);
} else {
- if (len > SEEK_BUFFER_SIZE)
- len = SEEK_BUFFER_SIZE;
+ if (len > SEEK_BUFFER_SIZE) {
+ dbg("seek buffer too small %d", SEEK_BUFFER_SIZE);
+ return NULL;
+ }
/* get seek buffer */
if (id->seekbuf == NULL) {
}
/* check if we need to read */
- if ((off < id->seekbuf_off) ||
- ((off + len) > (id->seekbuf_off + id->seekbuf_len))) {
+ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) {
dbg("read seekbuf off:0x%llx len:0x%x", off, len);
if (lseek(id->fd, off, SEEK_SET) == -1)
return NULL;
dbg("got 0x%x (%i) bytes", buf_len, buf_len);
id->seekbuf_off = off;
id->seekbuf_len = buf_len;
- if (buf_len < len)
+ if (buf_len < len) {
+ dbg("requested 0x%x bytes, got only 0x%x bytes", len, buf_len);
return NULL;
+ }
}
return &(id->seekbuf[off - id->seekbuf_off]);
}
}
+#define HPT37X_CONFIG_OFF 0x1200
+#define HPT37X_MAGIC_OK 0x5a7816f0
+#define HPT37X_MAGIC_BAD 0x5a7816fd
+static int probe_highpoint_ataraid(struct volume_id *id, __u64 off)
+{
+ struct hpt37x {
+ __u8 filler1[32];
+ __u32 magic;
+ __u32 magic_0;
+ __u32 magic_1;
+ } __attribute__((packed)) *hpt;
+
+ const __u8 *buf;
+
+ buf = get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200);
+ if (buf == NULL)
+ return -1;
+
+ hpt = (struct hpt37x *) buf;
+
+ if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD)
+ return -1;
+
+ id->usage_id = VOLUME_ID_RAID;
+ id->type_id = VOLUME_ID_HPTRAID;
+ id->type = "hpt_ataraid_member";
+
+ return 0;
+}
+
#define LVM1_SB_OFF 0x400
#define LVM1_MAGIC "HM"
static int probe_lvm1(struct volume_id *id, __u64 off)
found:
strncpy(id->type_version, lvm->type, 8);
id->usage_id = VOLUME_ID_RAID;
- id->type_id = VOLUME_ID_LVM1;
+ id->type_id = VOLUME_ID_LVM2;
id->type = "LVM2_member";
return 0;
} __attribute__((packed)) *mdp;
const __u8 *buf;
- __u64 sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES;
+ __u64 sboff;
__u8 uuid[16];
if (size < 0x10000)
return -1;
+ sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES;
buf = get_buffer(id, off + sboff, 0x800);
if (buf == NULL)
return -1;
memcpy(uuid, &mdp->set_uuid0, 4);
memcpy(&uuid[4], &mdp->set_uuid1, 12);
- set_uuid(id, uuid, 16);
+ set_uuid(id, uuid, UUID_DCE);
snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u",
le32_to_cpu(mdp->major_version),
p = &id->partitions[i];
+ p->partition_type_raw = part[i].sys_ind;
+
if (is_extended(part[i].sys_ind)) {
dbg("found extended partition at 0x%llx", poff);
p->usage_id = VOLUME_ID_PARTITIONTABLE;
p->off = current + poff;
p->len = plen;
id->partition_count++;
+
+ p->partition_type_raw = part[i].sys_ind;
+
if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) {
- dbg("to many partitions");
+ dbg("too many partitions");
next = 0;
}
}
set_label_raw(id, es->volume_name, 16);
set_label_string(id, es->volume_name, 16);
- set_uuid(id, es->uuid, 16);
+ set_uuid(id, es->uuid, UUID_DCE);
if ((le32_to_cpu(es->feature_compat) &
EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) {
found:
set_label_raw(id, rs->label, 16);
set_label_string(id, rs->label, 16);
- set_uuid(id, rs->uuid, 16);
+ set_uuid(id, rs->uuid, UUID_DCE);
id->usage_id = VOLUME_ID_FILESYSTEM;
id->type_id = VOLUME_ID_REISERFS;
set_label_raw(id, xs->fname, 12);
set_label_string(id, xs->fname, 12);
- set_uuid(id, xs->uuid, 16);
+ set_uuid(id, xs->uuid, UUID_DCE);
id->usage_id = VOLUME_ID_FILESYSTEM;
id->type_id = VOLUME_ID_XFS;
set_label_raw(id, js->label, 16);
set_label_string(id, js->label, 16);
- set_uuid(id, js->uuid, 16);
+ set_uuid(id, js->uuid, UUID_DCE);
id->usage_id = VOLUME_ID_FILESYSTEM;
id->type_id = VOLUME_ID_JFS;
#define FAT12_MAX 0xff5
#define FAT16_MAX 0xfff5
-#define FAT_ATTR_VOLUME 0x08
-struct vfat_dir_entry {
- __u8 name[11];
- __u8 attr;
- __u16 time_creat;
- __u16 date_creat;
- __u16 time_acc;
- __u16 date_acc;
- __u16 cluster_high;
- __u16 time_write;
- __u16 date_write;
- __u16 cluster_low;
- __u32 size;
-} __attribute__((__packed__));
-
-static char *vfat_search_label_in_dir(const __u8 *buf, __u16 size)
-{
- struct vfat_dir_entry *dir;
- int i;
- __u16 count;
-
- dir = (struct vfat_dir_entry*) buf;
- count = size / sizeof(struct vfat_dir_entry);
- dbg("expected entries 0x%x", count);
-
- for (i = 0; i <= count; i++) {
- /* end marker */
- if (dir[i].attr == 0x00) {
- dbg("end of dir");
- return NULL;
- }
-
- /* empty entry */
- if (dir[i].attr == 0xe5)
- continue;
-
- if (dir[i].attr == FAT_ATTR_VOLUME) {
- dbg("found ATTR_VOLUME id in root dir");
- return dir[i].name;
- }
-
- dbg("skip dir entry");
- }
-
- return NULL;
-}
-
+#define FAT_ATTR_VOLUME_ID 0x08
+#define FAT_ATTR_DIR 0x10
+#define FAT_ENTRY_FREE 0xe5
static int probe_vfat(struct volume_id *id, __u64 off)
{
struct vfat_super_block {
} __attribute__((__packed__)) type;
} __attribute__((__packed__)) *vs;
+ struct vfat_dir_entry {
+ __u8 name[11];
+ __u8 attr;
+ __u16 time_creat;
+ __u16 date_creat;
+ __u16 time_acc;
+ __u16 date_acc;
+ __u16 cluster_high;
+ __u16 time_write;
+ __u16 date_write;
+ __u16 cluster_low;
+ __u32 size;
+ } __attribute__((__packed__)) *dir;
+
__u16 sector_size;
__u16 dir_entries;
__u32 sect_count;
__u16 reserved;
- __u16 fat_size;
+ __u32 fat_size;
__u32 root_cluster;
__u32 dir_size;
__u32 cluster_count;
__u32 buf_size;
__u8 *label = NULL;
__u32 next;
+ int maxloop;
+ int i;
vs = (struct vfat_super_block *) get_buffer(id, off, 0x200);
if (vs == NULL)
sect_count = le16_to_cpu(vs->sectors);
if (sect_count == 0)
- sect_count = vs->total_sect;
+ sect_count = le32_to_cpu(vs->total_sect);
dbg("sect_count 0x%x", sect_count);
fat_length = le16_to_cpu(vs->fat_length);
/* the label may be an attribute in the root directory */
root_start = (reserved + fat_size) * sector_size;
+ dbg("root dir start 0x%llx", root_start);
root_dir_entries = le16_to_cpu(vs->dir_entries);
- dbg("root dir start 0x%x", root_start);
+ dbg("expected entries 0x%x", root_dir_entries);
buf_size = root_dir_entries * sizeof(struct vfat_dir_entry);
buf = get_buffer(id, off + root_start, buf_size);
if (buf == NULL)
goto found;
- label = vfat_search_label_in_dir(buf, buf_size);
+ dir = (struct vfat_dir_entry*) buf;
+
+ for (i = 0; i <= root_dir_entries; i++) {
+ /* end marker */
+ if (dir[i].name[0] == 0x00) {
+ dbg("end of dir");
+ break;
+ }
+
+ /* empty entry */
+ if (dir[i].name[0] == FAT_ENTRY_FREE)
+ continue;
+
+ if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) {
+ dbg("found ATTR_VOLUME_ID id in root dir");
+ label = dir[i].name;
+ break;
+ }
+
+ dbg("skip dir entry");
+ }
if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) {
set_label_raw(id, label, 11);
set_label_raw(id, vs->type.fat.label, 11);
set_label_string(id, vs->type.fat.label, 11);
}
- set_uuid(id, vs->type.fat.serno, 4);
+ set_uuid(id, vs->type.fat.serno, UUID_DOS);
goto found;
fat32:
start_data_sect = reserved + fat_size;
next = root_cluster;
- while (1) {
+ maxloop = 100;
+ while (--maxloop) {
__u32 next_sect_off;
__u64 next_off;
__u64 fat_entry_off;
+ int count;
dbg("next cluster %u", next);
next_sect_off = (next - 2) * vs->sectors_per_cluster;
next_off = (start_data_sect + next_sect_off) * sector_size;
- dbg("cluster offset 0x%x", next_off);
+ dbg("cluster offset 0x%llx", next_off);
/* get cluster */
buf = get_buffer(id, off + next_off, buf_size);
if (buf == NULL)
goto found;
- label = vfat_search_label_in_dir(buf, buf_size);
- if (label != NULL)
- break;
+ dir = (struct vfat_dir_entry*) buf;
+ count = buf_size / sizeof(struct vfat_dir_entry);
+ dbg("expected entries 0x%x", count);
+
+ for (i = 0; i <= count; i++) {
+ /* end marker */
+ if (dir[i].name[0] == 0x00) {
+ dbg("end of dir");
+ goto fat32_label;
+ }
+
+ /* empty entry */
+ if (dir[i].name[0] == FAT_ENTRY_FREE)
+ continue;
+
+ if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) {
+ dbg("found ATTR_VOLUME_ID id in root dir");
+ label = dir[i].name;
+ goto fat32_label;
+ }
+
+ dbg("skip dir entry");
+ }
/* get FAT entry */
fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32));
if (next == 0)
break;
}
+ if (maxloop == 0)
+ dbg("reached maximum follow count of root cluster chain, give up");
+fat32_label:
if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) {
set_label_raw(id, label, 11);
set_label_string(id, label, 11);
- } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) == 0) {
+ } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) != 0) {
set_label_raw(id, vs->type.fat32.label, 11);
set_label_string(id, vs->type.fat32.label, 11);
}
- set_uuid(id, vs->type.fat32.serno, 4);
+ set_uuid(id, vs->type.fat32.serno, UUID_DOS);
found:
id->usage_id = VOLUME_ID_FILESYSTEM;
}
#define ISO_SUPERBLOCK_OFFSET 0x8000
+#define ISO_SECTOR_SIZE 0x800
+#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE)
+#define ISO_VD_PRIMARY 0x1
+#define ISO_VD_SUPPLEMENTARY 0x2
+#define ISO_VD_END 0xff
+#define ISO_VD_MAX 16
static int probe_iso9660(struct volume_id *id, __u64 off)
{
union iso_super_block {
return -1;
if (strncmp(is->iso.id, "CD001", 5) == 0) {
- set_label_raw(id, is->iso.volume_id, 32);
- set_label_string(id, is->iso.volume_id, 32);
+ int vd_offset;
+ int i;
+ int found_svd;
+
+ found_svd = 0;
+ vd_offset = ISO_VD_OFFSET;
+ for (i = 0; i < ISO_VD_MAX; i++) {
+ is = (union iso_super_block *)
+ get_buffer (id, off + vd_offset, 0x200);
+ if (is == NULL || is->iso.type == ISO_VD_END)
+ break;
+ if (is->iso.type == ISO_VD_SUPPLEMENTARY) {
+ dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset);
+ found_svd = 1;
+ break;
+ }
+ vd_offset += ISO_SECTOR_SIZE;
+ }
+
+ if (!found_svd) {
+ is = (union iso_super_block *)
+ get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200);
+ if (is == NULL)
+ return -1;
+ set_label_raw(id, is->iso.volume_id, 32);
+ set_label_string(id, is->iso.volume_id, 32);
+ } else {
+ set_label_raw(id, is->iso.volume_id, 32);
+ set_label_unicode16(id, is->iso.volume_id, BE, 32);
+ }
goto found;
}
if (strncmp(is->hs.id, "CDROM", 5) == 0)
#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 {
+ struct hfs_finder_info{
__u32 boot_folder;
__u32 start_app;
__u32 open_folder;
__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;
__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 {
__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;
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;
unsigned int label_len;
+ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
const __u8 *buf;
buf = get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200);
set_label_string(id, hfs->label, hfs->label_len) ;
}
+ set_uuid(id, hfs->finder_info.id, UUID_HFS);
+
id->usage_id = VOLUME_ID_FILESYSTEM;
id->type_id = VOLUME_ID_HFS;
id->type = "hfs";
return -1;
hfsplus:
+ set_uuid(id, hfsplus->finder_info.id, UUID_HFS);
+
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_len = cat_block_count * blocksize;
- dbg("catalog start 0x%llx, len 0x%x", off + cat_off, cat_len);
+ dbg("blocksize %u", blocksize);
- buf = get_buffer(id, off + cat_off, 0x2000);
+ memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
+ cat_block = be32_to_cpu(extents[0].start_block);
+ dbg("catalog start block 0x%x", cat_block);
+
+ buf = get_buffer(id, off + (cat_block * blocksize), 0x2000);
if (buf == NULL)
goto found;
&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);
+
+ 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;
- dbg("catalog leaf node 0x%x, size 0x%x",
- leaf_node_head, leaf_node_size);
+ leaf_block = (leaf_node_head * leaf_node_size) / blocksize;
- buf = get_buffer(id, off + cat_off + (leaf_node_head * leaf_node_size),
- leaf_node_size);
+ /* get physical location */
+ for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) {
+ ext_block_start = be32_to_cpu(extents[ext].start_block);
+ ext_block_count = be32_to_cpu(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;
if (strncmp(ns->oem_id, "NTFS", 4) != 0)
return -1;
- set_uuid(id, ns->volume_serial, 8);
+ set_uuid(id, ns->volume_serial, UUID_NTFS);
sector_size = le16_to_cpu(ns->bytes_per_sector);
cluster_size = ns->sectors_per_cluster * sector_size;
#define LARGEST_PAGESIZE 0x4000
static int probe_swap(struct volume_id *id, __u64 off)
{
- const __u8 *sig;
+ struct swap_header_v1_2 {
+ __u8 bootbits[1024];
+ __u32 version;
+ __u32 last_page;
+ __u32 nr_badpages;
+ __u8 uuid[16];
+ __u8 volume_name[16];
+ } __attribute__((__packed__)) *sw;
+
+ const __u8 *buf;
unsigned int page;
- /* huhh, the swap signature is on the end of the PAGE_SIZE */
+ /* the swap signature is at the end of the PAGE_SIZE */
for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) {
- sig = get_buffer(id, off + page-10, 10);
- if (sig == NULL)
+ buf = get_buffer(id, off + page-10, 10);
+ if (buf == NULL)
return -1;
- if (strncmp(sig, "SWAP-SPACE", 10) == 0) {
+ if (strncmp(buf, "SWAP-SPACE", 10) == 0) {
strcpy(id->type_version, "1");
goto found;
}
- if (strncmp(sig, "SWAPSPACE2", 10) == 0) {
+
+ if (strncmp(buf, "SWAPSPACE2", 10) == 0) {
+ sw = (struct swap_header_v1_2 *) get_buffer(id, off, sizeof(struct swap_header_v1_2));
+ if (sw == NULL)
+ return -1;
strcpy(id->type_version, "2");
+ set_label_raw(id, sw->volume_name, 16);
+ set_label_string(id, sw->volume_name, 16);
+ set_uuid(id, sw->uuid, UUID_DCE);
goto found;
}
}
{
int rc;
+ dbg("called with size=0x%llx", size);
+
if (id == NULL)
return -EINVAL;
case VOLUME_ID_LVM2:
rc = probe_lvm2(id, off);
break;
+ case VOLUME_ID_HPTRAID:
+ rc = probe_highpoint_ataraid(id, off);
+ break;
case VOLUME_ID_ALL:
default:
+ /* probe for raid first, cause fs probes may be successful on raid members */
rc = probe_linux_raid(id, off, size);
if (rc == 0)
break;
-
- /* signature in the first block */
- rc = probe_ntfs(id, off);
+ rc = probe_lvm1(id, off);
if (rc == 0)
break;
- rc = probe_vfat(id, off);
+ rc = probe_lvm2(id, off);
if (rc == 0)
break;
- rc = probe_msdos_part_table(id, off);
+ rc = probe_highpoint_ataraid(id, off);
+ if (rc == 0)
+ break;
+
+ /* signature in the first block, only small buffer needed */
+ rc = probe_vfat(id, off);
if (rc == 0)
break;
rc = probe_mac_partition_map(id, off);
rc = probe_ufs(id, off);
if (rc == 0)
break;
- rc = probe_lvm1(id, off);
- if (rc == 0)
- break;
- rc = probe_lvm2(id, off);
+ rc = probe_ntfs(id, off);
if (rc == 0)
break;
struct volume_id *id;
int fd;
- fd = open(path, O_RDONLY | O_NONBLOCK);
+ fd = open(path, O_RDONLY);
if (fd < 0) {
dbg("unable to open '%s'", path);
return NULL;