Fix a compile issue with big endian config & some small issues fixes
[lwext4.git] / include / ext4_fs.h
1 /*
2  * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
3  *
4  *
5  * HelenOS:
6  * Copyright (c) 2012 Martin Sucha
7  * Copyright (c) 2012 Frantisek Princ
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * - Redistributions of source code must retain the above copyright
15  *   notice, this list of conditions and the following disclaimer.
16  * - Redistributions in binary form must reproduce the above copyright
17  *   notice, this list of conditions and the following disclaimer in the
18  *   documentation and/or other materials provided with the distribution.
19  * - The name of the author may not be used to endorse or promote products
20  *   derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 /** @addtogroup lwext4
35  * @{
36  */
37 /**
38  * @file  ext4_fs.c
39  * @brief More complex filesystem functions.
40  */
41
42 #ifndef EXT4_FS_H_
43 #define EXT4_FS_H_
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 #include <ext4_config.h>
50 #include <ext4_types.h>
51 #include <ext4_misc.h>
52
53 #include <stdint.h>
54 #include <stdbool.h>
55
56 struct ext4_fs {
57         bool read_only;
58
59         struct ext4_blockdev *bdev;
60         struct ext4_sblock sb;
61
62         uint64_t inode_block_limits[4];
63         uint64_t inode_blocks_per_level[4];
64
65         uint32_t last_inode_bg_id;
66
67         struct jbd_fs *jbd_fs;
68         struct jbd_journal *jbd_journal;
69         struct jbd_trans *curr_trans;
70 };
71
72 struct ext4_block_group_ref {
73         struct ext4_block block;
74         struct ext4_bgroup *block_group;
75         struct ext4_fs *fs;
76         uint32_t index;
77         bool dirty;
78 };
79
80 struct ext4_inode_ref {
81         struct ext4_block block;
82         struct ext4_inode *inode;
83         struct ext4_fs *fs;
84         uint32_t index;
85         bool dirty;
86 };
87
88
89 /**@brief Convert block address to relative index in block group.
90  * @param sb Superblock pointer
91  * @param baddr Block number to convert
92  * @return Relative number of block
93  */
94 static inline uint32_t ext4_fs_addr_to_idx_bg(struct ext4_sblock *s,
95                                                      ext4_fsblk_t baddr)
96 {
97         if (ext4_get32(s, first_data_block) && baddr)
98                 baddr--;
99
100         return baddr % ext4_get32(s, blocks_per_group);
101 }
102
103 /**@brief Convert relative block address in group to absolute address.
104  * @param s Superblock pointer
105  * @param index Relative block address
106  * @param bgid Block group
107  * @return Absolute block address
108  */
109 static inline ext4_fsblk_t ext4_fs_bg_idx_to_addr(struct ext4_sblock *s,
110                                                      uint32_t index,
111                                                      uint32_t bgid)
112 {
113         if (ext4_get32(s, first_data_block))
114                 index++;
115
116         return ext4_get32(s, blocks_per_group) * bgid + index;
117 }
118
119 /**@brief TODO: */
120 static inline ext4_fsblk_t ext4_fs_first_bg_block_no(struct ext4_sblock *s,
121                                                  uint32_t bgid)
122 {
123         return (uint64_t)bgid * ext4_get32(s, blocks_per_group) +
124                ext4_get32(s, first_data_block);
125 }
126
127 /**@brief Initialize filesystem and read all needed data.
128  * @param fs Filesystem instance to be initialized
129  * @param bdev Identifier if device with the filesystem
130  * @param read_only Mark the filesystem as read-only.
131  * @return Error code
132  */
133 int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev,
134                  bool read_only);
135
136 /**@brief Destroy filesystem instance (used by unmount operation).
137  * @param fs Filesystem to be destroyed
138  * @return Error code
139  */
140 int ext4_fs_fini(struct ext4_fs *fs);
141
142 /**@brief Check filesystem's features, if supported by this driver
143  * Function can return EOK and set read_only flag. It mean's that
144  * there are some not-supported features, that can cause problems
145  * during some write operations.
146  * @param fs        Filesystem to be checked
147  * @param read_only Flag if filesystem should be mounted only for reading
148  * @return Error code
149  */
150 int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only);
151
152 /**@brief Get reference to block group specified by index.
153  * @param fs   Filesystem to find block group on
154  * @param bgid Index of block group to load
155  * @param ref  Output pointer for reference
156  * @return Error code
157  */
158 int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
159                                 struct ext4_block_group_ref *ref);
160
161 /**@brief Put reference to block group.
162  * @param ref Pointer for reference to be put back
163  * @return Error code
164  */
165 int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref);
166
167 /**@brief Get reference to i-node specified by index.
168  * @param fs    Filesystem to find i-node on
169  * @param index Index of i-node to load
170  * @param ref   Output pointer for reference
171  * @return Error code
172  */
173 int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
174                           struct ext4_inode_ref *ref);
175
176 /**@brief Reset blocks field of i-node.
177  * @param fs        Filesystem to reset blocks field of i-inode on
178  * @param inode_ref ref Pointer for inode to be operated on
179  */
180 void ext4_fs_inode_blocks_init(struct ext4_fs *fs,
181                                struct ext4_inode_ref *inode_ref);
182
183 /**@brief Put reference to i-node.
184  * @param ref Pointer for reference to be put back
185  * @return Error code
186  */
187 int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref);
188
189 /**@brief Convert filetype to inode mode.
190  * @param filetype
191  * @return inode mode
192  */
193 uint32_t ext4_fs_correspond_inode_mode(int filetype);
194
195 /**@brief Allocate new i-node in the filesystem.
196  * @param fs        Filesystem to allocated i-node on
197  * @param inode_ref Output pointer to return reference to allocated i-node
198  * @param filetype  File type of newly created i-node
199  * @return Error code
200  */
201 int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
202                         int filetype);
203
204 /**@brief Release i-node and mark it as free.
205  * @param inode_ref I-node to be released
206  * @return Error code
207  */
208 int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref);
209
210 /**@brief Truncate i-node data blocks.
211  * @param inode_ref I-node to be truncated
212  * @param new_size  New size of inode (must be < current size)
213  * @return Error code
214  */
215 int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size);
216
217 /**@brief Compute 'goal' for inode index
218  * @param inode_ref Reference to inode, to allocate block for
219  * @return goal
220  */
221 ext4_fsblk_t ext4_fs_inode_to_goal_block(struct ext4_inode_ref *inode_ref);
222
223 /**@brief Compute 'goal' for allocation algorithm (For blockmap).
224  * @param inode_ref Reference to inode, to allocate block for
225  * @param goal
226  * @return error code
227  */
228 int ext4_fs_indirect_find_goal(struct ext4_inode_ref *inode_ref,
229                                 ext4_fsblk_t *goal);
230
231 /**@brief Get physical block address by logical index of the block.
232  * @param inode_ref I-node to read block address from
233  * @param iblock            Logical index of block
234  * @param fblock            Output pointer for return physical
235  *                          block address
236  * @param support_unwritten Indicate whether unwritten block range
237  *                          is supported under the current context
238  * @return Error code
239  */
240 int ext4_fs_get_inode_dblk_idx(struct ext4_inode_ref *inode_ref,
241                                  ext4_lblk_t iblock, ext4_fsblk_t *fblock,
242                                  bool support_unwritten);
243
244 /**@brief Initialize a part of unwritten range of the inode.
245  * @param inode_ref I-node to proceed on.
246  * @param iblock    Logical index of block
247  * @param fblock    Output pointer for return physical block address
248  * @return Error code
249  */
250 int ext4_fs_init_inode_dblk_idx(struct ext4_inode_ref *inode_ref,
251                                   ext4_lblk_t iblock, ext4_fsblk_t *fblock);
252
253 /**@brief Append following logical block to the i-node.
254  * @param inode_ref I-node to append block to
255  * @param fblock    Output physical block address of newly allocated block
256  * @param iblock    Output logical number of newly allocated block
257  * @return Error code
258  */
259 int ext4_fs_append_inode_dblk(struct ext4_inode_ref *inode_ref,
260                               ext4_fsblk_t *fblock, ext4_lblk_t *iblock);
261
262 /**@brief   Increment inode link count.
263  * @param   inode none handle
264  */
265 void ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref);
266
267 /**@brief   Decrement inode link count.
268  * @param   inode none handle
269  */
270 void ext4_fs_inode_links_count_dec(struct ext4_inode_ref *inode_ref);
271
272 #ifdef __cplusplus
273 }
274 #endif
275
276 #endif /* EXT4_FS_H_ */
277
278 /**
279  * @}
280  */