diff options
| author | Al Viro <viro@www.linux.org.uk> | 2005-05-01 11:59:19 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-01 11:59:19 -0400 |
| commit | f8e08a8466c4ac5f61b4bdb6338fd97eedb9c9e8 (patch) | |
| tree | 082b472e19d4b21f2ecb0eb486e961b16ffeaab0 | |
| parent | 6b9f5829e6e3af44f20c681e26524c637d4f82ff (diff) | |
[PATCH] reiserfs endianness: sanitize reiserfs_key union
Since we only access reiserfs_key ->u.k_offset_v2 guts in four helper
functions, we are free to sanitize those, as long as
- layout of the structure is unchanged (it's on-disk object)
- behaviour of these helpers is same as before.
Patch kills the mess with endianness-dependent bitfields and replaces them
with a single __le64. Helpers are switched to straightforward shift/and/or.
Benefits:
- exact same definitions for little- and big-endian architectures; no ifdefs
in sight.
- generate the same code on little-endian and improved on big-endian.
- doesn't rely on lousy bitfields handling in gcc codegenerator.
- happens to be standard C (unsigned long long is not a valid type for a
bitfield; it's a gccism and not well-implemented one, at that).
Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
Cc: <reiserfs-dev@namesys.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | include/linux/reiserfs_fs.h | 42 |
1 files changed, 7 insertions, 35 deletions
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index d445b682ce00..32148625fc2f 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h | |||
| @@ -381,57 +381,29 @@ struct offset_v1 { | |||
| 381 | } __attribute__ ((__packed__)); | 381 | } __attribute__ ((__packed__)); |
| 382 | 382 | ||
| 383 | struct offset_v2 { | 383 | struct offset_v2 { |
| 384 | #ifdef __LITTLE_ENDIAN | 384 | __le64 v; |
| 385 | /* little endian version */ | ||
| 386 | __u64 k_offset:60; | ||
| 387 | __u64 k_type: 4; | ||
| 388 | #else | ||
| 389 | /* big endian version */ | ||
| 390 | __u64 k_type: 4; | ||
| 391 | __u64 k_offset:60; | ||
| 392 | #endif | ||
| 393 | } __attribute__ ((__packed__)); | 385 | } __attribute__ ((__packed__)); |
| 394 | 386 | ||
| 395 | #ifndef __LITTLE_ENDIAN | ||
| 396 | typedef union { | ||
| 397 | struct offset_v2 offset_v2; | ||
| 398 | __u64 linear; | ||
| 399 | } __attribute__ ((__packed__)) offset_v2_esafe_overlay; | ||
| 400 | |||
| 401 | static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 ) | 387 | static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 ) |
| 402 | { | 388 | { |
| 403 | offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; | 389 | __u8 type = le64_to_cpu(v2->v) >> 60; |
| 404 | tmp.linear = le64_to_cpu( tmp.linear ); | 390 | return (type <= TYPE_MAXTYPE)?type:TYPE_ANY; |
| 405 | return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY; | ||
| 406 | } | 391 | } |
| 407 | 392 | ||
| 408 | static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type ) | 393 | static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type ) |
| 409 | { | 394 | { |
| 410 | offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2; | 395 | v2->v = (v2->v & cpu_to_le64(~0ULL>>4)) | cpu_to_le64((__u64)type<<60); |
| 411 | tmp->linear = le64_to_cpu(tmp->linear); | ||
| 412 | tmp->offset_v2.k_type = type; | ||
| 413 | tmp->linear = cpu_to_le64(tmp->linear); | ||
| 414 | } | 396 | } |
| 415 | 397 | ||
| 416 | static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 ) | 398 | static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 ) |
| 417 | { | 399 | { |
| 418 | offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; | 400 | return le64_to_cpu(v2->v) & (~0ULL>>4); |
| 419 | tmp.linear = le64_to_cpu( tmp.linear ); | ||
| 420 | return tmp.offset_v2.k_offset; | ||
| 421 | } | 401 | } |
| 422 | 402 | ||
| 423 | static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){ | 403 | static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){ |
| 424 | offset_v2_esafe_overlay *tmp = (offset_v2_esafe_overlay *)v2; | 404 | offset &= (~0ULL>>4); |
| 425 | tmp->linear = le64_to_cpu(tmp->linear); | 405 | v2->v = (v2->v & cpu_to_le64(15ULL<<60)) | cpu_to_le64(offset); |
| 426 | tmp->offset_v2.k_offset = offset; | ||
| 427 | tmp->linear = cpu_to_le64(tmp->linear); | ||
| 428 | } | 406 | } |
| 429 | #else | ||
| 430 | # define offset_v2_k_type(v2) ((v2)->k_type) | ||
| 431 | # define set_offset_v2_k_type(v2,val) (offset_v2_k_type(v2) = (val)) | ||
| 432 | # define offset_v2_k_offset(v2) ((v2)->k_offset) | ||
| 433 | # define set_offset_v2_k_offset(v2,val) (offset_v2_k_offset(v2) = (val)) | ||
| 434 | #endif | ||
| 435 | 407 | ||
| 436 | /* Key of an item determines its location in the S+tree, and | 408 | /* Key of an item determines its location in the S+tree, and |
| 437 | is composed of 4 components */ | 409 | is composed of 4 components */ |
