2  * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
 
   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.
 
   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.
 
  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
 
  18 #ifndef __XFS_ATTR_LEAF_H__
 
  19 #define __XFS_ATTR_LEAF_H__
 
  22  * Attribute storage layout, internal structure, access macros, etc.
 
  24  * Attribute lists are structured around Btrees where all the data
 
  25  * elements are in the leaf nodes.  Attribute names are hashed into an int,
 
  26  * then that int is used as the index into the Btree.  Since the hashval
 
  27  * of an attribute name may not be unique, we may have duplicate keys.  The
 
  28  * internal links in the Btree are logical block offsets into the file.
 
  32 struct attrlist_cursor_kern;
 
  37 struct xfs_da_state_blk;
 
  41 /*========================================================================
 
  42  * Attribute structure when equal to XFS_LBSIZE(mp) bytes.
 
  43  *========================================================================*/
 
  46  * This is the structure of the leaf nodes in the Btree.
 
  48  * Struct leaf_entry's are packed from the top.  Name/values grow from the
 
  49  * bottom but are not packed.  The freemap contains run-length-encoded entries
 
  50  * for the free bytes after the leaf_entry's, but only the N largest such,
 
  51  * smaller runs are dropped.  When the freemap doesn't show enough space
 
  52  * for an allocation, we compact the name/value area and try again.  If we
 
  53  * still don't have enough space, then we have to split the block.  The
 
  54  * name/value structs (both local and remote versions) must be 32bit aligned.
 
  56  * Since we have duplicate hash keys, for each key that matches, compare
 
  57  * the actual name string.  The root and intermediate node search always
 
  58  * takes the first-in-the-block key match found, so we should only have
 
  59  * to work "forw"ard.  If none matches, continue with the "forw"ard leaf
 
  60  * nodes until the hash key changes or the attribute name is found.
 
  62  * We store the fact that an attribute is a ROOT/USER/SECURE attribute in
 
  63  * the leaf_entry.  The namespaces are independent only because we also look
 
  64  * at the namespace bit when we are looking for a matching attribute name.
 
  66  * We also store an "incomplete" bit in the leaf_entry.  It shows that an
 
  67  * attribute is in the middle of being created and should not be shown to
 
  68  * the user if we crash during the time that the bit is set.  We clear the
 
  69  * bit when we have finished setting up the attribute.  We do this because
 
  70  * we cannot create some large attributes inside a single transaction, and we
 
  71  * need some indication that we weren't finished if we crash in the middle.
 
  73 #define XFS_ATTR_LEAF_MAPSIZE   3       /* how many freespace slots */
 
  75 typedef struct xfs_attr_leaf_map {      /* RLE map of free bytes */
 
  76         __uint16_t      base;           /* base of free region */
 
  77         __uint16_t      size;           /* length of free region */
 
  78 } xfs_attr_leaf_map_t;
 
  80 typedef struct xfs_attr_leaf_hdr {      /* constant-structure header block */
 
  81         xfs_da_blkinfo_t info;          /* block type, links, etc. */
 
  82         __uint16_t      count;          /* count of active leaf_entry's */
 
  83         __uint16_t      usedbytes;      /* num bytes of names/values stored */
 
  84         __uint16_t      firstused;      /* first used byte in name area */
 
  85         __uint8_t       holes;          /* != 0 if blk needs compaction */
 
  87         xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE];
 
  88                                         /* N largest free regions */
 
  89 } xfs_attr_leaf_hdr_t;
 
  91 typedef struct xfs_attr_leaf_entry {    /* sorted on key, not name */
 
  92         xfs_dahash_t    hashval;        /* hash value of name */
 
  93         __uint16_t      nameidx;        /* index into buffer of name/value */
 
  94         __uint8_t       flags;          /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
 
  95         __uint8_t       pad2;           /* unused pad byte */
 
  96 } xfs_attr_leaf_entry_t;
 
  98 typedef struct xfs_attr_leaf_name_local {
 
  99         __uint16_t      valuelen;       /* number of bytes in value */
 
 100         __uint8_t       namelen;        /* length of name bytes */
 
 101         __uint8_t       nameval[1];     /* name/value bytes */
 
 102 } xfs_attr_leaf_name_local_t;
 
 104 typedef struct xfs_attr_leaf_name_remote {
 
 105         xfs_dablk_t     valueblk;       /* block number of value bytes */
 
 106         __uint32_t      valuelen;       /* number of bytes in value */
 
 107         __uint8_t       namelen;        /* length of name bytes */
 
 108         __uint8_t       name[1];        /* name bytes */
 
 109 } xfs_attr_leaf_name_remote_t;
 
 111 typedef struct xfs_attr_leafblock {
 
 112         xfs_attr_leaf_hdr_t     hdr;    /* constant-structure header block */
 
 113         xfs_attr_leaf_entry_t   entries[1];     /* sorted on key, not name */
 
 114         xfs_attr_leaf_name_local_t namelist;    /* grows from bottom of buf */
 
 115         xfs_attr_leaf_name_remote_t valuelist;  /* grows from bottom of buf */
 
 116 } xfs_attr_leafblock_t;
 
 119  * Flags used in the leaf_entry[i].flags field.
 
 120  * NOTE: the INCOMPLETE bit must not collide with the flags bits specified
 
 121  * on the system call, they are "or"ed together for various operations.
 
 123 #define XFS_ATTR_LOCAL_BIT      0       /* attr is stored locally */
 
 124 #define XFS_ATTR_ROOT_BIT       1       /* limit access to trusted attrs */
 
 125 #define XFS_ATTR_SECURE_BIT     2       /* limit access to secure attrs */
 
 126 #define XFS_ATTR_INCOMPLETE_BIT 7       /* attr in middle of create/delete */
 
 127 #define XFS_ATTR_LOCAL          (1 << XFS_ATTR_LOCAL_BIT)
 
 128 #define XFS_ATTR_ROOT           (1 << XFS_ATTR_ROOT_BIT)
 
 129 #define XFS_ATTR_SECURE         (1 << XFS_ATTR_SECURE_BIT)
 
 130 #define XFS_ATTR_INCOMPLETE     (1 << XFS_ATTR_INCOMPLETE_BIT)
 
 133  * Alignment for namelist and valuelist entries (since they are mixed
 
 134  * there can be only one alignment value)
 
 136 #define XFS_ATTR_LEAF_NAME_ALIGN        ((uint)sizeof(xfs_dablk_t))
 
 139  * Cast typed pointers for "local" and "remote" name/value structs.
 
 141 #define XFS_ATTR_LEAF_NAME_REMOTE(leafp,idx)    \
 
 142         xfs_attr_leaf_name_remote(leafp,idx)
 
 143 static inline xfs_attr_leaf_name_remote_t *
 
 144 xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
 
 146         return (xfs_attr_leaf_name_remote_t *) &((char *)
 
 147                 (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
 
 150 #define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx)     \
 
 151         xfs_attr_leaf_name_local(leafp,idx)
 
 152 static inline xfs_attr_leaf_name_local_t *
 
 153 xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
 
 155         return (xfs_attr_leaf_name_local_t *) &((char *)
 
 156                 (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
 
 159 #define XFS_ATTR_LEAF_NAME(leafp,idx)           \
 
 160         xfs_attr_leaf_name(leafp,idx)
 
 161 static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
 
 164                 (leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)]);
 
 168  * Calculate total bytes used (including trailing pad for alignment) for
 
 169  * a "local" name/value structure, a "remote" name/value structure, and
 
 170  * a pointer which might be either.
 
 172 #define XFS_ATTR_LEAF_ENTSIZE_REMOTE(nlen)      \
 
 173         xfs_attr_leaf_entsize_remote(nlen)
 
 174 static inline int xfs_attr_leaf_entsize_remote(int nlen)
 
 176         return ((uint)sizeof(xfs_attr_leaf_name_remote_t) - 1 + (nlen) + \
 
 177                 XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1);
 
 180 #define XFS_ATTR_LEAF_ENTSIZE_LOCAL(nlen,vlen)  \
 
 181         xfs_attr_leaf_entsize_local(nlen,vlen)
 
 182 static inline int xfs_attr_leaf_entsize_local(int nlen, int vlen)
 
 184         return ((uint)sizeof(xfs_attr_leaf_name_local_t) - 1 + (nlen) + (vlen) +
 
 185                 XFS_ATTR_LEAF_NAME_ALIGN - 1) & ~(XFS_ATTR_LEAF_NAME_ALIGN - 1);
 
 188 #define XFS_ATTR_LEAF_ENTSIZE_LOCAL_MAX(bsize)  \
 
 189         xfs_attr_leaf_entsize_local_max(bsize)
 
 190 static inline int xfs_attr_leaf_entsize_local_max(int bsize)
 
 192         return (((bsize) >> 1) + ((bsize) >> 2));
 
 196 /*========================================================================
 
 197  * Structure used to pass context around among the routines.
 
 198  *========================================================================*/
 
 200 typedef struct xfs_attr_list_context {
 
 201         struct xfs_inode                *dp;    /* inode */
 
 202         struct attrlist_cursor_kern     *cursor;/* position in list */
 
 203         struct attrlist                 *alist; /* output buffer */
 
 204         int                             count;  /* num used entries */
 
 205         int                             dupcnt; /* count dup hashvals seen */
 
 206         int                             bufsize;/* total buffer size */
 
 207         int                             firstu; /* first used byte in buffer */
 
 208         int                             flags;  /* from VOP call */
 
 209         int                             resynch;/* T/F: resynch with cursor */
 
 210 } xfs_attr_list_context_t;
 
 213  * Used to keep a list of "remote value" extents when unlinking an inode.
 
 215 typedef struct xfs_attr_inactive_list {
 
 216         xfs_dablk_t     valueblk;       /* block number of value bytes */
 
 217         int             valuelen;       /* number of bytes in value */
 
 218 } xfs_attr_inactive_list_t;
 
 221 /*========================================================================
 
 222  * Function prototypes for the kernel.
 
 223  *========================================================================*/
 
 226  * Internal routines when attribute fork size < XFS_LITINO(mp).
 
 228 void    xfs_attr_shortform_create(struct xfs_da_args *args);
 
 229 void    xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff);
 
 230 int     xfs_attr_shortform_lookup(struct xfs_da_args *args);
 
 231 int     xfs_attr_shortform_getvalue(struct xfs_da_args *args);
 
 232 int     xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
 
 233 int     xfs_attr_shortform_remove(struct xfs_da_args *args);
 
 234 int     xfs_attr_shortform_list(struct xfs_attr_list_context *context);
 
 235 int     xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp);
 
 236 int     xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes);
 
 240  * Internal routines when attribute fork size == XFS_LBSIZE(mp).
 
 242 int     xfs_attr_leaf_to_node(struct xfs_da_args *args);
 
 243 int     xfs_attr_leaf_to_shortform(struct xfs_dabuf *bp,
 
 244                                    struct xfs_da_args *args, int forkoff);
 
 245 int     xfs_attr_leaf_clearflag(struct xfs_da_args *args);
 
 246 int     xfs_attr_leaf_setflag(struct xfs_da_args *args);
 
 247 int     xfs_attr_leaf_flipflags(xfs_da_args_t *args);
 
 250  * Routines used for growing the Btree.
 
 252 int     xfs_attr_leaf_split(struct xfs_da_state *state,
 
 253                                    struct xfs_da_state_blk *oldblk,
 
 254                                    struct xfs_da_state_blk *newblk);
 
 255 int     xfs_attr_leaf_lookup_int(struct xfs_dabuf *leaf,
 
 256                                         struct xfs_da_args *args);
 
 257 int     xfs_attr_leaf_getvalue(struct xfs_dabuf *bp, struct xfs_da_args *args);
 
 258 int     xfs_attr_leaf_add(struct xfs_dabuf *leaf_buffer,
 
 259                                  struct xfs_da_args *args);
 
 260 int     xfs_attr_leaf_remove(struct xfs_dabuf *leaf_buffer,
 
 261                                     struct xfs_da_args *args);
 
 262 int     xfs_attr_leaf_list_int(struct xfs_dabuf *bp,
 
 263                                       struct xfs_attr_list_context *context);
 
 266  * Routines used for shrinking the Btree.
 
 268 int     xfs_attr_leaf_toosmall(struct xfs_da_state *state, int *retval);
 
 269 void    xfs_attr_leaf_unbalance(struct xfs_da_state *state,
 
 270                                        struct xfs_da_state_blk *drop_blk,
 
 271                                        struct xfs_da_state_blk *save_blk);
 
 272 int     xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
 
 277 xfs_dahash_t    xfs_attr_leaf_lasthash(struct xfs_dabuf *bp, int *count);
 
 278 int     xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
 
 279                                    struct xfs_dabuf *leaf2_bp);
 
 280 int     xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
 
 282 int     xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
 
 284 #endif  /* __XFS_ATTR_LEAF_H__ */