]>
Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
7b718769 NS |
2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | |
1da177e4 | 4 | * |
7b718769 NS |
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 | |
1da177e4 LT |
7 | * published by the Free Software Foundation. |
8 | * | |
7b718769 NS |
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. | |
1da177e4 | 13 | * |
7b718769 NS |
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 | |
1da177e4 LT |
17 | */ |
18 | #ifndef __XFS_DIR2_SF_H__ | |
19 | #define __XFS_DIR2_SF_H__ | |
20 | ||
21 | /* | |
22 | * Directory layout when stored internal to an inode. | |
23 | * | |
24 | * Small directories are packed as tightly as possible so as to | |
25 | * fit into the literal area of the inode. | |
26 | */ | |
27 | ||
28 | struct uio; | |
29 | struct xfs_dabuf; | |
30 | struct xfs_da_args; | |
31 | struct xfs_dir2_block; | |
32 | struct xfs_inode; | |
33 | struct xfs_mount; | |
34 | struct xfs_trans; | |
35 | ||
36 | /* | |
37 | * Maximum size of a shortform directory. | |
38 | */ | |
39 | #define XFS_DIR2_SF_MAX_SIZE \ | |
40 | (XFS_DINODE_MAX_SIZE - (uint)sizeof(xfs_dinode_core_t) - \ | |
41 | (uint)sizeof(xfs_agino_t)) | |
42 | ||
43 | /* | |
44 | * Inode number stored as 8 8-bit values. | |
45 | */ | |
46 | typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t; | |
47 | ||
48 | /* | |
49 | * Inode number stored as 4 8-bit values. | |
50 | * Works a lot of the time, when all the inode numbers in a directory | |
51 | * fit in 32 bits. | |
52 | */ | |
53 | typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t; | |
54 | ||
55 | typedef union { | |
56 | xfs_dir2_ino8_t i8; | |
57 | xfs_dir2_ino4_t i4; | |
58 | } xfs_dir2_inou_t; | |
59 | #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) | |
60 | ||
61 | /* | |
62 | * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t. | |
63 | * Only need 16 bits, this is the byte offset into the single block form. | |
64 | */ | |
ae23a5e8 | 65 | typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t; |
1da177e4 LT |
66 | |
67 | /* | |
68 | * The parent directory has a dedicated field, and the self-pointer must | |
69 | * be calculated on the fly. | |
70 | * | |
71 | * Entries are packed toward the top as tightly as possible. The header | |
72 | * and the elements must be memcpy'd out into a work area to get correct | |
73 | * alignment for the inode number fields. | |
74 | */ | |
75 | typedef struct xfs_dir2_sf_hdr { | |
76 | __uint8_t count; /* count of entries */ | |
77 | __uint8_t i8count; /* count of 8-byte inode #s */ | |
78 | xfs_dir2_inou_t parent; /* parent dir inode number */ | |
ae23a5e8 | 79 | } __arch_pack xfs_dir2_sf_hdr_t; |
1da177e4 LT |
80 | |
81 | typedef struct xfs_dir2_sf_entry { | |
82 | __uint8_t namelen; /* actual name length */ | |
83 | xfs_dir2_sf_off_t offset; /* saved offset */ | |
84 | __uint8_t name[1]; /* name, variable size */ | |
85 | xfs_dir2_inou_t inumber; /* inode number, var. offset */ | |
ae23a5e8 | 86 | } __arch_pack xfs_dir2_sf_entry_t; |
1da177e4 LT |
87 | |
88 | typedef struct xfs_dir2_sf { | |
89 | xfs_dir2_sf_hdr_t hdr; /* shortform header */ | |
90 | xfs_dir2_sf_entry_t list[1]; /* shortform entries */ | |
91 | } xfs_dir2_sf_t; | |
92 | ||
a844f451 NS |
93 | static inline int xfs_dir2_sf_hdr_size(int i8count) |
94 | { | |
95 | return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ | |
96 | ((i8count) == 0) * \ | |
97 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | |
98 | } | |
99 | ||
a844f451 NS |
100 | static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) |
101 | { | |
102 | return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; | |
103 | } | |
1da177e4 | 104 | |
a844f451 NS |
105 | static inline xfs_intino_t |
106 | xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) | |
107 | { | |
108 | return ((sfp)->hdr.i8count == 0 ? \ | |
1da177e4 | 109 | (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \ |
a844f451 NS |
110 | (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); |
111 | } | |
1da177e4 | 112 | |
a844f451 NS |
113 | static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, |
114 | xfs_dir2_inou_t *to) | |
115 | { | |
116 | if ((sfp)->hdr.i8count == 0) | |
117 | XFS_PUT_DIR_INO4(*(from), (to)->i4); | |
118 | else | |
119 | XFS_PUT_DIR_INO8(*(from), (to)->i8); | |
120 | } | |
121 | ||
a844f451 NS |
122 | static inline xfs_dir2_data_aoff_t |
123 | xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) | |
124 | { | |
125 | return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); | |
126 | } | |
1da177e4 | 127 | |
a844f451 NS |
128 | static inline void |
129 | xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) | |
130 | { | |
131 | INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); | |
132 | } | |
1da177e4 | 133 | |
a844f451 NS |
134 | static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) |
135 | { | |
136 | return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ | |
137 | ((sfp)->hdr.i8count == 0) * \ | |
138 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | |
139 | } | |
140 | ||
a844f451 NS |
141 | static inline int |
142 | xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | |
143 | { | |
144 | return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ | |
145 | ((sfp)->hdr.i8count == 0) * \ | |
146 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | |
147 | } | |
148 | ||
a844f451 NS |
149 | static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) |
150 | { | |
151 | return ((xfs_dir2_sf_entry_t *) \ | |
bbaaf538 | 152 | ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count))); |
a844f451 NS |
153 | } |
154 | ||
a844f451 NS |
155 | static inline xfs_dir2_sf_entry_t * |
156 | xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | |
157 | { | |
158 | return ((xfs_dir2_sf_entry_t *) \ | |
bbaaf538 | 159 | ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); |
a844f451 | 160 | } |
1da177e4 LT |
161 | |
162 | /* | |
163 | * Functions. | |
164 | */ | |
a844f451 NS |
165 | extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, |
166 | struct xfs_dir2_block *block, | |
167 | xfs_dir2_sf_hdr_t *sfhp); | |
168 | extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, | |
169 | int size, xfs_dir2_sf_hdr_t *sfhp); | |
170 | extern int xfs_dir2_sf_addname(struct xfs_da_args *args); | |
171 | extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); | |
051e7cd4 CH |
172 | extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent, |
173 | xfs_off_t *offset, filldir_t filldir); | |
a844f451 NS |
174 | extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); |
175 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); | |
176 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); | |
1da177e4 LT |
177 | |
178 | #endif /* __XFS_DIR2_SF_H__ */ |