Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | /* * linux/fs/ufs/swab.h * * Copyright (C) 1997, 1998 Francois-Rene Rideau <fare@tunes.org> * Copyright (C) 1998 Jakub Jelinek <jj@ultra.linux.cz> */ #ifndef _UFS_SWAB_H #define _UFS_SWAB_H /* * Notes: * HERE WE ASSUME EITHER BIG OR LITTLE ENDIAN UFSes * in case there are ufs implementations that have strange bytesexes, * you'll need to modify code here as well as in ufs_super.c and ufs_fs.h * to support them. * * WE ALSO ASSUME A REMOTELY SANE ARCHITECTURE BYTESEX. * We are not ready to confront insane bytesexual perversions where * conversion to/from little/big-endian is not an involution. * That is, we require that XeYZ_to_cpu(x) == cpu_to_XeYZ(x) * * NOTE that swab macros depend on a variable (or macro) swab being in * scope and properly initialized (usually from sb->u.ufs_sb.s_swab). * Its meaning depends on whether the architecture is sane-endian or not. * For sane architectures, it's a flag taking values UFS_NATIVE_ENDIAN (0) * or UFS_SWABBED_ENDIAN (1), indicating whether to swab or not. * For pervert architectures, it's either UFS_LITTLE_ENDIAN or * UFS_BIG_ENDIAN whose meaning you'll have to guess. * * It is important to keep these conventions in synch with ufs_fs.h * and super.c. Failure to do so (initializing swab to 0 both for * NATIVE_ENDIAN and LITTLE_ENDIAN) led to nasty crashes on big endian * machines reading little endian UFSes. Search for "swab =" in super.c. * * I also suspect the whole UFS code to trust the on-disk structures * much too much, which might lead to losing badly when mounting * inconsistent partitions as UFS filesystems. fsck required (but of * course, no fsck.ufs has yet to be ported from BSD to Linux as of 199808). */ #include <linux/ufs_fs.h> #include <asm/byteorder.h> /* * These are only valid inside ufs routines, * after swab has been initialized to sb->u.ufs_sb.s_swab */ #define SWAB16(x) ufs_swab16(swab,x) #define SWAB32(x) ufs_swab32(swab,x) #define SWAB64(x) ufs_swab64(swab,x) /* * We often use swabing, when we want to increment/decrement some value, * so these macros might become handy and increase readability. (Daniel) */ #define INC_SWAB16(x) ((x)=ufs_swab16_add(swab,x,1)) #define INC_SWAB32(x) ((x)=ufs_swab32_add(swab,x,1)) #define INC_SWAB64(x) ((x)=ufs_swab64_add(swab,x,1)) #define DEC_SWAB16(x) ((x)=ufs_swab16_add(swab,x,-1)) #define DEC_SWAB32(x) ((x)=ufs_swab32_add(swab,x,-1)) #define DEC_SWAB64(x) ((x)=ufs_swab64_add(swab,x,-1)) #define ADD_SWAB16(x,y) ((x)=ufs_swab16_add(swab,x,y)) #define ADD_SWAB32(x,y) ((x)=ufs_swab32_add(swab,x,y)) #define ADD_SWAB64(x,y) ((x)=ufs_swab64_add(swab,x,y)) #define SUB_SWAB16(x,y) ((x)=ufs_swab16_add(swab,x,-(y))) #define SUB_SWAB32(x,y) ((x)=ufs_swab32_add(swab,x,-(y))) #define SUB_SWAB64(x,y) ((x)=ufs_swab64_add(swab,x,-(y))) #if defined(__LITTLE_ENDIAN) || defined(__BIG_ENDIAN) /* sane bytesex */ extern __inline__ __const__ __u16 ufs_swab16(unsigned swab, __u16 x) { if (swab) return swab16(x); else return x; } extern __inline__ __const__ __u32 ufs_swab32(unsigned swab, __u32 x) { if (swab) return swab32(x); else return x; } extern __inline__ __const__ __u64 ufs_swab64(unsigned swab, __u64 x) { if (swab) return swab64(x); else return x; } extern __inline__ __const__ __u16 ufs_swab16_add(unsigned swab, __u16 x, __u16 y) { if (swab) return swab16(swab16(x)+y); else return x + y; } extern __inline__ __const__ __u32 ufs_swab32_add(unsigned swab, __u32 x, __u32 y) { if (swab) return swab32(swab32(x)+y); else return x + y; } extern __inline__ __const__ __u64 ufs_swab64_add(unsigned swab, __u64 x, __u64 y) { if (swab) return swab64(swab64(x)+y); else return x + y; } #else /* bytesexual perversion -- BEWARE! Read note at top of file! */ extern __inline__ __const__ __u16 ufs_swab16(unsigned swab, __u16 x) { if (swab == UFS_LITTLE_ENDIAN) return le16_to_cpu(x); else return be16_to_cpu(x); } extern __inline__ __const__ __u32 ufs_swab32(unsigned swab, __u32 x) { if (swab == UFS_LITTLE_ENDIAN) return le32_to_cpu(x); else return be32_to_cpu(x); } extern __inline__ __const__ __u64 ufs_swab64(unsigned swab, __u64 x) { if (swab == UFS_LITTLE_ENDIAN) return le64_to_cpu(x); else return be64_to_cpu(x); } extern __inline__ __const__ __u16 ufs_swab16_add(unsigned swab, __u16 x, __u16 y) { return ufs_swab16(swab, ufs_swab16(swab, x) + y); } extern __inline__ __const__ __u32 ufs_swab32_add(unsigned swab, __u32 x, __u32 y) { return ufs_swab32(swab, ufs_swab32(swab, x) + y); } extern __inline__ __const__ __u64 ufs_swab64_add(unsigned swab, __u64 x, __u64 y) { return ufs_swab64(swab, ufs_swab64(swab, x) + y); } #endif /* byte sexuality */ #endif /* _UFS_SWAB_H */ |