Subject: file id alignment
To: None <tech-kern@NetBSD.org>
From: Martin Husemann <martin@duskware.de>
List: tech-kern
Date: 06/29/2006 23:51:04
I think we have a problem. We define the superclass of any file id as:

struct fid {
        unsigned short  fid_len;                /* length of data in bytes */
        unsigned short  fid_reserved;           /* force longword alignment */
        char            fid_data[_VFS_MAXFIDSZ];/* data (variable length) */
};

and a pointer to this is passed, for example, to vptofh(). The alignement
requirement of this struct should be 2 bytes on most (all?) of our archs.
Luckily gcc4 seems to use 4 byte alignement for this.

Now when the fid is filled, it is casted to the proper type for the concrete
filesystem. Two examples:

struct ufid {
        u_int16_t ufid_len;     /* Length of structure. */
        u_int16_t ufid_pad;     /* Force 32-bit alignment. */
        u_int32_t ufid_ino;     /* File number (ino). */
        int32_t   ufid_gen;     /* Generation number. */
};

This should have 4 byte alignement. We are lucky (but by pure chance).

struct tmpfs_fid { 
        uint16_t                tf_len;
        uint16_t                tf_pad;
        uint32_t                tf_gen;
        ino_t                   tf_id;
};

This has 8 byte alignment (due to ino_t) - and indeed alignment critical archs
fault when assigning tf_id.

How about:

struct fid {
        unsigned short  fid_len;                /* length of data in bytes */
        unsigned short  fid_reserved;           /* force longword alignment */
        union {
                char    fid_data[_VFS_MAXFIDSZ];/* data (variable length) */
                ino_t   fid_alignment;
        };
};

or:

struct fid {
        unsigned short  fid_len;                /* length of data in bytes */
        unsigned short  fid_reserved;           /* force longword alignment */
        char            fid_data[_VFS_MAXFIDSZ]
	    __aligned(8);			/* data (variable length) */
};

Of course we could just tell FS authors to be carefull and copy byte by 
byte ;-)

Any better suggestions? Comments?

Martin