source: mainline/uspace/lib/ext4/src/bitmap.c@ 84239b1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 84239b1 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 * Copyright (c) 2012 Frantisek Princ
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libext4
30 * @{
31 */
32/**
33 * @file bitmap.c
34 * @brief Ext4 bitmap operations.
35 */
36
37#include <errno.h>
38#include <block.h>
39#include <stdint.h>
40#include "ext4/bitmap.h"
41
42/** Set bit in bitmap to 0 (free).
43 *
44 * Index must be checked by caller, if it's not out of bounds.
45 *
46 * @param bitmap Pointer to bitmap
47 * @param index Index of bit in bitmap
48 *
49 */
50void ext4_bitmap_free_bit(uint8_t *bitmap, uint32_t index)
51{
52 uint32_t byte_index = index / 8;
53 uint32_t bit_index = index % 8;
54
55 uint8_t *target = bitmap + byte_index;
56
57 *target &= ~ (1 << bit_index);
58}
59
60/** Free continous set of bits (set to 0).
61 *
62 * Index and count must be checked by caller, if they aren't out of bounds.
63 *
64 * @param bitmap Pointer to bitmap
65 * @param index Index of first bit to zeroed
66 * @param count Number of bits to be zeroed
67 *
68 */
69void ext4_bitmap_free_bits(uint8_t *bitmap, uint32_t index, uint32_t count)
70{
71 uint8_t *target;
72 uint32_t idx = index;
73 uint32_t remaining = count;
74 uint32_t byte_index;
75
76 /* Align index to multiple of 8 */
77 while (((idx % 8) != 0) && (remaining > 0)) {
78 byte_index = idx / 8;
79 uint32_t bit_index = idx % 8;
80
81 target = bitmap + byte_index;
82 *target &= ~ (1 << bit_index);
83
84 idx++;
85 remaining--;
86 }
87
88 /* For < 8 bits this check necessary */
89 if (remaining == 0)
90 return;
91
92 assert((idx % 8) == 0);
93
94 byte_index = idx / 8;
95 target = bitmap + byte_index;
96
97 /* Zero the whole bytes */
98 while (remaining >= 8) {
99 *target = 0;
100
101 idx += 8;
102 remaining -= 8;
103 target++;
104 }
105
106 assert(remaining < 8);
107
108 /* Zero remaining bytes */
109 while (remaining != 0) {
110 byte_index = idx / 8;
111 uint32_t bit_index = idx % 8;
112
113 target = bitmap + byte_index;
114 *target &= ~ (1 << bit_index);
115
116 idx++;
117 remaining--;
118 }
119}
120
121/** Set bit in bitmap to 1 (used).
122 *
123 * @param bitmap Pointer to bitmap
124 * @param index Index of bit to set
125 *
126 */
127void ext4_bitmap_set_bit(uint8_t *bitmap, uint32_t index)
128{
129 uint32_t byte_index = index / 8;
130 uint32_t bit_index = index % 8;
131
132 uint8_t *target = bitmap + byte_index;
133
134 *target |= 1 << bit_index;
135}
136
137/** Check if requested bit is free.
138 *
139 * @param bitmap Pointer to bitmap
140 * @param index Index of bit to be checked
141 *
142 * @return True if bit is free, else false
143 *
144 */
145bool ext4_bitmap_is_free_bit(uint8_t *bitmap, uint32_t index)
146{
147 uint32_t byte_index = index / 8;
148 uint32_t bit_index = index % 8;
149
150 uint8_t *target = bitmap + byte_index;
151
152 if (*target & (1 << bit_index))
153 return false;
154 else
155 return true;
156}
157
158/** Try to find free byte and set the first bit as used.
159 *
160 * Walk through bitmap and try to find free byte (equal to 0).
161 * If byte found, set the first bit as used.
162 *
163 * @param bitmap Pointer to bitmap
164 * @param start Index of bit, where the algorithm will begin
165 * @param index Output value - index of bit (if found free byte)
166 * @param max Maximum index of bit in bitmap
167 *
168 * @return Error code
169 *
170 */
171errno_t ext4_bitmap_find_free_byte_and_set_bit(uint8_t *bitmap, uint32_t start,
172 uint32_t *index, uint32_t max)
173{
174 uint32_t idx;
175
176 /* Align idx */
177 if (start % 8)
178 idx = start + (8 - (start % 8));
179 else
180 idx = start;
181
182 uint8_t *pos = bitmap + (idx / 8);
183
184 /* Try to find free byte */
185 while (idx < max) {
186 if (*pos == 0) {
187 *pos |= 1;
188
189 *index = idx;
190 return EOK;
191 }
192
193 idx += 8;
194 ++pos;
195 }
196
197 /* Free byte not found */
198 return ENOSPC;
199}
200
201/** Try to find free bit and set it as used (1).
202 *
203 * Walk through bitmap and try to find any free bit.
204 *
205 * @param bitmap Pointer to bitmap
206 * @param start_idx Index of bit, where algorithm will begin
207 * @param index Output value - index of set bit (if found)
208 * @param max Maximum index of bit in bitmap
209 *
210 * @return Error code
211 *
212 */
213errno_t ext4_bitmap_find_free_bit_and_set(uint8_t *bitmap, uint32_t start_idx,
214 uint32_t *index, uint32_t max)
215{
216 uint8_t *pos = bitmap + (start_idx / 8);
217 uint32_t idx = start_idx;
218 bool byte_part = false;
219
220 /* Check the rest of first byte */
221 while ((idx % 8) != 0) {
222 byte_part = true;
223
224 if ((*pos & (1 << (idx % 8))) == 0) {
225 *pos |= (1 << (idx % 8));
226 *index = idx;
227 return EOK;
228 }
229
230 ++idx;
231 }
232
233 if (byte_part)
234 ++pos;
235
236 /* Check the whole bytes (255 = 11111111 binary) */
237 while (idx < max) {
238 if ((*pos & 255) != 255) {
239 /* Free bit found */
240 break;
241 }
242
243 idx += 8;
244 ++pos;
245 }
246
247 /* If idx < max, some free bit found */
248 if (idx < max) {
249 /* Check which bit from byte is free */
250 for (uint8_t i = 0; i < 8; ++i) {
251 if ((*pos & (1 << i)) == 0) {
252 /* Free bit found */
253 *pos |= (1 << i);
254
255 *index = idx;
256 return EOK;
257 }
258
259 idx++;
260 }
261 }
262
263 /* Free bit not found */
264 return ENOSPC;
265}
266
267/**
268 * @}
269 */
Note: See TracBrowser for help on using the repository browser.