2005-04-17 02:20:36 +04:00
/*
2005-11-02 06:58:39 +03:00
* Copyright ( c ) 2000 , 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
2005-04-17 02:20:36 +04:00
* published by the Free Software Foundation .
*
2005-11-02 06:58:39 +03:00
* 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 .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* 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
2005-04-17 02:20:36 +04:00
*/
# ifndef __XFS_DIR2_DATA_H__
# define __XFS_DIR2_DATA_H__
/*
* Directory format 2 , data block structures .
*/
struct xfs_dabuf ;
struct xfs_da_args ;
struct xfs_inode ;
struct xfs_trans ;
/*
* Constants .
*/
# define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */
# define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
# define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
# define XFS_DIR2_DATA_FREE_TAG 0xffff
# define XFS_DIR2_DATA_FD_COUNT 3
/*
* Directory address space divided into sections ,
2009-03-29 11:55:42 +04:00
* spaces separated by 32 GB .
2005-04-17 02:20:36 +04:00
*/
# define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
# define XFS_DIR2_DATA_SPACE 0
# define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
# define XFS_DIR2_DATA_FIRSTDB(mp) \
2007-06-28 10:43:50 +04:00
xfs_dir2_byte_to_db ( mp , XFS_DIR2_DATA_OFFSET )
2005-04-17 02:20:36 +04:00
/*
* Offsets of . and . . in data space ( always block 0 )
*/
# define XFS_DIR2_DATA_DOT_OFFSET \
( ( xfs_dir2_data_aoff_t ) sizeof ( xfs_dir2_data_hdr_t ) )
# define XFS_DIR2_DATA_DOTDOT_OFFSET \
2007-06-28 10:43:50 +04:00
( XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize ( 1 ) )
2005-04-17 02:20:36 +04:00
# define XFS_DIR2_DATA_FIRST_OFFSET \
2007-06-28 10:43:50 +04:00
( XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize ( 2 ) )
2005-04-17 02:20:36 +04:00
/*
* Structures .
*/
/*
* Describe a free area in the data block .
* The freespace will be formatted as a xfs_dir2_data_unused_t .
*/
typedef struct xfs_dir2_data_free {
2006-03-17 09:26:52 +03:00
__be16 offset ; /* start of freespace */
__be16 length ; /* length of freespace */
2005-04-17 02:20:36 +04:00
} xfs_dir2_data_free_t ;
/*
* Header for the data blocks .
* Always at the beginning of a directory - sized block .
* The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
*/
typedef struct xfs_dir2_data_hdr {
2006-03-17 09:26:52 +03:00
__be32 magic ; /* XFS_DIR2_DATA_MAGIC */
2005-04-17 02:20:36 +04:00
/* or XFS_DIR2_BLOCK_MAGIC */
xfs_dir2_data_free_t bestfree [ XFS_DIR2_DATA_FD_COUNT ] ;
} xfs_dir2_data_hdr_t ;
/*
* Active entry in a data block . Aligned to 8 bytes .
* Tag appears as the last 2 bytes .
*/
typedef struct xfs_dir2_data_entry {
2006-06-09 08:48:37 +04:00
__be64 inumber ; /* inode number */
__u8 namelen ; /* name length */
__u8 name [ 1 ] ; /* name bytes, no null */
2005-04-17 02:20:36 +04:00
/* variable offset */
2006-06-09 08:48:37 +04:00
__be16 tag ; /* starting offset of us */
2005-04-17 02:20:36 +04:00
} xfs_dir2_data_entry_t ;
/*
* Unused entry in a data block . Aligned to 8 bytes .
* Tag appears as the last 2 bytes .
*/
typedef struct xfs_dir2_data_unused {
2006-03-17 09:27:37 +03:00
__be16 freetag ; /* XFS_DIR2_DATA_FREE_TAG */
__be16 length ; /* total free length */
2005-04-17 02:20:36 +04:00
/* variable offset */
2006-03-17 09:27:37 +03:00
__be16 tag ; /* starting offset of us */
2005-04-17 02:20:36 +04:00
} xfs_dir2_data_unused_t ;
typedef union {
xfs_dir2_data_entry_t entry ;
xfs_dir2_data_unused_t unused ;
} xfs_dir2_data_union_t ;
/*
* Generic data block structure , for xfs_db .
*/
typedef struct xfs_dir2_data {
xfs_dir2_data_hdr_t hdr ; /* magic XFS_DIR2_DATA_MAGIC */
xfs_dir2_data_union_t u [ 1 ] ;
} xfs_dir2_data_t ;
/*
* Macros .
*/
/*
* Size of a data entry .
*/
2005-11-02 06:38:42 +03:00
static inline int xfs_dir2_data_entsize ( int n )
{
return ( int ) roundup ( offsetof ( xfs_dir2_data_entry_t , name [ 0 ] ) + ( n ) + \
( uint ) sizeof ( xfs_dir2_data_off_t ) , XFS_DIR2_DATA_ALIGN ) ;
}
2005-04-17 02:20:36 +04:00
/*
* Pointer to an entry ' s tag word .
*/
2006-03-17 09:28:27 +03:00
static inline __be16 *
2005-11-02 06:38:42 +03:00
xfs_dir2_data_entry_tag_p ( xfs_dir2_data_entry_t * dep )
{
2006-03-17 09:28:27 +03:00
return ( __be16 * ) ( ( char * ) dep +
2007-06-28 10:43:50 +04:00
xfs_dir2_data_entsize ( dep - > namelen ) - sizeof ( __be16 ) ) ;
2005-11-02 06:38:42 +03:00
}
2005-04-17 02:20:36 +04:00
/*
* Pointer to a freespace ' s tag word .
*/
2006-03-17 09:27:47 +03:00
static inline __be16 *
2005-11-02 06:38:42 +03:00
xfs_dir2_data_unused_tag_p ( xfs_dir2_data_unused_t * dup )
{
2006-03-17 09:27:47 +03:00
return ( __be16 * ) ( ( char * ) dup +
be16_to_cpu ( dup - > length ) - sizeof ( __be16 ) ) ;
2005-11-02 06:38:42 +03:00
}
2005-04-17 02:20:36 +04:00
/*
* Function declarations .
*/
# ifdef DEBUG
2005-11-02 06:38:42 +03:00
extern void xfs_dir2_data_check ( struct xfs_inode * dp , struct xfs_dabuf * bp ) ;
2005-04-17 02:20:36 +04:00
# else
# define xfs_dir2_data_check(dp,bp)
# endif
2005-11-02 06:38:42 +03:00
extern xfs_dir2_data_free_t * xfs_dir2_data_freefind ( xfs_dir2_data_t * d ,
xfs_dir2_data_unused_t * dup ) ;
extern xfs_dir2_data_free_t * xfs_dir2_data_freeinsert ( xfs_dir2_data_t * d ,
xfs_dir2_data_unused_t * dup , int * loghead ) ;
extern void xfs_dir2_data_freescan ( struct xfs_mount * mp , xfs_dir2_data_t * d ,
2007-05-08 07:48:49 +04:00
int * loghead ) ;
2005-11-02 06:38:42 +03:00
extern int xfs_dir2_data_init ( struct xfs_da_args * args , xfs_dir2_db_t blkno ,
struct xfs_dabuf * * bpp ) ;
extern void xfs_dir2_data_log_entry ( struct xfs_trans * tp , struct xfs_dabuf * bp ,
2005-04-17 02:20:36 +04:00
xfs_dir2_data_entry_t * dep ) ;
2005-11-02 06:38:42 +03:00
extern void xfs_dir2_data_log_header ( struct xfs_trans * tp ,
struct xfs_dabuf * bp ) ;
extern void xfs_dir2_data_log_unused ( struct xfs_trans * tp , struct xfs_dabuf * bp ,
xfs_dir2_data_unused_t * dup ) ;
extern void xfs_dir2_data_make_free ( struct xfs_trans * tp , struct xfs_dabuf * bp ,
2005-04-17 02:20:36 +04:00
xfs_dir2_data_aoff_t offset ,
xfs_dir2_data_aoff_t len , int * needlogp ,
int * needscanp ) ;
2005-11-02 06:38:42 +03:00
extern void xfs_dir2_data_use_free ( struct xfs_trans * tp , struct xfs_dabuf * bp ,
2005-04-17 02:20:36 +04:00
xfs_dir2_data_unused_t * dup ,
xfs_dir2_data_aoff_t offset ,
xfs_dir2_data_aoff_t len , int * needlogp ,
int * needscanp ) ;
# endif /* __XFS_DIR2_DATA_H__ */