linux/fs/xfs/xfs_dir2_format.h
<<
>>
Prefs
   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 */
  41typedef __uint16_t      xfs_dir2_data_off_t;
  42#define NULLDATAOFF     0xffffU
  43typedef 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 */
  49typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
  50
  51/*
  52 * Offset in data space of a data entry.
  53 */
  54typedef __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 */
  61typedef xfs_off_t       xfs_dir2_off_t;
  62
  63/*
  64 * Directory block number (logical dirblk in file)
  65 */
  66typedef __uint32_t      xfs_dir2_db_t;
  67
  68/*
  69 * Inode number stored as 8 8-bit values.
  70 */
  71typedef 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 */
  78typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
  79
  80typedef 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 */
  97typedef 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
 103typedef 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
 113static 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
 120static inline xfs_dir2_data_aoff_t
 121xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
 122{
 123        return get_unaligned_be16(&sfep->offset.i);
 124}
 125
 126static inline void
 127xfs_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
 132static inline int
 133xfs_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
 142static inline struct xfs_dir2_sf_entry *
 143xfs_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
 149static inline struct xfs_dir2_sf_entry *
 150xfs_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 */
 212typedef 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 */
 222typedef 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 */
 234typedef 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 */
 247typedef 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 */
 257static 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 */
 266static inline __be16 *
 267xfs_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 */
 276static inline __be16 *
 277xfs_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 */
 326typedef 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 */
 335typedef 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 */
 343typedef struct xfs_dir2_leaf_tail {
 344        __be32                  bestcount;
 345} xfs_dir2_leaf_tail_t;
 346
 347/*
 348 * Leaf block.
 349 */
 350typedef 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
 359static 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 */
 368static inline struct xfs_dir2_leaf_tail *
 369xfs_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 */
 379static inline __be16 *
 380xfs_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 */
 388static inline xfs_dir2_off_t
 389xfs_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 */
 397static inline xfs_dir2_dataptr_t
 398xfs_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 */
 406static inline xfs_dir2_db_t
 407xfs_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 */
 416static inline xfs_dir2_db_t
 417xfs_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 */
 425static inline xfs_dir2_data_aoff_t
 426xfs_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 */
 435static inline xfs_dir2_data_aoff_t
 436xfs_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 */
 444static inline xfs_dir2_off_t
 445xfs_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 */
 455static inline xfs_dablk_t
 456xfs_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 */
 464static inline xfs_dablk_t
 465xfs_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 */
 473static inline xfs_dir2_dataptr_t
 474xfs_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 */
 483static inline xfs_dir2_db_t
 484xfs_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 */
 492static inline xfs_dir2_off_t
 493xfs_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
 510typedef 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
 517typedef 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
 523static 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 */
 532static inline xfs_dir2_db_t
 533xfs_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 */
 541static inline int
 542xfs_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
 573typedef 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 */
 581static inline struct xfs_dir2_block_tail *
 582xfs_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 */
 591static inline struct xfs_dir2_leaf_entry *
 592xfs_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__ */
 598
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.