FreeBSD/sys/geom/vinum/geom_vinum_drive.c
/*
 * Read the header while taking magic number into account, and write it to
 * destination pointer.
 */
Read the header while taking magic number into account, and write it to
destination pointer.
Read the header while taking magic number into account and write it to destination pointer .
int
gv_read_header(struct g_consumer *cp, struct gv_hdr *m_hdr)
{
	struct g_provider *pp;
	uint64_t magic_machdep;
	uint8_t *d_hdr;
	int be, off;
#define GV_GET32(endian)					\
		endian##32toh(*((uint32_t *)&d_hdr[off]));	\
		off += 4
#define GV_GET64(endian)					\
		endian##64toh(*((uint64_t *)&d_hdr[off]));	\
		off += 8
	KASSERT(m_hdr != NULL, ("gv_read_header: null m_hdr"));
	KASSERT(cp != NULL, ("gv_read_header: null cp"));
	pp = cp->provider;
	KASSERT(pp != NULL, ("gv_read_header: null pp"));
	if ((GV_HDR_OFFSET % pp->sectorsize) != 0 ||
	    (GV_HDR_LEN % pp->sectorsize) != 0)
		return (ENODEV);
	d_hdr = g_read_data(cp, GV_HDR_OFFSET, pp->sectorsize, NULL);
	if (d_hdr == NULL)
		return (-1);
	off = 0;
	m_hdr->magic = GV_GET64(be);
	magic_machdep = *((uint64_t *)&d_hdr[0]);
	be = (m_hdr->magic == magic_machdep);
	if (m_hdr->magic == GV_MAGIC) {
		m_hdr->config_length = GV_GET64(be);
		off = 16;
		bcopy(d_hdr + off, m_hdr->label.sysname, GV_HOSTNAME_LEN);
		off += GV_HOSTNAME_LEN;
		bcopy(d_hdr + off, m_hdr->label.name, GV_MAXDRIVENAME);
		off += GV_MAXDRIVENAME;
		m_hdr->label.date_of_birth.tv_sec = GV_GET64(be);
		m_hdr->label.date_of_birth.tv_usec = GV_GET64(be);
		m_hdr->label.last_update.tv_sec = GV_GET64(be);
		m_hdr->label.last_update.tv_usec = GV_GET64(be);
		m_hdr->label.drive_size = GV_GET64(be);
	} else if (m_hdr->magic != GV_OLD_MAGIC &&
	    m_hdr->magic != le64toh(GV_OLD_MAGIC)) {
		g_free(d_hdr);
		return (-1);
	} else if (gv_legacy_header_type(d_hdr, be) == GV_LEGACY_SPARC64) {
		G_VINUM_DEBUG(1, "detected legacy sparc64 header");
		m_hdr->magic = GV_MAGIC;
		m_hdr->config_length = GV_GET64(be);
		bcopy(d_hdr + 16, m_hdr->label.sysname, GV_HOSTNAME_LEN);
		off += GV_HOSTNAME_LEN;
		bcopy(d_hdr + 48, m_hdr->label.name, GV_MAXDRIVENAME);
		off += GV_MAXDRIVENAME;
		m_hdr->label.date_of_birth.tv_sec = GV_GET64(be);
		m_hdr->label.date_of_birth.tv_usec = GV_GET64(be);
		m_hdr->label.last_update.tv_sec = GV_GET64(be);
		m_hdr->label.last_update.tv_usec = GV_GET64(be);
		m_hdr->label.drive_size = GV_GET64(be);
	} else if (gv_legacy_header_type(d_hdr, be) == GV_LEGACY_POWERPC) {
		G_VINUM_DEBUG(1, "detected legacy PowerPC header");
		m_hdr->magic = GV_MAGIC;
		m_hdr->config_length = GV_GET32(be);
		bcopy(d_hdr + off, m_hdr->label.sysname, GV_HOSTNAME_LEN);
		off += GV_HOSTNAME_LEN;
		bcopy(d_hdr + off, m_hdr->label.name, GV_MAXDRIVENAME);
		off += GV_MAXDRIVENAME;
		m_hdr->label.date_of_birth.tv_sec = GV_GET32(be);
		m_hdr->label.date_of_birth.tv_usec = GV_GET32(be);
		m_hdr->label.last_update.tv_sec = GV_GET32(be);
		m_hdr->label.last_update.tv_usec = GV_GET32(be);
		m_hdr->label.drive_size = GV_GET64(be);
	} else if (gv_legacy_header_type(d_hdr, be) == GV_LEGACY_I386) {
		G_VINUM_DEBUG(1, "detected legacy i386 header");
		m_hdr->magic = GV_MAGIC;
		m_hdr->config_length = GV_GET32(le);
		bcopy(d_hdr + off, m_hdr->label.sysname, GV_HOSTNAME_LEN);
		off += GV_HOSTNAME_LEN;
		bcopy(d_hdr + off, m_hdr->label.name, GV_MAXDRIVENAME);
		off += GV_MAXDRIVENAME;
		m_hdr->label.date_of_birth.tv_sec = GV_GET32(le);
		m_hdr->label.date_of_birth.tv_usec = GV_GET32(le);
		m_hdr->label.last_update.tv_sec = GV_GET32(le);
		m_hdr->label.last_update.tv_usec = GV_GET32(le);
		m_hdr->label.drive_size = GV_GET64(le);
	} else {
		G_VINUM_DEBUG(1, "detected legacy amd64 header");
		m_hdr->magic = GV_MAGIC;
		m_hdr->config_length = GV_GET64(le);
		bcopy(d_hdr + 16, m_hdr->label.sysname, GV_HOSTNAME_LEN);
		off += GV_HOSTNAME_LEN;
		bcopy(d_hdr + 48, m_hdr->label.name, GV_MAXDRIVENAME);
		off += GV_MAXDRIVENAME;
		m_hdr->label.date_of_birth.tv_sec = GV_GET64(le);
		m_hdr->label.date_of_birth.tv_usec = GV_GET64(le);
		m_hdr->label.last_update.tv_sec = GV_GET64(le);
		m_hdr->label.last_update.tv_usec = GV_GET64(le);
		m_hdr->label.drive_size = GV_GET64(le);
	}
	g_free(d_hdr);
	return (0);
}
int gv_read_header ( struct g_consumer * cp , struct gv_hdr * m_hdr ) { struct g_provider * pp ; uint64_t magic_machdep ; uint8_t * d_hdr ; int be , off ; #define GV_GET32 ( endian ) 					\
		endian##32toh(*((uint32_t *)&d_hdr[off]));	\
		off += 4 #define GV_GET64 ( endian ) 					\
		endian##64toh(*((uint64_t *)&d_hdr[off]));	\
		off += 8 KASSERT ( m_hdr != NULL , ( " " ) ) ; KASSERT ( cp != NULL , ( " " ) ) ; pp = cp -> provider ; KASSERT ( pp != NULL , ( " " ) ) ; if ( ( GV_HDR_OFFSET % pp -> sectorsize ) != 0 || ( GV_HDR_LEN % pp -> sectorsize ) != 0 ) return ( ENODEV ) ; d_hdr = g_read_data ( cp , GV_HDR_OFFSET , pp -> sectorsize , NULL ) ; if ( d_hdr == NULL ) return ( -1 ) ; off = 0 ; m_hdr -> magic = GV_GET64 ( be ) ; magic_machdep = * ( ( uint64_t * ) & d_hdr [ 0 ] ) ; be = ( m_hdr -> magic == magic_machdep ) ; if ( m_hdr -> magic == GV_MAGIC ) { m_hdr -> config_length = GV_GET64 ( be ) ; off = 16 ; bcopy ( d_hdr + off , m_hdr -> label . sysname , GV_HOSTNAME_LEN ) ; off += GV_HOSTNAME_LEN ; bcopy ( d_hdr + off , m_hdr -> label . name , GV_MAXDRIVENAME ) ; off += GV_MAXDRIVENAME ; m_hdr -> label . date_of_birth . tv_sec = GV_GET64 ( be ) ; m_hdr -> label . date_of_birth . tv_usec = GV_GET64 ( be ) ; m_hdr -> label . last_update . tv_sec = GV_GET64 ( be ) ; m_hdr -> label . last_update . tv_usec = GV_GET64 ( be ) ; m_hdr -> label . drive_size = GV_GET64 ( be ) ; } else if ( m_hdr -> magic != GV_OLD_MAGIC && m_hdr -> magic != le64toh ( GV_OLD_MAGIC ) ) { g_free ( d_hdr ) ; return ( -1 ) ; } else if ( gv_legacy_header_type ( d_hdr , be ) == GV_LEGACY_SPARC64 ) { G_VINUM_DEBUG ( 1 , " " ) ; m_hdr -> magic = GV_MAGIC ; m_hdr -> config_length = GV_GET64 ( be ) ; bcopy ( d_hdr + 16 , m_hdr -> label . sysname , GV_HOSTNAME_LEN ) ; off += GV_HOSTNAME_LEN ; bcopy ( d_hdr + 48 , m_hdr -> label . name , GV_MAXDRIVENAME ) ; off += GV_MAXDRIVENAME ; m_hdr -> label . date_of_birth . tv_sec = GV_GET64 ( be ) ; m_hdr -> label . date_of_birth . tv_usec = GV_GET64 ( be ) ; m_hdr -> label . last_update . tv_sec = GV_GET64 ( be ) ; m_hdr -> label . last_update . tv_usec = GV_GET64 ( be ) ; m_hdr -> label . drive_size = GV_GET64 ( be ) ; } else if ( gv_legacy_header_type ( d_hdr , be ) == GV_LEGACY_POWERPC ) { G_VINUM_DEBUG ( 1 , " " ) ; m_hdr -> magic = GV_MAGIC ; m_hdr -> config_length = GV_GET32 ( be ) ; bcopy ( d_hdr + off , m_hdr -> label . sysname , GV_HOSTNAME_LEN ) ; off += GV_HOSTNAME_LEN ; bcopy ( d_hdr + off , m_hdr -> label . name , GV_MAXDRIVENAME ) ; off += GV_MAXDRIVENAME ; m_hdr -> label . date_of_birth . tv_sec = GV_GET32 ( be ) ; m_hdr -> label . date_of_birth . tv_usec = GV_GET32 ( be ) ; m_hdr -> label . last_update . tv_sec = GV_GET32 ( be ) ; m_hdr -> label . last_update . tv_usec = GV_GET32 ( be ) ; m_hdr -> label . drive_size = GV_GET64 ( be ) ; } else if ( gv_legacy_header_type ( d_hdr , be ) == GV_LEGACY_I386 ) { G_VINUM_DEBUG ( 1 , " " ) ; m_hdr -> magic = GV_MAGIC ; m_hdr -> config_length = GV_GET32 ( le ) ; bcopy ( d_hdr + off , m_hdr -> label . sysname , GV_HOSTNAME_LEN ) ; off += GV_HOSTNAME_LEN ; bcopy ( d_hdr + off , m_hdr -> label . name , GV_MAXDRIVENAME ) ; off += GV_MAXDRIVENAME ; m_hdr -> label . date_of_birth . tv_sec = GV_GET32 ( le ) ; m_hdr -> label . date_of_birth . tv_usec = GV_GET32 ( le ) ; m_hdr -> label . last_update . tv_sec = GV_GET32 ( le ) ; m_hdr -> label . last_update . tv_usec = GV_GET32 ( le ) ; m_hdr -> label . drive_size = GV_GET64 ( le ) ; } else { G_VINUM_DEBUG ( 1 , " " ) ; m_hdr -> magic = GV_MAGIC ; m_hdr -> config_length = GV_GET64 ( le ) ; bcopy ( d_hdr + 16 , m_hdr -> label . sysname , GV_HOSTNAME_LEN ) ; off += GV_HOSTNAME_LEN ; bcopy ( d_hdr + 48 , m_hdr -> label . name , GV_MAXDRIVENAME ) ; off += GV_MAXDRIVENAME ; m_hdr -> label . date_of_birth . tv_sec = GV_GET64 ( le ) ; m_hdr -> label . date_of_birth . tv_usec = GV_GET64 ( le ) ; m_hdr -> label . last_update . tv_sec = GV_GET64 ( le ) ; m_hdr -> label . last_update . tv_usec = GV_GET64 ( le ) ; m_hdr -> label . drive_size = GV_GET64 ( le ) ; } g_free ( d_hdr ) ; return ( 0 ) ; }
Read the header while taking magic number into account, and write it to
 destination pointer.
Read the header while taking magic number into account and write it to destination pointer .
/*
	 * The big endian machines will have a reverse of GV_OLD_MAGIC, so we
	 * need to decide if we are running on a big endian machine as well as
	 * checking the magic against the reverse of GV_OLD_MAGIC.
	 */ /* Not a gvinum drive. */ /* Legacy sparc64 on-disk header */ /* legacy 32-bit big endian on-disk header */ /* legacy i386 on-disk header */ /* legacy amd64 on-disk header */