2009-10-06 11:31:13 -07:00
# ifndef __CEPH_DECODE_H
# define __CEPH_DECODE_H
# include <asm/unaligned.h>
2010-02-02 16:11:19 -08:00
# include <linux/time.h>
2009-10-06 11:31:13 -07:00
2009-10-14 09:59:09 -07:00
# include "types.h"
2009-10-06 11:31:13 -07:00
/*
* in all cases ,
* void * * p pointer to position pointer
* void * end pointer to end of buffer ( last byte + 1 )
*/
2009-10-14 09:59:09 -07:00
static inline u64 ceph_decode_64 ( void * * p )
{
u64 v = get_unaligned_le64 ( * p ) ;
* p + = sizeof ( u64 ) ;
return v ;
}
static inline u32 ceph_decode_32 ( void * * p )
{
u32 v = get_unaligned_le32 ( * p ) ;
* p + = sizeof ( u32 ) ;
return v ;
}
static inline u16 ceph_decode_16 ( void * * p )
{
u16 v = get_unaligned_le16 ( * p ) ;
* p + = sizeof ( u16 ) ;
return v ;
}
static inline u8 ceph_decode_8 ( void * * p )
{
u8 v = * ( u8 * ) * p ;
( * p ) + + ;
return v ;
}
static inline void ceph_decode_copy ( void * * p , void * pv , size_t n )
{
memcpy ( pv , * p , n ) ;
* p + = n ;
}
2009-10-06 11:31:13 -07:00
/*
* bounds check input .
*/
# define ceph_decode_need(p, end, n, bad) \
do { \
if ( unlikely ( * ( p ) + ( n ) > ( end ) ) ) \
goto bad ; \
} while ( 0 )
# define ceph_decode_64_safe(p, end, v, bad) \
do { \
ceph_decode_need ( p , end , sizeof ( u64 ) , bad ) ; \
2009-10-14 09:59:09 -07:00
v = ceph_decode_64 ( p ) ; \
2009-10-06 11:31:13 -07:00
} while ( 0 )
# define ceph_decode_32_safe(p, end, v, bad) \
do { \
ceph_decode_need ( p , end , sizeof ( u32 ) , bad ) ; \
2009-10-14 09:59:09 -07:00
v = ceph_decode_32 ( p ) ; \
2009-10-06 11:31:13 -07:00
} while ( 0 )
# define ceph_decode_16_safe(p, end, v, bad) \
do { \
ceph_decode_need ( p , end , sizeof ( u16 ) , bad ) ; \
2009-10-14 09:59:09 -07:00
v = ceph_decode_16 ( p ) ; \
2009-10-06 11:31:13 -07:00
} while ( 0 )
2010-02-02 16:11:19 -08:00
# define ceph_decode_8_safe(p, end, v, bad) \
do { \
ceph_decode_need ( p , end , sizeof ( u8 ) , bad ) ; \
v = ceph_decode_8 ( p ) ; \
} while ( 0 )
2009-10-06 11:31:13 -07:00
# define ceph_decode_copy_safe(p, end, pv, n, bad) \
do { \
ceph_decode_need ( p , end , n , bad ) ; \
ceph_decode_copy ( p , pv , n ) ; \
} while ( 0 )
/*
* struct ceph_timespec < - > struct timespec
*/
2009-10-14 09:59:09 -07:00
static inline void ceph_decode_timespec ( struct timespec * ts ,
2009-11-03 15:17:56 -08:00
const struct ceph_timespec * tv )
2009-10-14 09:59:09 -07:00
{
ts - > tv_sec = le32_to_cpu ( tv - > tv_sec ) ;
ts - > tv_nsec = le32_to_cpu ( tv - > tv_nsec ) ;
}
static inline void ceph_encode_timespec ( struct ceph_timespec * tv ,
2009-11-03 15:17:56 -08:00
const struct timespec * ts )
2009-10-14 09:59:09 -07:00
{
tv - > tv_sec = cpu_to_le32 ( ts - > tv_sec ) ;
tv - > tv_nsec = cpu_to_le32 ( ts - > tv_nsec ) ;
}
2009-10-06 11:31:13 -07:00
2009-11-03 15:17:56 -08:00
/*
* sockaddr_storage < - > ceph_sockaddr
*/
static inline void ceph_encode_addr ( struct ceph_entity_addr * a )
{
a - > in_addr . ss_family = htons ( a - > in_addr . ss_family ) ;
}
static inline void ceph_decode_addr ( struct ceph_entity_addr * a )
{
a - > in_addr . ss_family = ntohs ( a - > in_addr . ss_family ) ;
2009-11-18 16:19:57 -08:00
WARN_ON ( a - > in_addr . ss_family = = 512 ) ;
2009-11-03 15:17:56 -08:00
}
2009-10-06 11:31:13 -07:00
/*
* encoders
*/
2009-10-14 09:59:09 -07:00
static inline void ceph_encode_64 ( void * * p , u64 v )
{
put_unaligned_le64 ( v , ( __le64 * ) * p ) ;
* p + = sizeof ( u64 ) ;
}
static inline void ceph_encode_32 ( void * * p , u32 v )
{
put_unaligned_le32 ( v , ( __le32 * ) * p ) ;
* p + = sizeof ( u32 ) ;
}
static inline void ceph_encode_16 ( void * * p , u16 v )
{
put_unaligned_le16 ( v , ( __le16 * ) * p ) ;
* p + = sizeof ( u16 ) ;
}
static inline void ceph_encode_8 ( void * * p , u8 v )
{
* ( u8 * ) * p = v ;
( * p ) + + ;
}
2009-11-18 16:19:57 -08:00
static inline void ceph_encode_copy ( void * * p , const void * s , int len )
{
memcpy ( * p , s , len ) ;
* p + = len ;
}
2009-10-06 11:31:13 -07:00
/*
* filepath , string encoders
*/
static inline void ceph_encode_filepath ( void * * p , void * end ,
u64 ino , const char * path )
{
u32 len = path ? strlen ( path ) : 0 ;
BUG_ON ( * p + sizeof ( ino ) + sizeof ( len ) + len > end ) ;
2010-01-27 14:28:10 -08:00
ceph_encode_8 ( p , 1 ) ;
2009-10-06 11:31:13 -07:00
ceph_encode_64 ( p , ino ) ;
ceph_encode_32 ( p , len ) ;
if ( len )
memcpy ( * p , path , len ) ;
* p + = len ;
}
static inline void ceph_encode_string ( void * * p , void * end ,
const char * s , u32 len )
{
BUG_ON ( * p + sizeof ( len ) + len > end ) ;
ceph_encode_32 ( p , len ) ;
if ( len )
memcpy ( * p , s , len ) ;
* p + = len ;
}
2010-02-02 16:11:19 -08:00
# define ceph_encode_need(p, end, n, bad) \
do { \
if ( unlikely ( * ( p ) + ( n ) > ( end ) ) ) \
goto bad ; \
} while ( 0 )
# define ceph_encode_64_safe(p, end, v, bad) \
do { \
ceph_encode_need ( p , end , sizeof ( u64 ) , bad ) ; \
ceph_encode_64 ( p , v ) ; \
} while ( 0 )
# define ceph_encode_32_safe(p, end, v, bad) \
do { \
ceph_encode_need ( p , end , sizeof ( u32 ) , bad ) ; \
ceph_encode_32 ( p , v ) ; \
} while ( 0 )
# define ceph_encode_16_safe(p, end, v, bad) \
do { \
ceph_encode_need ( p , end , sizeof ( u16 ) , bad ) ; \
ceph_encode_16 ( p , v ) ; \
} while ( 0 )
# define ceph_encode_copy_safe(p, end, pv, n, bad) \
do { \
ceph_encode_need ( p , end , n , bad ) ; \
ceph_encode_copy ( p , pv , n ) ; \
} while ( 0 )
2009-10-06 11:31:13 -07:00
# endif