![]() |
|
|||
File indexing completed on 2025-05-11 08:24:12
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @brief RTEMS File Systems Block Management 0007 * 0008 * @ingroup rtems_rfs 0009 * 0010 * RTEMS File Systems Block Management. 0011 * 0012 * These functions manage the blocks used in the file system. 0013 */ 0014 0015 /* 0016 * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org> 0017 * 0018 * Redistribution and use in source and binary forms, with or without 0019 * modification, are permitted provided that the following conditions 0020 * are met: 0021 * 1. Redistributions of source code must retain the above copyright 0022 * notice, this list of conditions and the following disclaimer. 0023 * 2. Redistributions in binary form must reproduce the above copyright 0024 * notice, this list of conditions and the following disclaimer in the 0025 * documentation and/or other materials provided with the distribution. 0026 * 0027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0037 * POSSIBILITY OF SUCH DAMAGE. 0038 */ 0039 0040 0041 #if !defined (_RTEMS_RFS_BLOCK_H_) 0042 #define _RTEMS_RFS_BLOCK_H_ 0043 0044 #include <rtems/rfs/rtems-rfs-block-pos.h> 0045 #include <rtems/rfs/rtems-rfs-buffer.h> 0046 #include <rtems/rfs/rtems-rfs-data.h> 0047 #include <rtems/rfs/rtems-rfs-file-system.h> 0048 0049 /** 0050 * Get a block number in the media format and return it in the host format. 0051 * 0052 * @param[in] _h is the buffer handle of the block. 0053 * @param[in] _b is the block number index. 0054 * 0055 * @retval block The block number. 0056 */ 0057 #define rtems_rfs_block_get_number(_h, _b) \ 0058 ((rtems_rfs_block_no) \ 0059 (rtems_rfs_read_u32 (rtems_rfs_buffer_data (_h) + \ 0060 ((_b) * sizeof (rtems_rfs_block_no))))) 0061 0062 /** 0063 * Set a block number in the media format given a number in the host format. 0064 * 0065 * @param[in] _h is the buffer handle of the block. 0066 * @param[in] _b is the block number index, ie the number of block number not the 0067 * buffer offset. 0068 * @param[in] _n is the block number. 0069 */ 0070 #define rtems_rfs_block_set_number(_h, _b, _n) \ 0071 do { \ 0072 rtems_rfs_write_u32 (rtems_rfs_buffer_data (_h) + \ 0073 ((_b) * sizeof (rtems_rfs_block_no)), (_n)); \ 0074 rtems_rfs_buffer_mark_dirty (_h); \ 0075 } while (0) 0076 0077 /** 0078 * A block map manges the block lists that originate from an inode. The inode 0079 * contains a number of block numbers. A block map takes those block numbers 0080 * and manages them. 0081 * 0082 * The blocks cannot have all ones as a block number nor block 0. The block map 0083 * is series of block numbers in a blocks. The size of the map determines the 0084 * way the block numbers are stored. The map uses the following: 0085 * 0086 * @li @e Direct Access, 0087 * @li @e Single Indirect Access, and 0088 * @li @e Double Indirect Access. 0089 * 0090 * Direct access has the blocks numbers in the inode slots. The Single Indirect 0091 * Access has block numbers in the inode slots that pointer to a table of block 0092 * numbers that point to data blocks. The Double Indirect Access has block 0093 * numbers in the inode that point to Single Indirect block tables. 0094 * 0095 * The inode can hold a number of Direct, Single Indirect, and Double Indirect 0096 * block tables. The move from Direct to Single occurs then the block count in 0097 * the map is above the number of slots in the inode. The move from Single to 0098 * Double occurs when the map block count is greated than the block numbers per 0099 * block multipled by the slots in the inode. The move from Single to Double 0100 * occurs when the map block count is over the block numbers per block squared 0101 * multipled by the number of slots in the inode. 0102 * 0103 * The block map can managed files of the follow size verses block size with 5 0104 * inode slots: 0105 * 0106 * @li 41,943,040 bytes for a 512 byte block size, 0107 * @li 335,544,320 bytes for a 1024 byte block size, 0108 * @li 2,684,354,560 bytes for a 2048 byte block size, and 0109 * @li 21,474,836,480 bytes for a 4096 byte block size. 0110 */ 0111 typedef struct rtems_rfs_block_map_s 0112 { 0113 /** 0114 * Is the map dirty ? 0115 */ 0116 bool dirty; 0117 0118 /** 0119 * The inode this map is attached to. 0120 */ 0121 rtems_rfs_inode_handle* inode; 0122 0123 /** 0124 * The size of the map. 0125 */ 0126 rtems_rfs_block_size size; 0127 0128 /** 0129 * The block map position. Used to navigate the map when seeking. The find 0130 * call is to a position in the file/directory and is a block number plus 0131 * offset. The block find only needs to locate a block and not worry about 0132 * the offset while a seek can be less than a block size yet move across a 0133 * block boundary. Therefore the position a block map has to maintain must 0134 * include the offset so seeks work. 0135 */ 0136 rtems_rfs_block_pos bpos; 0137 0138 /** 0139 * The last map block allocated. This is used as the goal when allocating a 0140 * new map block. 0141 */ 0142 rtems_rfs_block_no last_map_block; 0143 0144 /** 0145 * The last data block allocated. This is used as the goal when allocating a 0146 * new data block. 0147 */ 0148 rtems_rfs_block_no last_data_block; 0149 0150 /** 0151 * The block map. 0152 */ 0153 uint32_t blocks[RTEMS_RFS_INODE_BLOCKS]; 0154 0155 /** 0156 * Singly Buffer handle. 0157 */ 0158 rtems_rfs_buffer_handle singly_buffer; 0159 0160 /** 0161 * Doubly Buffer handle. 0162 */ 0163 rtems_rfs_buffer_handle doubly_buffer; 0164 0165 } rtems_rfs_block_map; 0166 0167 /** 0168 * Is the map dirty ? 0169 */ 0170 #define rtems_rfs_block_map_is_dirty(_m) ((_m)->dirty) 0171 0172 /** 0173 * Return the block count in the map. 0174 */ 0175 #define rtems_rfs_block_map_count(_m) ((_m)->size.count) 0176 0177 /** 0178 * Return the map's size element. 0179 */ 0180 #define rtems_rfs_block_map_size(_m) (&((_m)->size)) 0181 0182 /** 0183 * Return the size offset for the map. 0184 */ 0185 #define rtems_rfs_block_map_size_offset(_m) ((_m)->size.offset) 0186 0187 /** 0188 * Are we at the last block in the map ? 0189 */ 0190 #define rtems_rfs_block_map_last(_m) \ 0191 rtems_rfs_block_pos_last_block (&(_m)->bpos, &(_m)->size) 0192 0193 /** 0194 * Is the position past the end of the block ? 0195 */ 0196 #define rtems_rfs_block_map_past_end(_m, _p) \ 0197 rtems_rfs_block_pos_past_end (_p, &(_m)->size) 0198 0199 /** 0200 * Return the current position in the map. 0201 */ 0202 #define rtems_rfs_block_map_pos(_f, _m) \ 0203 rtems_rfs_block_get_pos (_f, &(_m)->bpos) 0204 0205 /** 0206 * Return the map's current block number. 0207 */ 0208 #define rtems_rfs_block_map_block(_m) ((_m)->bpos.bno) 0209 0210 /** 0211 * Return the map's current block offset. 0212 */ 0213 #define rtems_rfs_block_map_block_offset(_m) ((_m)->bpos.boff) 0214 0215 /** 0216 * Set the size offset for the map. The map is tagged as dirty. 0217 * 0218 * @param[in] map is a pointer to the open map to set the offset in. 0219 * @param[in] offset is the offset to set in the map's size. 0220 */ 0221 static inline void 0222 rtems_rfs_block_map_set_size_offset (rtems_rfs_block_map* map, 0223 rtems_rfs_block_off offset) 0224 { 0225 map->size.offset = offset; 0226 map->dirty = true; 0227 } 0228 0229 /** 0230 * Set the map's size. The map is tagged as dirty. 0231 * 0232 * @param[in] map is a pointer to the open map to set the offset in. 0233 * @param[in] size is the size to set in the map's size. 0234 */ 0235 static inline void 0236 rtems_rfs_block_map_set_size (rtems_rfs_block_map* map, 0237 rtems_rfs_block_size* size) 0238 { 0239 rtems_rfs_block_copy_size (&map->size, size); 0240 map->dirty = true; 0241 } 0242 /** 0243 * Open a block map. The block map data in the inode is copied into the 0244 * map. The buffer handles are opened. The block position is set to the start 0245 * so a seek of offset 0 will return the first block. 0246 * 0247 * @param[in] fs is the file system data. 0248 * @param[in] inode is a pointer to the inode the map belongs to. 0249 * @param[in] map is a pointer to the map that is opened. 0250 * 0251 * @retval 0 Successful operation. 0252 * @retval error_code An error occurred. 0253 */ 0254 int rtems_rfs_block_map_open (rtems_rfs_file_system* fs, 0255 rtems_rfs_inode_handle* inode, 0256 rtems_rfs_block_map* map); 0257 0258 /** 0259 * Close the map. The buffer handles are closed and any help buffers are 0260 * released. 0261 * 0262 * @param[in] fs is the file system data. 0263 * @param[in] map is a pointer to the map that is opened. 0264 * 0265 * @retval 0 Successful operation. 0266 * @retval error_code An error occurred. 0267 */ 0268 int rtems_rfs_block_map_close (rtems_rfs_file_system* fs, 0269 rtems_rfs_block_map* map); 0270 0271 /** 0272 * Find a block number in the map from the position provided. 0273 * 0274 * @param[in] fs is the file system data. 0275 * @param[in] map is a pointer to the map to search. 0276 * @param[in] bpos is a pointer to the block position to find. 0277 * @param[out] block will contain the block in when found. 0278 * 0279 * @retval 0 Successful operation. 0280 * @retval error_code An error occurred. 0281 */ 0282 int rtems_rfs_block_map_find (rtems_rfs_file_system* fs, 0283 rtems_rfs_block_map* map, 0284 rtems_rfs_block_pos* bpos, 0285 rtems_rfs_buffer_block* block); 0286 0287 /** 0288 * Seek around the map. 0289 * 0290 * @param[in] fs is the file system data. 0291 * @param[in] map is a pointer to the map to search. 0292 * @param[in] offset is the distance to seek. It is signed. 0293 * @param[out] block will contain the block in when found. 0294 * 0295 * @retval 0 Successful operation. 0296 * @retval ENXIO Failed to seek because it is outside the block map. 0297 * @retval error_code An error occurred. 0298 */ 0299 int rtems_rfs_block_map_seek (rtems_rfs_file_system* fs, 0300 rtems_rfs_block_map* map, 0301 rtems_rfs_pos_rel offset, 0302 rtems_rfs_buffer_block* block); 0303 0304 /** 0305 * Seek to the next block. 0306 * 0307 * @param[in] fs is the file system data. 0308 * @param[in] map is a pointer to the map to search. 0309 * @param[out] block will contain the block in when found. 0310 * 0311 * @retval 0 Successful operation. 0312 * @retval ENXIO Failed to seek because it is outside the block map. 0313 * @retval error_code An error occurred. 0314 */ 0315 int rtems_rfs_block_map_next_block (rtems_rfs_file_system* fs, 0316 rtems_rfs_block_map* map, 0317 rtems_rfs_buffer_block* block); 0318 0319 /** 0320 * Grow the block map by the specified number of blocks. 0321 * 0322 * @param[in] fs is the file system data. 0323 * @param[in] map is a pointer to the open map to grow. 0324 * @param[in] blocks is the number of blocks to grow the map by. 0325 * @param[out] new_block will contain first of the blocks allocated 0326 * to the map. 0327 * 0328 * @retval 0 Successful operation. 0329 * @retval error_code An error occurred. 0330 */ 0331 int rtems_rfs_block_map_grow (rtems_rfs_file_system* fs, 0332 rtems_rfs_block_map* map, 0333 size_t blocks, 0334 rtems_rfs_block_no* new_block); 0335 0336 /** 0337 * Grow the block map by the specified number of blocks. 0338 * 0339 * @param[in] fs is the file system data. 0340 * @param[in] map is a pointer to the open map to shrink. 0341 * @param[in] blocks is the number of blocks to shrink the map by. If more 0342 * than the number of blocks the map is emptied. 0343 * 0344 * @retval 0 Successful operation. 0345 * @retval error_code An error occurred. 0346 */ 0347 int rtems_rfs_block_map_shrink (rtems_rfs_file_system* fs, 0348 rtems_rfs_block_map* map, 0349 size_t blocks); 0350 0351 /** 0352 * Free all blocks in the map. 0353 * 0354 * @param[in] fs is the file system data. 0355 * @param[in] map is a pointer to the open map to free all blocks from. 0356 * 0357 * @retval 0 Successful operation. 0358 * @retval error_code An error occurred. 0359 */ 0360 int rtems_rfs_block_map_free_all (rtems_rfs_file_system* fs, 0361 rtems_rfs_block_map* map); 0362 0363 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |