Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:18

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup rtems_rfs
0007  *
0008  * @brief RTEMS File Systems Bitmap Routines
0009  *
0010  * These functions manage bit maps. A bit map consists of the map of bit
0011  * allocated in a block and a search map where a bit represents 32 actual
0012  * bits. The search map allows for a faster search for an available bit as 32
0013  * search bits can checked in a test.
0014  */
0015 
0016 /*
0017  *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
0018  *
0019  * Redistribution and use in source and binary forms, with or without
0020  * modification, are permitted provided that the following conditions
0021  * are met:
0022  * 1. Redistributions of source code must retain the above copyright
0023  *    notice, this list of conditions and the following disclaimer.
0024  * 2. Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the distribution.
0027  *
0028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0029  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0031  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0032  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0033  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0034  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0036  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0037  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0038  * POSSIBILITY OF SUCH DAMAGE.
0039  */
0040 
0041 #ifdef HAVE_CONFIG_H
0042 #include "config.h"
0043 #endif
0044 
0045 /**
0046  * Set to 1 to enable warnings when developing.
0047  */
0048 #define RTEMS_RFS_BITMAP_WARNINGS 0
0049 
0050 #if RTEMS_RFS_BITMAP_WARNINGS
0051 #include <stdio.h>
0052 #endif
0053 #include <stdlib.h>
0054 #include <rtems/rfs/rtems-rfs-bitmaps.h>
0055 
0056 #define rtems_rfs_bitmap_check(_c, _sm) \
0057    _Assert(_sm >= _c->search_bits && \
0058            _sm < (_c->search_bits + \
0059              rtems_rfs_bitmap_elements(rtems_rfs_bitmap_elements(_c->size))))
0060 
0061 
0062 /**
0063  * Test a bit in an element. If set return true else return false.
0064  *
0065  * @param target The target to test the bit in.
0066  * @param bit The bit to test.
0067  * @retval true The bit is set.
0068  * @retval false The bit is clear.
0069  */
0070 static bool
0071 rtems_rfs_bitmap_test (rtems_rfs_bitmap_element target,
0072                        rtems_rfs_bitmap_bit     bit)
0073 {
0074   return RTEMS_RFS_BITMAP_TEST_BIT (target, bit);
0075 }
0076 
0077 /**
0078  * Set the bits in the element. Bits not set in the bit argument are left
0079  * unchanged.
0080  *
0081  * @param target The target element bits are set.
0082  * @param bits The bits in the target to set. A 1 in the bits will set the
0083  *             same bit in the target.
0084  */
0085 static rtems_rfs_bitmap_element
0086 rtems_rfs_bitmap_set (rtems_rfs_bitmap_element target,
0087                       rtems_rfs_bitmap_element bits)
0088 {
0089   return RTEMS_RFS_BITMAP_SET_BITS (target, bits);
0090 }
0091 
0092 /**
0093  * Clear the bits in the element. Bits not set in the bit argument are left
0094  * unchanged.
0095  *
0096  * @param target The target element to clear the bits in.
0097  * @param bits The bits in the target to clear. A 1 in the bits will clear the
0098  *             bit in the target.
0099  */
0100 static rtems_rfs_bitmap_element
0101 rtems_rfs_bitmap_clear (rtems_rfs_bitmap_element target,
0102                         rtems_rfs_bitmap_element bits)
0103 {
0104   return RTEMS_RFS_BITMAP_CLEAR_BITS (target, bits);
0105 }
0106 
0107 /**
0108  * Merge the bits in 2 variables based on the mask. A set bit in the mask will
0109  * merge the bits from bits1 and a clear bit will merge the bits from bits2.
0110  * The mask is always defined as 1 being set and 0 being clear.
0111  */
0112 static rtems_rfs_bitmap_element
0113 rtems_rfs_bitmap_merge (rtems_rfs_bitmap_element bits1,
0114                         rtems_rfs_bitmap_element bits2,
0115                         rtems_rfs_bitmap_element mask)
0116 {
0117   /*
0118    * Use the normal bit operators because we do not change the bits just merge
0119    * the 2 separate parts.
0120    */
0121   bits1 &= mask;
0122   bits2 &= RTEMS_RFS_BITMAP_INVERT_MASK (mask);
0123   return bits1 | bits2;
0124 }
0125 
0126 /**
0127  * Match the bits of 2 elements and return true if they match else return
0128  * false.
0129  *
0130  * @param bits1 One set of bits to match.
0131  * @param bits2 The second set of bits to match.
0132  * @retval true The bits match.
0133  * @retval false The bits do not match.
0134  */
0135 static bool
0136 rtems_rfs_bitmap_match (rtems_rfs_bitmap_element bits1,
0137                         rtems_rfs_bitmap_element bits2)
0138 {
0139   return bits1 ^ bits2 ? false : true;
0140 }
0141 
0142 #if RTEMS_NOT_USED_BUT_KEPT
0143 /**
0144  * Match the bits of 2 elements within the mask and return true if they match
0145  * else return false.
0146  *
0147  * @param mask The mask over which the match occurs. A 1 is a valid mask bit.
0148  * @param bits1 One set of bits to match.
0149  * @param bits2 The second set of bits to match.
0150  * @retval true The bits match.
0151  * @retval false The bits do not match.
0152  */
0153 static bool
0154 rtems_rfs_bitmap_match_masked (rtems_rfs_bitmap_element mask,
0155                                rtems_rfs_bitmap_element bits1,
0156                                rtems_rfs_bitmap_element bits2)
0157 {
0158   return (bits1 ^ bits2) & mask ? false : true;
0159 }
0160 #endif
0161 
0162 /**
0163  * Return the map after loading from disk if not already loaded.
0164  *
0165  * @param control The bitmap control.
0166  * @param rtems_rfs_bitmap_map* Pointer to the bitmap map data if no error.
0167  * @return int The error number (errno). No error if 0.
0168  */
0169 static int
0170 rtems_rfs_bitmap_load_map (rtems_rfs_bitmap_control* control,
0171                            rtems_rfs_bitmap_map*     map)
0172 {
0173   int rc;
0174 
0175   if (!control->buffer)
0176     return ENXIO;
0177 
0178   *map = NULL;
0179 
0180   rc = rtems_rfs_buffer_handle_request (control->fs,
0181                                         control->buffer,
0182                                         control->block,
0183                                         true);
0184   if (rc)
0185     return rc;
0186 
0187   *map = rtems_rfs_buffer_data (control->buffer);
0188   return 0;
0189 }
0190 
0191 rtems_rfs_bitmap_element
0192 rtems_rfs_bitmap_mask (unsigned int size)
0193 {
0194   rtems_rfs_bitmap_element mask = RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK;
0195   mask >>= (rtems_rfs_bitmap_element_bits () - size);
0196   return mask;
0197 }
0198 
0199 rtems_rfs_bitmap_element
0200 rtems_rfs_bitmap_mask_section (unsigned int start, unsigned int end)
0201 {
0202   rtems_rfs_bitmap_element mask = 0;
0203   if (end > start)
0204     mask = rtems_rfs_bitmap_mask (end - start) << start;
0205   return mask;
0206 }
0207 
0208 int
0209 rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
0210                           rtems_rfs_bitmap_bit      bit)
0211 {
0212   rtems_rfs_bitmap_map     map;
0213   rtems_rfs_bitmap_map     search_map;
0214   int                      index;
0215   int                      offset;
0216   int                      rc;
0217   rtems_rfs_bitmap_element element;
0218 
0219   rc = rtems_rfs_bitmap_load_map (control, &map);
0220   if (rc > 0)
0221     return rc;
0222 
0223   if (bit >= control->size)
0224     return EINVAL;
0225 
0226   search_map = control->search_bits;
0227   index      = rtems_rfs_bitmap_map_index (bit);
0228   offset     = rtems_rfs_bitmap_map_offset (bit);
0229   element    = map[index];
0230   map[index] = rtems_rfs_bitmap_set (element, 1 << offset);
0231 
0232   /*
0233    * If the element does not change, the bit was already set. There will be no
0234    * further action to take.
0235    */
0236   if (rtems_rfs_bitmap_match(element, map[index]))
0237       return 0;
0238 
0239   control->free--;
0240 
0241   rtems_rfs_buffer_mark_dirty (control->buffer);
0242   if (rtems_rfs_bitmap_match(map[index], RTEMS_RFS_BITMAP_ELEMENT_SET))
0243   {
0244     bit = index;
0245     index  = rtems_rfs_bitmap_map_index (bit);
0246     offset = rtems_rfs_bitmap_map_offset (bit);
0247     search_map[index] = rtems_rfs_bitmap_set (search_map[index], 1 << offset);
0248     rtems_rfs_bitmap_check(control, &search_map[index]);
0249   }
0250 
0251   return 0;
0252 }
0253 
0254 int
0255 rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
0256                             rtems_rfs_bitmap_bit      bit)
0257 {
0258   rtems_rfs_bitmap_map     map;
0259   rtems_rfs_bitmap_map     search_map;
0260   int                      index;
0261   int                      offset;
0262   int                      rc;
0263   rtems_rfs_bitmap_element element;
0264 
0265   rc = rtems_rfs_bitmap_load_map (control, &map);
0266   if (rc > 0)
0267     return rc;
0268 
0269   if (bit >= control->size)
0270     return EINVAL;
0271 
0272   search_map = control->search_bits;
0273   index      = rtems_rfs_bitmap_map_index (bit);
0274   offset     = rtems_rfs_bitmap_map_offset (bit);
0275   element    = map[index];
0276   map[index] = rtems_rfs_bitmap_clear (element, 1 << offset);
0277 
0278   /*
0279    * If the element does not change, the bit was already clear. There will be
0280    * no further action to take.
0281    */
0282   if (rtems_rfs_bitmap_match(element, map[index]))
0283       return 0;
0284 
0285   bit               = index;
0286   index             = rtems_rfs_bitmap_map_index (bit);
0287   offset            = rtems_rfs_bitmap_map_offset(bit);
0288   search_map[index] = rtems_rfs_bitmap_clear (search_map[index], 1 << offset);
0289   rtems_rfs_bitmap_check(control, &search_map[index]);
0290   rtems_rfs_buffer_mark_dirty (control->buffer);
0291   control->free++;
0292 
0293   return 0;
0294 }
0295 
0296 int
0297 rtems_rfs_bitmap_map_test (rtems_rfs_bitmap_control* control,
0298                            rtems_rfs_bitmap_bit      bit,
0299                            bool*                     state)
0300 {
0301   rtems_rfs_bitmap_map map;
0302   int                  index;
0303   int                  rc;
0304   rc = rtems_rfs_bitmap_load_map (control, &map);
0305   if (rc > 0)
0306     return rc;
0307   if (bit >= control->size)
0308     return EINVAL;
0309   index = rtems_rfs_bitmap_map_index (bit);
0310   *state = rtems_rfs_bitmap_test (map[index], bit);
0311   return 0;
0312 }
0313 
0314 int
0315 rtems_rfs_bitmap_map_set_all (rtems_rfs_bitmap_control* control)
0316 {
0317   rtems_rfs_bitmap_map map;
0318   size_t               elements;
0319   int                  e;
0320   int                  rc;
0321 
0322   rc = rtems_rfs_bitmap_load_map (control, &map);
0323   if (rc > 0)
0324     return rc;
0325 
0326   elements = rtems_rfs_bitmap_elements (control->size);
0327 
0328   control->free = 0;
0329 
0330   for (e = 0; e < elements; e++)
0331     map[e] = RTEMS_RFS_BITMAP_ELEMENT_SET;
0332 
0333   elements = rtems_rfs_bitmap_elements (elements);
0334 
0335   for (e = 0; e < elements; e++)
0336     control->search_bits[e] = RTEMS_RFS_BITMAP_ELEMENT_SET;
0337 
0338   rtems_rfs_buffer_mark_dirty (control->buffer);
0339 
0340   return 0;
0341 }
0342 
0343 int
0344 rtems_rfs_bitmap_map_clear_all (rtems_rfs_bitmap_control* control)
0345 {
0346   rtems_rfs_bitmap_map map;
0347   rtems_rfs_bitmap_bit last_search_bit;
0348   size_t               elements;
0349   int                  e;
0350   int                  rc;
0351 
0352   rc = rtems_rfs_bitmap_load_map (control, &map);
0353   if (rc > 0)
0354     return rc;
0355 
0356   elements = rtems_rfs_bitmap_elements (control->size);
0357 
0358   control->free = control->size;
0359 
0360   for (e = 0; e < elements; e++)
0361     map[e] = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0362 
0363   /*
0364    * Set the un-mapped bits in the last search element so the available logic
0365    * works.
0366    */
0367   last_search_bit = rtems_rfs_bitmap_map_offset (elements);
0368 
0369   if (last_search_bit == 0)
0370     last_search_bit = rtems_rfs_bitmap_element_bits ();
0371 
0372   elements = rtems_rfs_bitmap_elements (elements);
0373 
0374   for (e = 0; e < (elements - 1); e++)
0375     control->search_bits[e] = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0376 
0377   control->search_bits[elements - 1] =
0378     rtems_rfs_bitmap_merge (RTEMS_RFS_BITMAP_ELEMENT_CLEAR,
0379                             RTEMS_RFS_BITMAP_ELEMENT_SET,
0380                             rtems_rfs_bitmap_mask (last_search_bit));
0381 
0382   rtems_rfs_buffer_mark_dirty (control->buffer);
0383 
0384   return 0;
0385 }
0386 
0387 static int
0388 rtems_rfs_search_map_for_clear_bit (rtems_rfs_bitmap_control* control,
0389                                     rtems_rfs_bitmap_bit*     bit,
0390                                     bool*                     found,
0391                                     size_t                    window,
0392                                     int                       direction)
0393 {
0394   rtems_rfs_bitmap_map      map;
0395   rtems_rfs_bitmap_bit      test_bit;
0396   rtems_rfs_bitmap_bit      end_bit;
0397   rtems_rfs_bitmap_element* search_bits;
0398   int                       search_index;
0399   int                       search_offset;
0400   rtems_rfs_bitmap_element* map_bits;
0401   int                       map_index;
0402   int                       map_offset;
0403   int                       rc;
0404 
0405   *found = false;
0406 
0407   /*
0408    * Load the bitmap.
0409    */
0410   rc = rtems_rfs_bitmap_load_map (control, &map);
0411   if (rc > 0)
0412     return rc;
0413 
0414   /*
0415    * Calculate the bit we are testing plus the end point we search over.
0416    */
0417   test_bit = *bit;
0418   end_bit  = test_bit + (window * direction);
0419 
0420   if (end_bit < 0)
0421     end_bit = 0;
0422   else if (end_bit >= control->size)
0423     end_bit = control->size - 1;
0424 
0425   map_index     = rtems_rfs_bitmap_map_index (test_bit);
0426   map_offset    = rtems_rfs_bitmap_map_offset (test_bit);
0427   search_index  = rtems_rfs_bitmap_map_index (map_index);
0428   search_offset = rtems_rfs_bitmap_map_offset (map_index);
0429 
0430   search_bits = &control->search_bits[search_index];
0431   map_bits    = &map[map_index];
0432 
0433   /*
0434    * Check each bit from the search map offset for a clear bit.
0435    */
0436   do
0437   {
0438     /*
0439      * If any bit is clear find that bit and then search the map element. If
0440      * all bits are set there are no map bits so move to the next search
0441      * element.
0442      */
0443     if (!rtems_rfs_bitmap_match (*search_bits, RTEMS_RFS_BITMAP_ELEMENT_SET))
0444     {
0445       while ((search_offset >= 0)
0446              && (search_offset < rtems_rfs_bitmap_element_bits ()))
0447       {
0448         if (!rtems_rfs_bitmap_test (*search_bits, search_offset))
0449         {
0450           /*
0451            * Find the clear bit in the map. Update the search map and map if
0452            * found. We may find none are spare if searching up from the seed.
0453            */
0454           while ((map_offset >= 0)
0455                  && (map_offset < rtems_rfs_bitmap_element_bits ()))
0456           {
0457             if (!rtems_rfs_bitmap_test (*map_bits, map_offset))
0458             {
0459               *map_bits = rtems_rfs_bitmap_set (*map_bits, 1 << map_offset);
0460               if (rtems_rfs_bitmap_match(*map_bits,
0461                                          RTEMS_RFS_BITMAP_ELEMENT_SET))
0462                 *search_bits = rtems_rfs_bitmap_set (*search_bits,
0463                                                      1 << search_offset);
0464               control->free--;
0465               *bit = test_bit;
0466               *found = true;
0467               rtems_rfs_buffer_mark_dirty (control->buffer);
0468               return 0;
0469             }
0470 
0471             if (test_bit == end_bit)
0472               break;
0473 
0474             map_offset += direction;
0475             test_bit   += direction;
0476           }
0477         }
0478 
0479         map_bits  += direction;
0480         map_index += direction;
0481         map_offset = direction > 0 ? 0 : rtems_rfs_bitmap_element_bits () - 1;
0482 
0483         test_bit = (map_index * rtems_rfs_bitmap_element_bits ()) + map_offset;
0484 
0485         search_offset += direction;
0486 
0487         if (((direction < 0) && (test_bit <= end_bit))
0488             || ((direction > 0) && (test_bit >= end_bit)))
0489           break;
0490       }
0491     }
0492     else
0493     {
0494       /*
0495        * Move to the next search element. We need to determine the number of
0496        * bits in the search offset that are being skipped so the map bits
0497        * pointer can be updated. If we are moving down and we have a search
0498        * offset of 0 then the search map adjustment is to the top bit of the
0499        * pervious search bit's value.
0500        *
0501        * Align test_bit either up or down depending on the direction to next 32
0502        * bit boundary.
0503        */
0504       rtems_rfs_bitmap_bit bits_skipped;
0505       test_bit &= ~((1 << RTEMS_RFS_ELEMENT_BITS_POWER_2) - 1);
0506       if (direction > 0)
0507       {
0508         bits_skipped = rtems_rfs_bitmap_element_bits () - search_offset;
0509         test_bit += bits_skipped * rtems_rfs_bitmap_element_bits ();
0510         map_offset = 0;
0511       }
0512       else
0513       {
0514         bits_skipped = search_offset + 1;
0515         /*
0516          * Need to remove 1 for the rounding up. The above rounds down and
0517          * adds 1. Remember the logic is for subtraction.
0518          */
0519         test_bit -= ((bits_skipped - 1) * rtems_rfs_bitmap_element_bits ()) + 1;
0520         map_offset = rtems_rfs_bitmap_element_bits () - 1;
0521       }
0522       map_bits += direction * bits_skipped;
0523       map_index += direction * bits_skipped;
0524     }
0525 
0526     search_bits  += direction;
0527     search_offset = direction > 0 ? 0 : rtems_rfs_bitmap_element_bits () - 1;
0528   }
0529   while (((direction < 0) && (test_bit >= end_bit))
0530          || ((direction > 0) && (test_bit <= end_bit)));
0531 
0532   return 0;
0533 }
0534 
0535 int
0536 rtems_rfs_bitmap_map_alloc (rtems_rfs_bitmap_control* control,
0537                             rtems_rfs_bitmap_bit      seed,
0538                             bool*                     allocated,
0539                             rtems_rfs_bitmap_bit*     bit)
0540 {
0541   rtems_rfs_bitmap_bit upper_seed;
0542   rtems_rfs_bitmap_bit lower_seed;
0543   rtems_rfs_bitmap_bit window;     /* may become a parameter */
0544   int                  rc = 0;
0545 
0546   /*
0547    * By default we assume the allocation failed.
0548    */
0549   *allocated = false;
0550 
0551   /*
0552    * The window is the number of bits we search over in either direction each
0553    * time.
0554    */
0555   window = RTEMS_RFS_BITMAP_SEARCH_WINDOW;
0556 
0557   /*
0558    * Start from the seed and move in either direction. Search in window amounts
0559    * of bits from the original seed above then below. That is search from the
0560    * seed up then from the seed down a window number of bits, then repeat the
0561    * process from the window distance from the seed, again above then
0562    * below. Keep moving out until all bits have been searched.
0563    */
0564   upper_seed = seed;
0565   lower_seed = seed;
0566 
0567   /*
0568    * If the upper and lower seed values have reached the limits of the bitmap
0569    * we have searched all of the map. The seed may not be aligned to a window
0570    * boundary so we may need to search a partial window and this may also not
0571    * be balanced for the upper or lower seeds. We move to the limits, search
0572    * then return false if no clear bits are found.
0573    */
0574   while (((upper_seed >= 0) && (upper_seed < control->size))
0575          || ((lower_seed >= 0) && (lower_seed < control->size)))
0576   {
0577     /*
0578      * Search up first so bits allocated in succession are grouped together.
0579      */
0580     if (upper_seed < control->size)
0581     {
0582       *bit = upper_seed;
0583       rc = rtems_rfs_search_map_for_clear_bit (control, bit, allocated,
0584                                                window, 1);
0585       if ((rc > 0) || *allocated)
0586         break;
0587     }
0588 
0589     if (lower_seed >= 0)
0590     {
0591       *bit = lower_seed;
0592       rc = rtems_rfs_search_map_for_clear_bit (control, bit, allocated,
0593                                                window, -1);
0594       if ((rc > 0) || *allocated)
0595         break;
0596     }
0597 
0598     /*
0599      * Do not bound the limits at the edges of the map. Do not update if an
0600      * edge has been passed.
0601      */
0602     if (upper_seed < control->size)
0603       upper_seed += window;
0604     if (lower_seed >= 0)
0605       lower_seed -= window;
0606   }
0607 
0608   return 0;
0609 }
0610 
0611 int
0612 rtems_rfs_bitmap_create_search (rtems_rfs_bitmap_control* control)
0613 {
0614   rtems_rfs_bitmap_map search_map;
0615   rtems_rfs_bitmap_map map;
0616   size_t               size;
0617   rtems_rfs_bitmap_bit bit;
0618   int                  rc;
0619 
0620   rc = rtems_rfs_bitmap_load_map (control, &map);
0621   if (rc > 0)
0622     return rc;
0623 
0624   control->free = 0;
0625   search_map = control->search_bits;
0626   size = control->size;
0627   bit = 0;
0628 
0629   rtems_rfs_bitmap_check(control, search_map);
0630   *search_map = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0631   while (size)
0632   {
0633     rtems_rfs_bitmap_element bits;
0634     int                      available;
0635     if (size < rtems_rfs_bitmap_element_bits ())
0636     {
0637       bits = rtems_rfs_bitmap_merge (*map,
0638                                      RTEMS_RFS_BITMAP_ELEMENT_SET,
0639                                      rtems_rfs_bitmap_mask_section (0, size));
0640       available = size;
0641     }
0642     else
0643     {
0644       bits      = *map;
0645       available = rtems_rfs_bitmap_element_bits ();
0646     }
0647 
0648     if (rtems_rfs_bitmap_match (bits, RTEMS_RFS_BITMAP_ELEMENT_SET))
0649       rtems_rfs_bitmap_set (*search_map, bit);
0650     else
0651     {
0652       int b;
0653       for (b = 0; b < available; b++)
0654         if (!rtems_rfs_bitmap_test (bits, b))
0655           control->free++;
0656     }
0657 
0658     size -= available;
0659 
0660     /* Iterate from 0 to 1 less than the number of bits in an element */
0661     if (bit == (rtems_rfs_bitmap_element_bits () - 1))
0662     {
0663       bit = 0;
0664       if (size > 0)
0665       {
0666         search_map++;
0667         rtems_rfs_bitmap_check(control, search_map);
0668         *search_map = RTEMS_RFS_BITMAP_ELEMENT_CLEAR;
0669       }
0670     }
0671     else
0672       bit++;
0673     map++;
0674   }
0675 
0676   return 0;
0677 }
0678 
0679 int
0680 rtems_rfs_bitmap_open (rtems_rfs_bitmap_control* control,
0681                        rtems_rfs_file_system*    fs,
0682                        rtems_rfs_buffer_handle*  buffer,
0683                        size_t                    size,
0684                        rtems_rfs_buffer_block    block)
0685 {
0686   size_t elements = rtems_rfs_bitmap_elements (size);
0687 
0688   control->buffer = buffer;
0689   control->fs = fs;
0690   control->block = block;
0691   control->size = size;
0692 
0693   elements = rtems_rfs_bitmap_elements (elements);
0694   control->search_bits = malloc (elements * sizeof (rtems_rfs_bitmap_element));
0695 
0696   if (!control->search_bits)
0697     return ENOMEM;
0698 
0699   return rtems_rfs_bitmap_create_search (control);
0700 }
0701 
0702 int
0703 rtems_rfs_bitmap_close (rtems_rfs_bitmap_control* control)
0704 {
0705   free (control->search_bits);
0706   return 0;
0707 }