linux/fs/xfs/xfs_dir2_sf.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_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
  28struct uio;
  29struct xfs_dabuf;
  30struct xfs_da_args;
  31struct xfs_dir2_block;
  32struct xfs_inode;
  33struct xfs_mount;
  34struct xfs_trans;
  35
  36/*
  37 * Inode number stored as 8 8-bit values.
  38 */
  39typedef 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 */
  46typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
  47
  48typedef 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 */
  58typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
  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 */
  68typedef 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 */
  72} __arch_pack xfs_dir2_sf_hdr_t;
  73
  74typedef 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 */
  79} __arch_pack xfs_dir2_sf_entry_t; 
  80
  81typedef 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
  86static 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
  93static 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}
  97
  98static inline xfs_intino_t
  99xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from)
 100{
 101        return ((sfp)->hdr.i8count == 0 ? \
 102                (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \
 103                (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8));
 104}
 105
 106static 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
 115static inline xfs_dir2_data_aoff_t
 116xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
 117{
 118        return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i);
 119}
 120
 121static inline void
 122xfs_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}
 126
 127static 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
 134static inline int
 135xfs_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
 142static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp)
 143{
 144        return ((xfs_dir2_sf_entry_t *) \
 145                ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count)));
 146}
 147
 148static inline xfs_dir2_sf_entry_t *
 149xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
 150{
 151        return ((xfs_dir2_sf_entry_t *) \
 152                ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep)));
 153}
 154
 155/*
 156 * Functions.
 157 */
 158extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
 159                                 struct xfs_dir2_block *block,
 160                                 xfs_dir2_sf_hdr_t *sfhp);
 161extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
 162                                int size, xfs_dir2_sf_hdr_t *sfhp);
 163extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
 164extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
 165extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
 166                                xfs_off_t *offset, filldir_t filldir);
 167extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
 168extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
 169extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
 170
 171#endif  /* __XFS_DIR2_SF_H__ */
 172