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