1/* 2 * Copyright (c) 2000,2005 Silicon Graphics, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18#ifndef __XFS_DIR2_DATA_H__ 19#define __XFS_DIR2_DATA_H__ 20 21/* 22 * Directory format 2, data block structures. 23 */ 24 25struct xfs_dabuf; 26struct xfs_da_args; 27struct xfs_inode; 28struct xfs_trans; 29 30/* 31 * Constants. 32 */ 33#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */ 34#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */ 35#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG) 36#define XFS_DIR2_DATA_FREE_TAG 0xffff 37#define XFS_DIR2_DATA_FD_COUNT 3 38 39/* 40 * Directory address space divided into sections, 41 * spaces separated by 32GB. 42 */ 43#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) 44#define XFS_DIR2_DATA_SPACE 0 45#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) 46#define XFS_DIR2_DATA_FIRSTDB(mp) \ 47 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) 48 49/* 50 * Offsets of . and .. in data space (always block 0) 51 */ 52#define XFS_DIR2_DATA_DOT_OFFSET \ 53 ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) 54#define XFS_DIR2_DATA_DOTDOT_OFFSET \ 55 (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1)) 56#define XFS_DIR2_DATA_FIRST_OFFSET \ 57 (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2)) 58 59/* 60 * Structures. 61 */ 62 63/* 64 * Describe a free area in the data block. 65 * The freespace will be formatted as a xfs_dir2_data_unused_t. 66 */ 67typedef struct xfs_dir2_data_free { 68 __be16 offset; /* start of freespace */ 69 __be16 length; /* length of freespace */ 70} xfs_dir2_data_free_t; 71 72/* 73 * Header for the data blocks. 74 * Always at the beginning of a directory-sized block. 75 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3. 76 */ 77typedef struct xfs_dir2_data_hdr { 78 __be32 magic; /* XFS_DIR2_DATA_MAGIC */ 79 /* or XFS_DIR2_BLOCK_MAGIC */ 80 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; 81} xfs_dir2_data_hdr_t; 82 83/* 84 * Active entry in a data block. Aligned to 8 bytes. 85 * Tag appears as the last 2 bytes. 86 */ 87typedef struct xfs_dir2_data_entry { 88 __be64 inumber; /* inode number */ 89 __u8 namelen; /* name length */ 90 __u8 name[1]; /* name bytes, no null */ 91 /* variable offset */ 92 __be16 tag; /* starting offset of us */ 93} xfs_dir2_data_entry_t; 94 95/* 96 * Unused entry in a data block. Aligned to 8 bytes. 97 * Tag appears as the last 2 bytes. 98 */ 99typedef struct xfs_dir2_data_unused { 100 __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */ 101 __be16 length; /* total free length */ 102 /* variable offset */ 103 __be16 tag; /* starting offset of us */ 104} xfs_dir2_data_unused_t; 105 106typedef union { 107 xfs_dir2_data_entry_t entry; 108 xfs_dir2_data_unused_t unused; 109} xfs_dir2_data_union_t; 110 111/* 112 * Generic data block structure, for xfs_db. 113 */ 114typedef struct xfs_dir2_data { 115 xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */ 116 xfs_dir2_data_union_t u[1]; 117} xfs_dir2_data_t; 118 119/* 120 * Macros. 121 */ 122 123/* 124 * Size of a data entry. 125 */ 126static inline int xfs_dir2_data_entsize(int n) 127{ 128 return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ 129 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN); 130} 131 132/* 133 * Pointer to an entry's tag word. 134 */ 135static inline __be16 * 136xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) 137{ 138 return (__be16 *)((char *)dep + 139 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); 140} 141 142/* 143 * Pointer to a freespace's tag word. 144 */ 145static inline __be16 * 146xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) 147{ 148 return (__be16 *)((char *)dup + 149 be16_to_cpu(dup->length) - sizeof(__be16)); 150} 151 152/* 153 * Function declarations. 154 */ 155#ifdef DEBUG 156extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp); 157#else 158#define xfs_dir2_data_check(dp,bp) 159#endif 160extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d, 161 xfs_dir2_data_unused_t *dup); 162extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, 163 xfs_dir2_data_unused_t *dup, int *loghead); 164extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, 165 int *loghead); 166extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, 167 struct xfs_dabuf **bpp); 168extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, 169 xfs_dir2_data_entry_t *dep); 170extern void xfs_dir2_data_log_header(struct xfs_trans *tp, 171 struct xfs_dabuf *bp); 172extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp, 173 xfs_dir2_data_unused_t *dup); 174extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp, 175 xfs_dir2_data_aoff_t offset, 176 xfs_dir2_data_aoff_t len, int *needlogp, 177 int *needscanp); 178extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp, 179 xfs_dir2_data_unused_t *dup, 180 xfs_dir2_data_aoff_t offset, 181 xfs_dir2_data_aoff_t len, int *needlogp, 182 int *needscanp); 183 184#endif /* __XFS_DIR2_DATA_H__ */ 185