~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to fs/xfs/xfs_dir2_format.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2000-2001,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_FORMAT_H__
 
19
#define __XFS_DIR2_FORMAT_H__
 
20
 
 
21
/*
 
22
 * Directory version 2.
 
23
 *
 
24
 * There are 4 possible formats:
 
25
 *  - shortform - embedded into the inode
 
26
 *  - single block - data with embedded leaf at the end
 
27
 *  - multiple data blocks, single leaf+freeindex block
 
28
 *  - data blocks, node and leaf blocks (btree), freeindex blocks
 
29
 *
 
30
 * Note: many node blocks structures and constants are shared with the attr
 
31
 * code and defined in xfs_da_btree.h.
 
32
 */
 
33
 
 
34
#define XFS_DIR2_BLOCK_MAGIC    0x58443242      /* XD2B: single block dirs */
 
35
#define XFS_DIR2_DATA_MAGIC     0x58443244      /* XD2D: multiblock dirs */
 
36
#define XFS_DIR2_FREE_MAGIC     0x58443246      /* XD2F: free index blocks */
 
37
 
 
38
/*
 
39
 * Byte offset in data block and shortform entry.
 
40
 */
 
41
typedef __uint16_t      xfs_dir2_data_off_t;
 
42
#define NULLDATAOFF     0xffffU
 
43
typedef uint            xfs_dir2_data_aoff_t;   /* argument form */
 
44
 
 
45
/*
 
46
 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
 
47
 * Only need 16 bits, this is the byte offset into the single block form.
 
48
 */
 
49
typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
 
50
 
 
51
/*
 
52
 * Offset in data space of a data entry.
 
53
 */
 
54
typedef __uint32_t      xfs_dir2_dataptr_t;
 
55
#define XFS_DIR2_MAX_DATAPTR    ((xfs_dir2_dataptr_t)0xffffffff)
 
56
#define XFS_DIR2_NULL_DATAPTR   ((xfs_dir2_dataptr_t)0)
 
57
 
 
58
/*
 
59
 * Byte offset in a directory.
 
60
 */
 
61
typedef xfs_off_t       xfs_dir2_off_t;
 
62
 
 
63
/*
 
64
 * Directory block number (logical dirblk in file)
 
65
 */
 
66
typedef __uint32_t      xfs_dir2_db_t;
 
67
 
 
68
/*
 
69
 * Inode number stored as 8 8-bit values.
 
70
 */
 
71
typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
 
72
 
 
73
/*
 
74
 * Inode number stored as 4 8-bit values.
 
75
 * Works a lot of the time, when all the inode numbers in a directory
 
76
 * fit in 32 bits.
 
77
 */
 
78
typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
 
79
 
 
80
typedef union {
 
81
        xfs_dir2_ino8_t i8;
 
82
        xfs_dir2_ino4_t i4;
 
83
} xfs_dir2_inou_t;
 
84
#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
 
85
 
 
86
/*
 
87
 * Directory layout when stored internal to an inode.
 
88
 *
 
89
 * Small directories are packed as tightly as possible so as to fit into the
 
90
 * literal area of the inode.  These "shortform" directories consist of a
 
91
 * single xfs_dir2_sf_hdr header followed by zero or more xfs_dir2_sf_entry
 
92
 * structures.  Due the different inode number storage size and the variable
 
93
 * length name field in the xfs_dir2_sf_entry all these structure are
 
94
 * variable length, and the accessors in this file should be used to iterate
 
95
 * over them.
 
96
 */
 
97
typedef struct xfs_dir2_sf_hdr {
 
98
        __uint8_t               count;          /* count of entries */
 
99
        __uint8_t               i8count;        /* count of 8-byte inode #s */
 
100
        xfs_dir2_inou_t         parent;         /* parent dir inode number */
 
101
} __arch_pack xfs_dir2_sf_hdr_t;
 
102
 
 
103
typedef struct xfs_dir2_sf_entry {
 
104
        __u8                    namelen;        /* actual name length */
 
105
        xfs_dir2_sf_off_t       offset;         /* saved offset */
 
106
        __u8                    name[];         /* name, variable size */
 
107
        /*
 
108
         * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
 
109
         * variable offset after the name.
 
110
         */
 
111
} __arch_pack xfs_dir2_sf_entry_t;
 
112
 
 
113
static inline int xfs_dir2_sf_hdr_size(int i8count)
 
114
{
 
115
        return sizeof(struct xfs_dir2_sf_hdr) -
 
116
                (i8count == 0) *
 
117
                (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
 
118
}
 
119
 
 
120
static inline xfs_dir2_data_aoff_t
 
121
xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
 
122
{
 
123
        return get_unaligned_be16(&sfep->offset.i);
 
124
}
 
125
 
 
126
static inline void
 
127
xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
 
128
{
 
129
        put_unaligned_be16(off, &sfep->offset.i);
 
130
}
 
131
 
 
132
static inline int
 
133
xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
 
134
{
 
135
        return sizeof(struct xfs_dir2_sf_entry) +       /* namelen + offset */
 
136
                len +                                   /* name */
 
137
                (hdr->i8count ?                         /* ino */
 
138
                 sizeof(xfs_dir2_ino8_t) :
 
139
                 sizeof(xfs_dir2_ino4_t));
 
140
}
 
141
 
 
142
static inline struct xfs_dir2_sf_entry *
 
143
xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
 
144
{
 
145
        return (struct xfs_dir2_sf_entry *)
 
146
                ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
 
147
}
 
148
 
 
149
static inline struct xfs_dir2_sf_entry *
 
150
xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
 
151
                struct xfs_dir2_sf_entry *sfep)
 
152
{
 
153
        return (struct xfs_dir2_sf_entry *)
 
154
                ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
 
155
}
 
156
 
 
157
 
 
158
/*
 
159
 * Data block structures.
 
160
 *
 
161
 * A pure data block looks like the following drawing on disk:
 
162
 *
 
163
 *    +-------------------------------------------------+
 
164
 *    | xfs_dir2_data_hdr_t                             |
 
165
 *    +-------------------------------------------------+
 
166
 *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
 
167
 *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
 
168
 *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
 
169
 *    | ...                                             |
 
170
 *    +-------------------------------------------------+
 
171
 *    | unused space                                    |
 
172
 *    +-------------------------------------------------+
 
173
 *
 
174
 * As all the entries are variable size structures the accessors below should
 
175
 * be used to iterate over them.
 
176
 *
 
177
 * In addition to the pure data blocks for the data and node formats,
 
178
 * most structures are also used for the combined data/freespace "block"
 
179
 * format below.
 
180
 */
 
181
 
 
182
#define XFS_DIR2_DATA_ALIGN_LOG 3               /* i.e., 8 bytes */
 
183
#define XFS_DIR2_DATA_ALIGN     (1 << XFS_DIR2_DATA_ALIGN_LOG)
 
184
#define XFS_DIR2_DATA_FREE_TAG  0xffff
 
185
#define XFS_DIR2_DATA_FD_COUNT  3
 
186
 
 
187
/*
 
188
 * Directory address space divided into sections,
 
189
 * spaces separated by 32GB.
 
190
 */
 
191
#define XFS_DIR2_SPACE_SIZE     (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
 
192
#define XFS_DIR2_DATA_SPACE     0
 
193
#define XFS_DIR2_DATA_OFFSET    (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
 
194
#define XFS_DIR2_DATA_FIRSTDB(mp)       \
 
195
        xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
 
196
 
 
197
/*
 
198
 * Offsets of . and .. in data space (always block 0)
 
199
 */
 
200
#define XFS_DIR2_DATA_DOT_OFFSET        \
 
201
        ((xfs_dir2_data_aoff_t)sizeof(struct xfs_dir2_data_hdr))
 
202
#define XFS_DIR2_DATA_DOTDOT_OFFSET     \
 
203
        (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
 
204
#define XFS_DIR2_DATA_FIRST_OFFSET              \
 
205
        (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
 
206
 
 
207
/*
 
208
 * Describe a free area in the data block.
 
209
 *
 
210
 * The freespace will be formatted as a xfs_dir2_data_unused_t.
 
211
 */
 
212
typedef struct xfs_dir2_data_free {
 
213
        __be16                  offset;         /* start of freespace */
 
214
        __be16                  length;         /* length of freespace */
 
215
} xfs_dir2_data_free_t;
 
216
 
 
217
/*
 
218
 * Header for the data blocks.
 
219
 *
 
220
 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
 
221
 */
 
222
typedef struct xfs_dir2_data_hdr {
 
223
        __be32                  magic;          /* XFS_DIR2_DATA_MAGIC or */
 
224
                                                /* XFS_DIR2_BLOCK_MAGIC */
 
225
        xfs_dir2_data_free_t    bestfree[XFS_DIR2_DATA_FD_COUNT];
 
226
} xfs_dir2_data_hdr_t;
 
227
 
 
228
/*
 
229
 * Active entry in a data block.
 
230
 *
 
231
 * Aligned to 8 bytes.  After the variable length name field there is a
 
232
 * 2 byte tag field, which can be accessed using xfs_dir2_data_entry_tag_p.
 
233
 */
 
234
typedef struct xfs_dir2_data_entry {
 
235
        __be64                  inumber;        /* inode number */
 
236
        __u8                    namelen;        /* name length */
 
237
        __u8                    name[];         /* name bytes, no null */
 
238
     /* __be16                  tag; */         /* starting offset of us */
 
239
} xfs_dir2_data_entry_t;
 
240
 
 
241
/*
 
242
 * Unused entry in a data block.
 
243
 *
 
244
 * Aligned to 8 bytes.  Tag appears as the last 2 bytes and must be accessed
 
245
 * using xfs_dir2_data_unused_tag_p.
 
246
 */
 
247
typedef struct xfs_dir2_data_unused {
 
248
        __be16                  freetag;        /* XFS_DIR2_DATA_FREE_TAG */
 
249
        __be16                  length;         /* total free length */
 
250
                                                /* variable offset */
 
251
        __be16                  tag;            /* starting offset of us */
 
252
} xfs_dir2_data_unused_t;
 
253
 
 
254
/*
 
255
 * Size of a data entry.
 
256
 */
 
257
static inline int xfs_dir2_data_entsize(int n)
 
258
{
 
259
        return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
 
260
                 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
 
261
}
 
262
 
 
263
/*
 
264
 * Pointer to an entry's tag word.
 
265
 */
 
266
static inline __be16 *
 
267
xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
 
268
{
 
269
        return (__be16 *)((char *)dep +
 
270
                xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
 
271
}
 
272
 
 
273
/*
 
274
 * Pointer to a freespace's tag word.
 
275
 */
 
276
static inline __be16 *
 
277
xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
 
278
{
 
279
        return (__be16 *)((char *)dup +
 
280
                        be16_to_cpu(dup->length) - sizeof(__be16));
 
281
}
 
282
 
 
283
/*
 
284
 * Leaf block structures.
 
285
 *
 
286
 * A pure leaf block looks like the following drawing on disk:
 
287
 *
 
288
 *    +---------------------------+
 
289
 *    | xfs_dir2_leaf_hdr_t       |
 
290
 *    +---------------------------+
 
291
 *    | xfs_dir2_leaf_entry_t     |
 
292
 *    | xfs_dir2_leaf_entry_t     |
 
293
 *    | xfs_dir2_leaf_entry_t     |
 
294
 *    | xfs_dir2_leaf_entry_t     |
 
295
 *    | ...                       |
 
296
 *    +---------------------------+
 
297
 *    | xfs_dir2_data_off_t       |
 
298
 *    | xfs_dir2_data_off_t       |
 
299
 *    | xfs_dir2_data_off_t       |
 
300
 *    | ...                       |
 
301
 *    +---------------------------+
 
302
 *    | xfs_dir2_leaf_tail_t      |
 
303
 *    +---------------------------+
 
304
 *
 
305
 * The xfs_dir2_data_off_t members (bests) and tail are at the end of the block
 
306
 * for single-leaf (magic = XFS_DIR2_LEAF1_MAGIC) blocks only, but not present
 
307
 * for directories with separate leaf nodes and free space blocks
 
308
 * (magic = XFS_DIR2_LEAFN_MAGIC).
 
309
 *
 
310
 * As all the entries are variable size structures the accessors below should
 
311
 * be used to iterate over them.
 
312
 */
 
313
 
 
314
/*
 
315
 * Offset of the leaf/node space.  First block in this space
 
316
 * is the btree root.
 
317
 */
 
318
#define XFS_DIR2_LEAF_SPACE     1
 
319
#define XFS_DIR2_LEAF_OFFSET    (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
 
320
#define XFS_DIR2_LEAF_FIRSTDB(mp)       \
 
321
        xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
 
322
 
 
323
/*
 
324
 * Leaf block header.
 
325
 */
 
326
typedef struct xfs_dir2_leaf_hdr {
 
327
        xfs_da_blkinfo_t        info;           /* header for da routines */
 
328
        __be16                  count;          /* count of entries */
 
329
        __be16                  stale;          /* count of stale entries */
 
330
} xfs_dir2_leaf_hdr_t;
 
331
 
 
332
/*
 
333
 * Leaf block entry.
 
334
 */
 
335
typedef struct xfs_dir2_leaf_entry {
 
336
        __be32                  hashval;        /* hash value of name */
 
337
        __be32                  address;        /* address of data entry */
 
338
} xfs_dir2_leaf_entry_t;
 
339
 
 
340
/*
 
341
 * Leaf block tail.
 
342
 */
 
343
typedef struct xfs_dir2_leaf_tail {
 
344
        __be32                  bestcount;
 
345
} xfs_dir2_leaf_tail_t;
 
346
 
 
347
/*
 
348
 * Leaf block.
 
349
 */
 
350
typedef struct xfs_dir2_leaf {
 
351
        xfs_dir2_leaf_hdr_t     hdr;            /* leaf header */
 
352
        xfs_dir2_leaf_entry_t   ents[];         /* entries */
 
353
} xfs_dir2_leaf_t;
 
354
 
 
355
/*
 
356
 * DB blocks here are logical directory block numbers, not filesystem blocks.
 
357
 */
 
358
 
 
359
static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
 
360
{
 
361
        return (mp->m_dirblksize - (uint)sizeof(struct xfs_dir2_leaf_hdr)) /
 
362
                (uint)sizeof(struct xfs_dir2_leaf_entry);
 
363
}
 
364
 
 
365
/*
 
366
 * Get address of the bestcount field in the single-leaf block.
 
367
 */
 
368
static inline struct xfs_dir2_leaf_tail *
 
369
xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
 
370
{
 
371
        return (struct xfs_dir2_leaf_tail *)
 
372
                ((char *)lp + mp->m_dirblksize -
 
373
                  sizeof(struct xfs_dir2_leaf_tail));
 
374
}
 
375
 
 
376
/*
 
377
 * Get address of the bests array in the single-leaf block.
 
378
 */
 
379
static inline __be16 *
 
380
xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
 
381
{
 
382
        return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
 
383
}
 
384
 
 
385
/*
 
386
 * Convert dataptr to byte in file space
 
387
 */
 
388
static inline xfs_dir2_off_t
 
389
xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
 
390
{
 
391
        return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
 
392
}
 
393
 
 
394
/*
 
395
 * Convert byte in file space to dataptr.  It had better be aligned.
 
396
 */
 
397
static inline xfs_dir2_dataptr_t
 
398
xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
 
399
{
 
400
        return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
 
401
}
 
402
 
 
403
/*
 
404
 * Convert byte in space to (DB) block
 
405
 */
 
406
static inline xfs_dir2_db_t
 
407
xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
 
408
{
 
409
        return (xfs_dir2_db_t)
 
410
                (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
 
411
}
 
412
 
 
413
/*
 
414
 * Convert dataptr to a block number
 
415
 */
 
416
static inline xfs_dir2_db_t
 
417
xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
 
418
{
 
419
        return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
 
420
}
 
421
 
 
422
/*
 
423
 * Convert byte in space to offset in a block
 
424
 */
 
425
static inline xfs_dir2_data_aoff_t
 
426
xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
 
427
{
 
428
        return (xfs_dir2_data_aoff_t)(by &
 
429
                ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
 
430
}
 
431
 
 
432
/*
 
433
 * Convert dataptr to a byte offset in a block
 
434
 */
 
435
static inline xfs_dir2_data_aoff_t
 
436
xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
 
437
{
 
438
        return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
 
439
}
 
440
 
 
441
/*
 
442
 * Convert block and offset to byte in space
 
443
 */
 
444
static inline xfs_dir2_off_t
 
445
xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
 
446
                        xfs_dir2_data_aoff_t o)
 
447
{
 
448
        return ((xfs_dir2_off_t)db <<
 
449
                (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
 
450
}
 
451
 
 
452
/*
 
453
 * Convert block (DB) to block (dablk)
 
454
 */
 
455
static inline xfs_dablk_t
 
456
xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
 
457
{
 
458
        return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
 
459
}
 
460
 
 
461
/*
 
462
 * Convert byte in space to (DA) block
 
463
 */
 
464
static inline xfs_dablk_t
 
465
xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
 
466
{
 
467
        return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
 
468
}
 
469
 
 
470
/*
 
471
 * Convert block and offset to dataptr
 
472
 */
 
473
static inline xfs_dir2_dataptr_t
 
474
xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
 
475
                           xfs_dir2_data_aoff_t o)
 
476
{
 
477
        return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
 
478
}
 
479
 
 
480
/*
 
481
 * Convert block (dablk) to block (DB)
 
482
 */
 
483
static inline xfs_dir2_db_t
 
484
xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
 
485
{
 
486
        return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
 
487
}
 
488
 
 
489
/*
 
490
 * Convert block (dablk) to byte offset in space
 
491
 */
 
492
static inline xfs_dir2_off_t
 
493
xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
 
494
{
 
495
        return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
 
496
}
 
497
 
 
498
/*
 
499
 * Free space block defintions for the node format.
 
500
 */
 
501
 
 
502
/*
 
503
 * Offset of the freespace index.
 
504
 */
 
505
#define XFS_DIR2_FREE_SPACE     2
 
506
#define XFS_DIR2_FREE_OFFSET    (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
 
507
#define XFS_DIR2_FREE_FIRSTDB(mp)       \
 
508
        xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
 
509
 
 
510
typedef struct xfs_dir2_free_hdr {
 
511
        __be32                  magic;          /* XFS_DIR2_FREE_MAGIC */
 
512
        __be32                  firstdb;        /* db of first entry */
 
513
        __be32                  nvalid;         /* count of valid entries */
 
514
        __be32                  nused;          /* count of used entries */
 
515
} xfs_dir2_free_hdr_t;
 
516
 
 
517
typedef struct xfs_dir2_free {
 
518
        xfs_dir2_free_hdr_t     hdr;            /* block header */
 
519
        __be16                  bests[];        /* best free counts */
 
520
                                                /* unused entries are -1 */
 
521
} xfs_dir2_free_t;
 
522
 
 
523
static inline int xfs_dir2_free_max_bests(struct xfs_mount *mp)
 
524
{
 
525
        return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) /
 
526
                sizeof(xfs_dir2_data_off_t);
 
527
}
 
528
 
 
529
/*
 
530
 * Convert data space db to the corresponding free db.
 
531
 */
 
532
static inline xfs_dir2_db_t
 
533
xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
 
534
{
 
535
        return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp);
 
536
}
 
537
 
 
538
/*
 
539
 * Convert data space db to the corresponding index in a free db.
 
540
 */
 
541
static inline int
 
542
xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
 
543
{
 
544
        return db % xfs_dir2_free_max_bests(mp);
 
545
}
 
546
 
 
547
/*
 
548
 * Single block format.
 
549
 *
 
550
 * The single block format looks like the following drawing on disk:
 
551
 *
 
552
 *    +-------------------------------------------------+
 
553
 *    | xfs_dir2_data_hdr_t                             |
 
554
 *    +-------------------------------------------------+
 
555
 *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
 
556
 *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
 
557
 *    | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t :
 
558
 *    | ...                                             |
 
559
 *    +-------------------------------------------------+
 
560
 *    | unused space                                    |
 
561
 *    +-------------------------------------------------+
 
562
 *    | ...                                             |
 
563
 *    | xfs_dir2_leaf_entry_t                           |
 
564
 *    | xfs_dir2_leaf_entry_t                           |
 
565
 *    +-------------------------------------------------+
 
566
 *    | xfs_dir2_block_tail_t                           |
 
567
 *    +-------------------------------------------------+
 
568
 *
 
569
 * As all the entries are variable size structures the accessors below should
 
570
 * be used to iterate over them.
 
571
 */
 
572
 
 
573
typedef struct xfs_dir2_block_tail {
 
574
        __be32          count;                  /* count of leaf entries */
 
575
        __be32          stale;                  /* count of stale lf entries */
 
576
} xfs_dir2_block_tail_t;
 
577
 
 
578
/*
 
579
 * Pointer to the leaf header embedded in a data block (1-block format)
 
580
 */
 
581
static inline struct xfs_dir2_block_tail *
 
582
xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
 
583
{
 
584
        return ((struct xfs_dir2_block_tail *)
 
585
                ((char *)hdr + mp->m_dirblksize)) - 1;
 
586
}
 
587
 
 
588
/*
 
589
 * Pointer to the leaf entries embedded in a data block (1-block format)
 
590
 */
 
591
static inline struct xfs_dir2_leaf_entry *
 
592
xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
 
593
{
 
594
        return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
 
595
}
 
596
 
 
597
#endif /* __XFS_DIR2_FORMAT_H__ */