Quick fix for msdsofs_write() on alphas and other machines with either

longs larger than 32 bits or strict alignment requirements.

pm_fatmask had type u_long, but it must have a type that has precisely
32 bits and this type must be no smaller than int, so that ~pmp->pm_fatmask
has no bits above the 31st set.  Otherwise, comparisons between (cn
| ~pmp->pm_fatmask) and magic 32-bit "cluster" numbers always fail.
The correct fix is to use the C99 type uint_least32_t and mask with
0xffffffff.  The quick fix is to use u_int32_t and assume that ints
have

msdosfs metadata is riddled with unaligned fields, and on alphas,
unaligned_fixup() apparently has problems fixing up the unaligned
accesses caused by this.  The quick fix is to not comment out the
NetBSD code that sort of handles this, and define UNALIGNED_ACCESS on
i386's so that the code doesn't change on i386's.  The correct fix
would define UNALIGNED_ACCESS in a central machine-dependent header
and maybe add some extra cases to unaligned_fixup().  UNALIGNED_ACCESS
is also tested in isofs.

Submitted by:	parts by Mark Abene <phiber@radicalmedia.com>
PR:		19086
This commit is contained in:
Bruce Evans 2000-08-25 09:03:58 +00:00
parent c4bf9c2485
commit ff4ad0c4d8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65075
4 changed files with 16 additions and 4 deletions

View File

@ -113,8 +113,14 @@ struct bpb_a {
* 16-bit and 32-bit quantities on byte boundaries. If this is not true,
* use the macros for the big-endian case.
*/
#include <machine/endian.h>
#if (BYTE_ORDER == LITTLE_ENDIAN) /* && defined(UNALIGNED_ACCESS) */
#ifdef __i386__
#define UNLALIGNED_ACCESS
#endif
#if (BYTE_ORDER == LITTLE_ENDIAN) && defined(UNALIGNED_ACCESS)
#define getushort(x) *((u_int16_t *)(x))
#define getulong(x) *((u_int32_t *)(x))
#define putushort(p, v) (*((u_int16_t *)(p)) = (v))

View File

@ -84,7 +84,7 @@ struct msdosfsmount {
u_long pm_fatblocksize; /* size of fat blocks in bytes */
u_long pm_fatblocksec; /* size of fat blocks in sectors */
u_long pm_fatsize; /* size of fat in bytes */
u_long pm_fatmask; /* mask to use for fat numbers */
u_int32_t pm_fatmask; /* mask to use for fat numbers */
u_long pm_fsinfo; /* fsinfo block number */
u_long pm_nxtfree; /* next free cluster in fsinfo block */
u_int pm_fatmult; /* these 2 values are used in fat */

View File

@ -113,8 +113,14 @@ struct bpb_a {
* 16-bit and 32-bit quantities on byte boundaries. If this is not true,
* use the macros for the big-endian case.
*/
#include <machine/endian.h>
#if (BYTE_ORDER == LITTLE_ENDIAN) /* && defined(UNALIGNED_ACCESS) */
#ifdef __i386__
#define UNLALIGNED_ACCESS
#endif
#if (BYTE_ORDER == LITTLE_ENDIAN) && defined(UNALIGNED_ACCESS)
#define getushort(x) *((u_int16_t *)(x))
#define getulong(x) *((u_int32_t *)(x))
#define putushort(p, v) (*((u_int16_t *)(p)) = (v))

View File

@ -84,7 +84,7 @@ struct msdosfsmount {
u_long pm_fatblocksize; /* size of fat blocks in bytes */
u_long pm_fatblocksec; /* size of fat blocks in sectors */
u_long pm_fatsize; /* size of fat in bytes */
u_long pm_fatmask; /* mask to use for fat numbers */
u_int32_t pm_fatmask; /* mask to use for fat numbers */
u_long pm_fsinfo; /* fsinfo block number */
u_long pm_nxtfree; /* next free cluster in fsinfo block */
u_int pm_fatmult; /* these 2 values are used in fat */