/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation.
*
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_ARCH_H__
#define __XFS_ARCH_H__
#include <asm/byteorder.h>
-#ifdef __LITTLE_ENDIAN
-# define __BYTE_ORDER __LITTLE_ENDIAN
-#endif
#ifdef __BIG_ENDIAN
-# define __BYTE_ORDER __BIG_ENDIAN
+#define XFS_NATIVE_HOST 1
+#else
+#undef XFS_NATIVE_HOST
+#endif
+
+#else /* __KERNEL__ */
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define XFS_NATIVE_HOST 1
+#else
+#undef XFS_NATIVE_HOST
+#endif
+
+#ifdef XFS_NATIVE_HOST
+#define cpu_to_be16(val) ((__be16)(val))
+#define cpu_to_be32(val) ((__be32)(val))
+#define cpu_to_be64(val) ((__be64)(val))
+#define be16_to_cpu(val) ((__uint16_t)(val))
+#define be32_to_cpu(val) ((__uint32_t)(val))
+#define be64_to_cpu(val) ((__uint64_t)(val))
+#else
+#define cpu_to_be16(val) (__swab16((__uint16_t)(val)))
+#define cpu_to_be32(val) (__swab32((__uint32_t)(val)))
+#define cpu_to_be64(val) (__swab64((__uint64_t)(val)))
+#define be16_to_cpu(val) (__swab16((__be16)(val)))
+#define be32_to_cpu(val) (__swab32((__be32)(val)))
+#define be64_to_cpu(val) (__swab64((__be64)(val)))
#endif
#endif /* __KERNEL__ */
/* do we need conversion? */
-
#define ARCH_NOCONVERT 1
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define ARCH_CONVERT 0
-#else
+#ifdef XFS_NATIVE_HOST
# define ARCH_CONVERT ARCH_NOCONVERT
+#else
+# define ARCH_CONVERT 0
#endif
/* generic swapping macros */
((sizeof(type) == 2) ? INT_SWAP16(type,var) : \
(var))))
-#define INT_SWAP_UNALIGNED_32(from,to) \
- { \
- ((__u8*)(to))[0] = ((__u8*)(from))[3]; \
- ((__u8*)(to))[1] = ((__u8*)(from))[2]; \
- ((__u8*)(to))[2] = ((__u8*)(from))[1]; \
- ((__u8*)(to))[3] = ((__u8*)(from))[0]; \
- }
-
-#define INT_SWAP_UNALIGNED_64(from,to) \
- { \
- INT_SWAP_UNALIGNED_32( ((__u8*)(from)) + 4, ((__u8*)(to))); \
- INT_SWAP_UNALIGNED_32( ((__u8*)(from)), ((__u8*)(to)) + 4); \
- }
-
/*
* get and set integers from potentially unaligned locations
*/
-#define INT_GET_UNALIGNED_16_LE(pointer) \
- ((__u16)((((__u8*)(pointer))[0] ) | (((__u8*)(pointer))[1] << 8 )))
#define INT_GET_UNALIGNED_16_BE(pointer) \
((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1])))
-#define INT_SET_UNALIGNED_16_LE(pointer,value) \
- { \
- ((__u8*)(pointer))[0] = (((value) ) & 0xff); \
- ((__u8*)(pointer))[1] = (((value) >> 8) & 0xff); \
- }
#define INT_SET_UNALIGNED_16_BE(pointer,value) \
{ \
((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \
((__u8*)(pointer))[1] = (((value) ) & 0xff); \
}
-#define INT_GET_UNALIGNED_32_LE(pointer) \
- ((__u32)((((__u8*)(pointer))[0] ) | (((__u8*)(pointer))[1] << 8 ) \
- |(((__u8*)(pointer))[2] << 16) | (((__u8*)(pointer))[3] << 24)))
-#define INT_GET_UNALIGNED_32_BE(pointer) \
- ((__u32)((((__u8*)(pointer))[0] << 24) | (((__u8*)(pointer))[1] << 16) \
- |(((__u8*)(pointer))[2] << 8) | (((__u8*)(pointer))[3] )))
-
-#define INT_GET_UNALIGNED_64_LE(pointer) \
- (((__u64)(INT_GET_UNALIGNED_32_LE(((__u8*)(pointer))+4)) << 32 ) \
- |((__u64)(INT_GET_UNALIGNED_32_LE(((__u8*)(pointer)) )) ))
-#define INT_GET_UNALIGNED_64_BE(pointer) \
- (((__u64)(INT_GET_UNALIGNED_32_BE(((__u8*)(pointer)) )) << 32 ) \
- |((__u64)(INT_GET_UNALIGNED_32_BE(((__u8*)(pointer))+4)) ))
-
-/*
- * now pick the right ones for our MACHINE ARCHITECTURE
- */
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define INT_GET_UNALIGNED_16(pointer) INT_GET_UNALIGNED_16_LE(pointer)
-#define INT_SET_UNALIGNED_16(pointer,value) INT_SET_UNALIGNED_16_LE(pointer,value)
-#define INT_GET_UNALIGNED_32(pointer) INT_GET_UNALIGNED_32_LE(pointer)
-#define INT_GET_UNALIGNED_64(pointer) INT_GET_UNALIGNED_64_LE(pointer)
-#else
-#define INT_GET_UNALIGNED_16(pointer) INT_GET_UNALIGNED_16_BE(pointer)
-#define INT_SET_UNALIGNED_16(pointer,value) INT_SET_UNALIGNED_16_BE(pointer,value)
-#define INT_GET_UNALIGNED_32(pointer) INT_GET_UNALIGNED_32_BE(pointer)
-#define INT_GET_UNALIGNED_64(pointer) INT_GET_UNALIGNED_64_BE(pointer)
-#endif
-
/* define generic INT_ macros */
#define INT_GET(reference,arch) \
} \
}
-#define INT_ISZERO(reference,arch) \
- ((reference) == 0)
-
-#define INT_ZERO(reference,arch) \
- ((reference) = 0)
-
-#define INT_GET_UNALIGNED_16_ARCH(pointer,arch) \
- ( ((arch) == ARCH_NOCONVERT) \
- ? \
- (INT_GET_UNALIGNED_16(pointer)) \
- : \
- (INT_GET_UNALIGNED_16_BE(pointer)) \
- )
-#define INT_SET_UNALIGNED_16_ARCH(pointer,value,arch) \
- if ((arch) == ARCH_NOCONVERT) { \
- INT_SET_UNALIGNED_16(pointer,value); \
- } else { \
- INT_SET_UNALIGNED_16_BE(pointer,value); \
- }
-
-#define DIRINO4_GET_ARCH(pointer,arch) \
- ( ((arch) == ARCH_NOCONVERT) \
- ? \
- (INT_GET_UNALIGNED_32(pointer)) \
- : \
- (INT_GET_UNALIGNED_32_BE(pointer)) \
- )
+static inline void be16_add(__be16 *a, __s16 b)
+{
+ *a = cpu_to_be16(be16_to_cpu(*a) + b);
+}
-#if XFS_BIG_INUMS
-#define DIRINO_GET_ARCH(pointer,arch) \
- ( ((arch) == ARCH_NOCONVERT) \
- ? \
- (INT_GET_UNALIGNED_64(pointer)) \
- : \
- (INT_GET_UNALIGNED_64_BE(pointer)) \
- )
-#else
-/* MACHINE ARCHITECTURE dependent */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define DIRINO_GET_ARCH(pointer,arch) \
- DIRINO4_GET_ARCH((((__u8*)pointer)+4),arch)
-#else
-#define DIRINO_GET_ARCH(pointer,arch) \
- DIRINO4_GET_ARCH(pointer,arch)
-#endif
-#endif
+static inline void be32_add(__be32 *a, __s32 b)
+{
+ *a = cpu_to_be32(be32_to_cpu(*a) + b);
+}
-#define DIRINO_COPY_ARCH(from,to,arch) \
- if ((arch) == ARCH_NOCONVERT) { \
- memcpy(to,from,sizeof(xfs_ino_t)); \
- } else { \
- INT_SWAP_UNALIGNED_64(from,to); \
- }
-#define DIRINO4_COPY_ARCH(from,to,arch) \
- if ((arch) == ARCH_NOCONVERT) { \
- memcpy(to,(((__u8*)from+4)),sizeof(xfs_dir2_ino4_t)); \
- } else { \
- INT_SWAP_UNALIGNED_32(from,to); \
- }
+static inline void be64_add(__be64 *a, __s64 b)
+{
+ *a = cpu_to_be64(be64_to_cpu(*a) + b);
+}
+/*
+ * In directories inode numbers are stored as unaligned arrays of unsigned
+ * 8bit integers on disk.
+ *
+ * For v1 directories or v2 directories that contain inode numbers that
+ * do not fit into 32bit the array has eight members, but the first member
+ * is always zero:
+ *
+ * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7|
+ *
+ * For v2 directories that only contain entries with inode numbers that fit
+ * into 32bits a four-member array is used:
+ *
+ * |24-31|16-23| 8-15| 0- 7|
+ */
+
+#define XFS_GET_DIR_INO4(di) \
+ (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
+
+#define XFS_PUT_DIR_INO4(from, di) \
+do { \
+ (di).i[0] = (((from) & 0xff000000ULL) >> 24); \
+ (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \
+ (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \
+ (di).i[3] = ((from) & 0x000000ffULL); \
+} while (0)
+
+#define XFS_DI_HI(di) \
+ (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
+#define XFS_DI_LO(di) \
+ (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7]))
+
+#define XFS_GET_DIR_INO8(di) \
+ (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \
+ ((xfs_ino_t)XFS_DI_HI(di) << 32))
+
+#define XFS_PUT_DIR_INO8(from, di) \
+do { \
+ (di).i[0] = 0; \
+ (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \
+ (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \
+ (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \
+ (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \
+ (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \
+ (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \
+ (di).i[7] = ((from) & 0x00000000000000ffULL); \
+} while (0)
+
#endif /* __XFS_ARCH_H__ */