1 /* 2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 59 21 * Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 31 */ 32 #ifndef __XFS_DIR2_SF_H__ 33 #define __XFS_DIR2_SF_H__ 34 35 /* 36 * Directory layout when stored internal to an inode. 37 * 38 * Small directories are packed as tightly as possible so as to 39 * fit into the literal area of the inode. 40 */ 41 42 struct uio; 43 struct xfs_dabuf; 44 struct xfs_da_args; 45 struct xfs_dir2_block; 46 struct xfs_inode; 47 struct xfs_mount; 48 struct xfs_trans; 49 50 /* 51 * Maximum size of a shortform directory. 52 */ 53 #define XFS_DIR2_SF_MAX_SIZE \ 54 (XFS_DINODE_MAX_SIZE - (uint)sizeof(xfs_dinode_core_t) - \ 55 (uint)sizeof(xfs_agino_t)) 56 57 /* 58 * Inode number stored as 8 8-bit values. 59 */ 60 typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; 61 62 #define XFS_DIR2_SF_GET_INO8_ARCH(di,arch) \ 63 (xfs_ino_t)(DIRINO_GET_ARCH(&di,arch)) 64 #define XFS_DIR2_SF_GET_INO8(di) \ 65 XFS_DIR2_SF_GET_INO8_ARCH(di,ARCH_NOCONVERT) 66 67 /* 68 * Inode number stored as 4 8-bit values. 69 * Works a lot of the time, when all the inode numbers in a directory 70 * fit in 32 bits. 71 */ 72 typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; 73 #define XFS_DIR2_SF_GET_INO4_ARCH(di,arch) \ 74 (xfs_ino_t)(DIRINO4_GET_ARCH(&di,arch)) 75 #define XFS_DIR2_SF_GET_INO4(di) \ 76 XFS_DIR2_SF_GET_INO4_ARCH(di,ARCH_NOCONVERT) 77 78 typedef union { 79 xfs_dir2_ino8_t i8; 80 xfs_dir2_ino4_t i4; 81 } xfs_dir2_inou_t; 82 #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) 83 84 /* 85 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. 86 * Only need 16 bits, this is the byte offset into the single block form. 87 */ 88 typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t; 89 90 /* 91 * The parent directory has a dedicated field, and the self-pointer must 92 * be calculated on the fly. 93 * 94 * Entries are packed toward the top as tightly as possible. The header 95 * and the elements must be memcpy'd out into a work area to get correct 96 * alignment for the inode number fields. 97 */ 98 typedef struct xfs_dir2_sf_hdr { 99 __uint8_t count; /* count of entries */ 100 __uint8_t i8count; /* count of 8-byte inode #s */ 101 xfs_dir2_inou_t parent; /* parent dir inode number */ 102 } xfs_dir2_sf_hdr_t; 103 104 typedef struct xfs_dir2_sf_entry { 105 __uint8_t namelen; /* actual name length */ 106 xfs_dir2_sf_off_t offset; /* saved offset */ 107 __uint8_t name[1]; /* name, variable size */ 108 xfs_dir2_inou_t inumber; /* inode number, var. offset */ 109 } xfs_dir2_sf_entry_t; 110 111 typedef struct xfs_dir2_sf { 112 xfs_dir2_sf_hdr_t hdr; /* shortform header */ 113 xfs_dir2_sf_entry_t list[1]; /* shortform entries */ 114 } xfs_dir2_sf_t; 115 116 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_HDR_SIZE) 117 int xfs_dir2_sf_hdr_size(int i8count); 118 #define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count) 119 #else 120 #define XFS_DIR2_SF_HDR_SIZE(i8count) \ 121 ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ 122 ((i8count) == 0) * \ 123 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))) 124 #endif 125 126 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_INUMBERP) 127 xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep); 128 #define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep) 129 #else 130 #define XFS_DIR2_SF_INUMBERP(sfep) \ 131 ((xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]) 132 #endif 133 134 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_GET_INUMBER) 135 xfs_intino_t xfs_dir2_sf_get_inumber_arch(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from, 136 xfs_arch_t arch); 137 #define XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, from, arch) \ 138 xfs_dir2_sf_get_inumber_arch(sfp, from, arch) 139 140 #else 141 #define XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, from, arch) \ 142 ((sfp)->hdr.i8count == 0 ? \ 143 (xfs_intino_t)XFS_DIR2_SF_GET_INO4_ARCH(*(from), arch) : \ 144 (xfs_intino_t)XFS_DIR2_SF_GET_INO8_ARCH(*(from), arch)) 145 #endif 146 147 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_PUT_INUMBER) 148 void xfs_dir2_sf_put_inumber_arch(xfs_dir2_sf_t *sfp, xfs_ino_t *from, 149 xfs_dir2_inou_t *to, xfs_arch_t arch); 150 #define XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp,from,to,arch) \ 151 xfs_dir2_sf_put_inumber_arch(sfp,from,to,arch) 152 #else 153 #define XFS_DIR2_SF_PUT_INUMBER_ARCH(sfp,from,to,arch) \ 154 if ((sfp)->hdr.i8count == 0) { \ 155 DIRINO4_COPY_ARCH(from,to,arch); \ 156 } else { \ 157 DIRINO_COPY_ARCH(from,to,arch); \ 158 } 159 #endif 160 161 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_GET_OFFSET) 162 xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset_arch(xfs_dir2_sf_entry_t *sfep, 163 xfs_arch_t arch); 164 xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep); 165 #define XFS_DIR2_SF_GET_OFFSET_ARCH(sfep,arch) \ 166 xfs_dir2_sf_get_offset_arch(sfep,arch) 167 #else 168 #define XFS_DIR2_SF_GET_OFFSET_ARCH(sfep,arch) \ 169 INT_GET_UNALIGNED_16_ARCH(&(sfep)->offset.i,arch) 170 #endif 171 172 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_PUT_OFFSET) 173 void xfs_dir2_sf_put_offset_arch(xfs_dir2_sf_entry_t *sfep, 174 xfs_dir2_data_aoff_t off, xfs_arch_t arch); 175 #define XFS_DIR2_SF_PUT_OFFSET_ARCH(sfep,off,arch) \ 176 xfs_dir2_sf_put_offset_arch(sfep,off,arch) 177 #else 178 #define XFS_DIR2_SF_PUT_OFFSET_ARCH(sfep,off,arch) \ 179 INT_SET_UNALIGNED_16_ARCH(&(sfep)->offset.i,off,arch) 180 #endif 181 182 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_ENTSIZE_BYNAME) 183 int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len); 184 #define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \ 185 xfs_dir2_sf_entsize_byname(sfp,len) 186 #else 187 #define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) /* space a name uses */ \ 188 ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ 189 ((sfp)->hdr.i8count == 0) * \ 190 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))) 191 #endif 192 193 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_ENTSIZE_BYENTRY) 194 int xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep); 195 #define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \ 196 xfs_dir2_sf_entsize_byentry(sfp,sfep) 197 #else 198 #define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) /* space an entry uses */ \ 199 ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ 200 ((sfp)->hdr.i8count == 0) * \ 201 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))) 202 #endif 203 204 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_FIRSTENTRY) 205 xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp); 206 #define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp) 207 #else 208 #define XFS_DIR2_SF_FIRSTENTRY(sfp) /* first entry in struct */ \ 209 ((xfs_dir2_sf_entry_t *) \ 210 ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count))) 211 #endif 212 213 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_DIR2_SF_NEXTENTRY) 214 xfs_dir2_sf_entry_t *xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, 215 xfs_dir2_sf_entry_t *sfep); 216 #define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep) 217 #else 218 #define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) /* next entry in struct */ \ 219 ((xfs_dir2_sf_entry_t *) \ 220 ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep))) 221 #endif 222 223 /* 224 * Functions. 225 */ 226 227 extern int 228 xfs_dir2_block_sfsize(struct xfs_inode *dp, 229 struct xfs_dir2_block *block, 230 xfs_dir2_sf_hdr_t *sfhp); 231 232 extern int 233 xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, 234 int size, xfs_dir2_sf_hdr_t *sfhp); 235 236 extern int 237 xfs_dir2_sf_addname(struct xfs_da_args *args); 238 239 extern int 240 xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); 241 242 extern int 243 xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, 244 struct xfs_dirent *dbp, xfs_dir2_put_t put); 245 246 extern int 247 xfs_dir2_sf_lookup(struct xfs_da_args *args); 248 249 extern int 250 xfs_dir2_sf_removename(struct xfs_da_args *args); 251 252 extern int 253 xfs_dir2_sf_replace(struct xfs_da_args *args); 254 255 #endif /* __XFS_DIR2_SF_H__ */ 256