Back to home page

LXR

 
 

    


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 Position and Size Management
0007  *
0008  * @ingroup rtems_rfs
0009  *
0010  * RTEMS File Systems Block Position and Size Management.
0011  *
0012  * These functions manage the position in a block map as well as a size of data
0013  * held in a block map. The position is the block count plus the offset into
0014  * the last block where a block position of 0 and an offset of 0 is the start
0015  * of a map. The size has a block count plus an offset, but the offset into the
0016  * last block gives the actual size of the data in the map. This means a size
0017  * will always have a block count greater than 0 when the file is not empty. A
0018  * size offset of 0 and a non-zero block count means the length if aligned to
0019  * the end of the block. For this reason there are 2 similar types so we know
0020  * which set of rules are in use and the reason for this file.
0021  */
0022 
0023 /*
0024  *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
0025  *
0026  * Redistribution and use in source and binary forms, with or without
0027  * modification, are permitted provided that the following conditions
0028  * are met:
0029  * 1. Redistributions of source code must retain the above copyright
0030  *    notice, this list of conditions and the following disclaimer.
0031  * 2. Redistributions in binary form must reproduce the above copyright
0032  *    notice, this list of conditions and the following disclaimer in the
0033  *    documentation and/or other materials provided with the distribution.
0034  *
0035  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0036  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0037  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0038  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0039  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0040  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0041  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0042  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0043  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0044  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0045  * POSSIBILITY OF SUCH DAMAGE.
0046  */
0047 
0048 #if !defined (_RTEMS_RFS_BLOCK_POS_H_)
0049 #define _RTEMS_RFS_BLOCK_POS_H_
0050 
0051 #include <rtems/rfs/rtems-rfs-file-system.h>
0052 #include <rtems/rfs/rtems-rfs-inode.h>
0053 
0054 /**
0055  * The block number is the same type as the inode block number. This makes sure
0056  * the sizes of the types match.
0057  */
0058 typedef rtems_rfs_inode_block rtems_rfs_block_no;
0059 
0060 /**
0061  * The offset into a block.
0062  */
0063 typedef uint32_t rtems_rfs_block_off;
0064 
0065 /**
0066  * A block position is a block number times the block size plus the offset. The
0067  * block field can be used hold a block number for the position as a look up
0068  * cache.
0069  */
0070 typedef struct rtems_rfs_block_pos_s
0071 {
0072   /**
0073    * The block index in the map. Range is from 0 to the maps block count minus
0074    * 1.
0075    */
0076   rtems_rfs_block_no bno;
0077 
0078   /**
0079    * The offset into the block. Must be less than the block size.
0080    */
0081   rtems_rfs_block_off boff;
0082 
0083   /**
0084    * The block number that the bpos + boff map to. The 0 value is invalid and
0085    * means no block number has been set.
0086    */
0087   rtems_rfs_block_no block;
0088 
0089 } rtems_rfs_block_pos;
0090 
0091 /**
0092  * Copy a block position.
0093  *
0094  * @param[in] _lhs is the left hand side.
0095  * @param[in] _rhs is the right hand side.
0096  */
0097 #define rtems_rfs_block_copy_bpos(_lhs, _rhs) \
0098   do { (_lhs)->bno = (_rhs)->bno; \
0099        (_lhs)->boff = (_rhs)->boff; \
0100        (_lhs)->block = (_rhs)->block; } while (0)
0101 
0102 /**
0103  * Zero a block position.
0104  *
0105  * @param[in] bpos is a pointer to the block position.
0106  */
0107 static inline void
0108 rtems_rfs_block_set_bpos_zero (rtems_rfs_block_pos* bpos)
0109 {
0110   bpos->bno = 0;
0111   bpos->boff = 0;
0112   bpos->block = 0;
0113 }
0114 
0115 /**
0116  * Given a position compute the block number and block offset.
0117  *
0118  * @param[in] fs is the file system data.
0119  * @param[in] pos is the position as an absolute offset from the start.
0120  * @param[out] bpos is a pointer to the block position to fill in.
0121  */
0122 void rtems_rfs_block_get_bpos (rtems_rfs_file_system*  fs,
0123                                rtems_rfs_pos           pos,
0124                                rtems_rfs_block_pos*    bpos);
0125 
0126 /**
0127  * Given a block position compute the absolute offset.
0128  *
0129  * @param[in] fs is the file system data.
0130  * @param[out] bpos is a pointer to the block position to fill in.
0131  *
0132  * @retval offset The absolute offset.
0133  */
0134 rtems_rfs_pos rtems_rfs_block_get_pos (rtems_rfs_file_system* fs,
0135                                        rtems_rfs_block_pos*   bpos);
0136 
0137 /**
0138  * Add the relative position to the block position. The relative position is
0139  * signed.
0140  *
0141  * @param[in] fs is the file system data.
0142  * @param[in] offset is the relative offset add to the block position.
0143  * @param[out] bpos is a pointer to the block position to fill in.
0144  */
0145 static inline void
0146 rtems_rfs_block_add_pos (rtems_rfs_file_system*  fs,
0147                          rtems_rfs_pos_rel       offset,
0148                          rtems_rfs_block_pos*    bpos)
0149 {
0150   rtems_rfs_block_get_bpos (fs,
0151                             rtems_rfs_block_get_pos (fs, bpos) + offset,
0152                             bpos);
0153   bpos->block = 0;
0154 }
0155 
0156 /**
0157  * A block size is the number of blocks less one plus the offset where the
0158  * offset must be less than the block size.
0159  */
0160 typedef struct rtems_rfs_block_size_s
0161 {
0162   /**
0163    * The count of blocks in a map. A 0 means no blocks and a zero length and
0164    * the offset should also be 0.
0165    */
0166   rtems_rfs_block_no count;
0167 
0168   /**
0169    * The offset into the block. An offset of 0 means block size, ie the first
0170    * byte of the next block which is not allocated.
0171    */
0172   rtems_rfs_block_off offset;
0173 
0174 } rtems_rfs_block_size;
0175 
0176 /**
0177  * Copy a block size.
0178  *
0179  * @param[in] _lhs is the left hand side.
0180  * @param[in] _rhs is the right hand side.
0181  */
0182 #define rtems_rfs_block_copy_size(_lhs, _rhs) \
0183   do { (_lhs)->count = (_rhs)->count; \
0184        (_lhs)->offset = (_rhs)->offset; } while (0)
0185 
0186 /**
0187  * Last block ?
0188  */
0189 #define rtems_rfs_block_pos_last_block(_p, _s) \
0190   ((((_p)->bno == 0) && ((_s)->count == 0)) || ((_p)->bno == ((_s)->count - 1)))
0191 
0192 /**
0193  * Last block ?
0194  */
0195 #define rtems_rfs_block_pos_past_end(_p, _s) \
0196   (((_p)->bno && ((_s)->count == 0)) || \
0197    ((_p)->bno >= (_s)->count) || \
0198    (((_p)->bno == ((_s)->count - 1)) && ((_p)->boff > (_s)->offset)))
0199 
0200 /**
0201  * Is the block position past the end.
0202  */
0203 #define rtems_rfs_block_pos_block_past_end(_p, _s) \
0204   (((_p)->bno && ((_s)->count == 0)) || ((_p)->bno >= (_s)->count))
0205 
0206 /**
0207  * Copy the size to the block position. Note the block position and the size
0208  * have different block counts.
0209  */
0210 #define rtems_rfs_block_size_get_bpos(_s, _b) \
0211   do { (_b)->bno = (_s)->count; \
0212        (_b)->boff = (_s)->offset; \
0213        (_b)->block = 0; \
0214        if ((_b)->boff) --(_b)->bno; } while (0)
0215 
0216 /**
0217  * Do the sizes match ?
0218  */
0219 #define rtems_rfs_block_size_equal(_lhs, _rhs) \
0220   (((_lhs)->count == (_rhs)->count) && ((_lhs)->offset == (_rhs)->offset))
0221 
0222 /**
0223  * Zero a block size.
0224  *
0225  * @param[in] size is a pointer to the block size.
0226  */
0227 static inline void
0228 rtems_rfs_block_set_size_zero (rtems_rfs_block_size* size)
0229 {
0230   size->count = 0;
0231   size->offset = 0;
0232 }
0233 
0234 /**
0235  * Set the size given a position.
0236  *
0237  * @param[in] fs is the file system data.
0238  * @param[in] pos is the position as an absolute offset from the start.
0239  * @param[out] size is a pointer to the block size to fill in.
0240  */
0241 void rtems_rfs_block_get_block_size (rtems_rfs_file_system*  fs,
0242                                      rtems_rfs_pos           pos,
0243                                      rtems_rfs_block_size*   size);
0244 
0245 /**
0246  * Calculate the position given the number of blocks and the offset. If the
0247  * block count is 0 the size is 0. If the block is greater than 0 and the
0248  * offset is 0 the size is number of blocks multipled by the block size and if
0249  * the offset is not 0 it is the offset into the last block. For example if
0250  * blocks is 1 and offset is 0 the size is the block size. If the block count
0251  * is 1 and size is 100 the size is 100.
0252  *
0253  * @param[in] fs is the file system data.
0254  * @param[in] size The size in blocks and offset.
0255  *
0256  * @retval size The size in bytes.
0257  */
0258 rtems_rfs_pos rtems_rfs_block_get_size (rtems_rfs_file_system* fs,
0259                                         rtems_rfs_block_size*  size);
0260 
0261 #endif