Subject: Alignment issue in msdosfs - bpb.h
To: None <current-users@netbsd.org>
From: John Hayward <John.C.Hayward@wheaton.edu>
List: current-users
Date: 03/20/2001 23:06:55
Dear NetBSDers,
   I am running on a NetBSD-1.5 i386 port - the question below may
apply to other ports.
   I am trying to write a utility to extract some info from a msdos file
system.  In the boot parameter block header file
(/usr/include/msdosfs/bpb.h) we find two versions of bpb for Fat32.
One starts out like:
====
/*
 * BPB for DOS 7.10 (FAT32).  This one has a few extensions to bpb50.
 */
struct bpb710 {
        u_int16_t       bpbBytesPerSec; /* bytes per sector */
        u_int8_t        bpbSecPerClust; /* sectors per cluster */
        u_int16_t       bpbResSectors;  /* number of reserved sectors */
        u_int8_t        bpbFATs;        /* number of FATs */
====
The other like:
====
/*
 * BPB for DOS 7.10 (FAT32).  This one has a few extensions to bpb50.
 */
struct byte_bpb710 {
        u_int8_t bpbBytesPerSec[2];     /* bytes per sector */
        u_int8_t bpbSecPerClust;        /* sectors per cluster */
        u_int8_t bpbResSectors[2];      /* number of reserved sectors */
        u_int8_t bpbFATs;               /* number of FATs */
====
It seems if I use the first version things get off - possibly due to the 
compiler aligning the bpbResSectors to an even location.

If I run the following program:
===
scilab02> more Alignment.c
#include <stdio.h>
#include <msdosfs/bpb.h>
int main(){
    struct byte_bpb710 byte_bios;
    struct bpb710 bios;
    printf("offset of bpbFATs for byte_bios is %d\n",
           (char *) &byte_bios.bpbFATs - (char *)&byte_bios);
    printf("offset of bpbFATs for bios is %d\n",
           (char *) &bios.bpbFATs - (char *) &bios);
    return 0;
}
scilab02> ./Alignment
offset of bpbFATs for byte_bios is 5
offset of bpbFATs for bios is 6
====
It seems to indicate that the location of bpbResSectors is aligned to an
even location which causes bpbFATs also to be an even location (when in
fact the data is at an odd location).

Since this info is read from the disk I cannot change how things are
actually laid out (why did MS mix single byte items with 2 byte items
where the layout would require that the 2 byte item start at an odd
location?)

Is there a compiler flag which will allow me to use the first structure
and retrieve the values correctly?

TIA
johnh...