xfs: use generic get_unaligned_beXX helpers
[pandora-kernel.git] / fs / xfs / xfs_dir2_sf.h
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 fit into the
25  * literal area of the inode.  They consist of a single xfs_dir2_sf_hdr header
26  * followed by zero or more xfs_dir2_sf_entry structures.  Due the different
27  * inode number storage size and the variable length name field in
28  * the xfs_dir2_sf_entry all these structure are variable length, and the
29  * accessors in this file should be used to iterate over them.
30  */
31
32 struct uio;
33 struct xfs_dabuf;
34 struct xfs_da_args;
35 struct xfs_dir2_data_hdr;
36 struct xfs_inode;
37 struct xfs_mount;
38 struct xfs_trans;
39
40 /*
41  * Inode number stored as 8 8-bit values.
42  */
43 typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
44
45 /*
46  * Inode number stored as 4 8-bit values.
47  * Works a lot of the time, when all the inode numbers in a directory
48  * fit in 32 bits.
49  */
50 typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
51
52 typedef union {
53         xfs_dir2_ino8_t i8;
54         xfs_dir2_ino4_t i4;
55 } xfs_dir2_inou_t;
56 #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
57
58 /*
59  * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
60  * Only need 16 bits, this is the byte offset into the single block form.
61  */
62 typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
63
64 /*
65  * The parent directory has a dedicated field, and the self-pointer must
66  * be calculated on the fly.
67  *
68  * Entries are packed toward the top as tightly as possible, and thus may
69  * be misaligned.  Care needs to be taken to access them through special
70  * helpers or copy them into aligned variables first.
71  */
72 typedef struct xfs_dir2_sf_hdr {
73         __uint8_t               count;          /* count of entries */
74         __uint8_t               i8count;        /* count of 8-byte inode #s */
75         xfs_dir2_inou_t         parent;         /* parent dir inode number */
76 } __arch_pack xfs_dir2_sf_hdr_t;
77
78 typedef struct xfs_dir2_sf_entry {
79         __u8                    namelen;        /* actual name length */
80         xfs_dir2_sf_off_t       offset;         /* saved offset */
81         __u8                    name[];         /* name, variable size */
82         /*
83          * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
84          * variable offset after the name.
85          */
86 } __arch_pack xfs_dir2_sf_entry_t; 
87
88 static inline int xfs_dir2_sf_hdr_size(int i8count)
89 {
90         return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \
91                 ((i8count) == 0) * \
92                 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
93 }
94
95 static inline xfs_dir2_data_aoff_t
96 xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
97 {
98         return get_unaligned_be16(&sfep->offset.i);
99 }
100
101 static inline void
102 xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
103 {
104         put_unaligned_be16(off, &sfep->offset.i);
105 }
106
107 static inline int
108 xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
109 {
110         return sizeof(struct xfs_dir2_sf_entry) +       /* namelen + offset */
111                 len +                                   /* name */
112                 (hdr->i8count ?                         /* ino */
113                  sizeof(xfs_dir2_ino8_t) :
114                  sizeof(xfs_dir2_ino4_t));
115 }
116
117 static inline struct xfs_dir2_sf_entry *
118 xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
119 {
120         return (struct xfs_dir2_sf_entry *)
121                 ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
122 }
123
124 static inline struct xfs_dir2_sf_entry *
125 xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
126                 struct xfs_dir2_sf_entry *sfep)
127 {
128         return (struct xfs_dir2_sf_entry *)
129                 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
130 }
131
132 /*
133  * Functions.
134  */
135 extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
136 extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp,
137                                       struct xfs_dir2_sf_entry *sfep);
138 extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
139                                  struct xfs_dir2_data_hdr *block,
140                                  xfs_dir2_sf_hdr_t *sfhp);
141 extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
142                                 int size, xfs_dir2_sf_hdr_t *sfhp);
143 extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
144 extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
145 extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
146                                 xfs_off_t *offset, filldir_t filldir);
147 extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
148 extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
149 extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
150
151 #endif  /* __XFS_DIR2_SF_H__ */