source: mainline/uspace/srv/fs/minixfs/mfs_balloc.c@ dd9af5d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dd9af5d was 88be951e, checked in by Maurizio Lombardi <m.lombardi85@…>, 14 years ago

Remove the mfs_utils.h file

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 * Copyright (c) 2011 Maurizio Lombardi
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 fs
30 * @{
31 */
32
33#include <stdlib.h>
34#include "mfs.h"
35
36static int
37find_free_bit_and_set(bitchunk_t *b, const int bsize,
38 const bool native, unsigned start_bit);
39
40static int
41mfs_free_bit(struct mfs_instance *inst, uint32_t idx, bmap_id_t bid);
42
43static int
44mfs_alloc_bit(struct mfs_instance *inst, uint32_t *idx, bmap_id_t bid);
45
46/**Allocate a new inode.
47 *
48 * @param inst Pointer to the filesystem instance.
49 * @param inum Pointer to a 32 bit number where the index of
50 * the new inode will be saved.
51 *
52 * @return EOK on success or a negative error code.
53 */
54int
55mfs_alloc_inode(struct mfs_instance *inst, uint32_t *inum)
56{
57 int r = mfs_alloc_bit(inst, inum, BMAP_INODE);
58
59 *inum += 1;
60 return r;
61}
62
63/**Free an inode.
64 *
65 * @param inst Pointer to the filesystem instance.
66 * @param inum Number of the inode to free.
67 *
68 * @return EOK on success or a negative error code.
69 */
70int
71mfs_free_inode(struct mfs_instance *inst, uint32_t inum)
72{
73 return mfs_free_bit(inst, inum - 1, BMAP_INODE);
74}
75
76/**Allocate a new zone.
77 *
78 * @param inst Pointer to the filesystem instance.
79 * @param zone Pointer to a 32 bit number where the index
80 * of the zone will be saved.
81 *
82 * @return EOK on success or a negative error code.
83 */
84int
85mfs_alloc_zone(struct mfs_instance *inst, uint32_t *zone)
86{
87 int r = mfs_alloc_bit(inst, zone, BMAP_ZONE);
88
89 *zone += inst->sbi->firstdatazone - 1;
90 return r;
91}
92
93/**Free a zone.
94 *
95 * @param inst Pointer to the filesystem instance.
96 * @param zone Index of the zone to free.
97 *
98 * @return EOK on success or a negative error code.
99 */
100int
101mfs_free_zone(struct mfs_instance *inst, uint32_t zone)
102{
103 zone -= inst->sbi->firstdatazone - 1;
104
105 return mfs_free_bit(inst, zone, BMAP_ZONE);
106}
107
108/**Clear a bit in a bitmap.
109 *
110 * @param inst Pointer to the filesystem instance.
111 * @param idx Index of the bit to clear.
112 * @param bid BMAP_ZONE if operating on the zone's bitmap,
113 * BMAP_INODE if operating on the inode's bitmap.
114 *
115 * @return EOK on success or a negative error code.
116 */
117static int
118mfs_free_bit(struct mfs_instance *inst, uint32_t idx, bmap_id_t bid)
119{
120 struct mfs_sb_info *sbi;
121 int r;
122 unsigned start_block;
123 unsigned *search;
124 block_t *b;
125
126 assert(inst != NULL);
127 sbi = inst->sbi;
128 assert(sbi != NULL);
129
130 if (bid == BMAP_ZONE) {
131 search = &sbi->zsearch;
132 start_block = 2 + sbi->ibmap_blocks;
133 if (idx > sbi->nzones) {
134 printf(NAME ": Error! Trying to free beyond the" \
135 "bitmap max size\n");
136 return -1;
137 }
138 } else {
139 /*bid == BMAP_INODE*/
140 search = &sbi->isearch;
141 start_block = 2;
142 if (idx > sbi->ninodes) {
143 printf(NAME ": Error! Trying to free beyond the" \
144 "bitmap max size\n");
145 return -1;
146 }
147 }
148
149 /*Compute the bitmap block*/
150 uint32_t block = idx / (sbi->block_size * 8) + start_block;
151
152 r = block_get(&b, inst->handle, block, BLOCK_FLAGS_NONE);
153 on_error(r, goto out_err);
154
155 /*Compute the bit index in the block*/
156 idx %= (sbi->block_size * 8);
157 bitchunk_t *ptr = b->data;
158 bitchunk_t chunk;
159 const size_t chunk_bits = sizeof(bitchunk_t) * 8;
160
161 chunk = conv32(sbi->native, ptr[idx / chunk_bits]);
162 chunk &= ~(1 << (idx % chunk_bits));
163 ptr[idx / chunk_bits] = conv32(sbi->native, chunk);
164
165 b->dirty = true;
166 r = block_put(b);
167 mfsdebug("free index %u\n", idx);
168
169 if (*search > idx)
170 *search = idx;
171
172out_err:
173 return r;
174}
175
176/**Search a free bit in a bitmap and mark it as used.
177 *
178 * @param inst Pointer to the filesystem instance.
179 * @param idx Pointer of a 32 bit number where the index
180 * of the found bit will be stored.
181 * @param bid BMAP_ZONE if operating on the zone's bitmap,
182 * BMAP_INODE if operating on the inode's bitmap.
183 *
184 * @return EOK on success or a negative error code.
185 */
186static int
187mfs_alloc_bit(struct mfs_instance *inst, uint32_t *idx, bmap_id_t bid)
188{
189 struct mfs_sb_info *sbi;
190 uint32_t limit;
191 unsigned long nblocks;
192 unsigned *search, i, start_block;
193 unsigned bits_per_block;
194 int r, freebit;
195
196 assert(inst != NULL);
197 sbi = inst->sbi;
198 assert(sbi != NULL);
199
200 if (bid == BMAP_ZONE) {
201 search = &sbi->zsearch;
202 start_block = 2 + sbi->ibmap_blocks;
203 nblocks = sbi->zbmap_blocks;
204 limit = sbi->nzones;
205 } else {
206 /*bid == BMAP_INODE*/
207 search = &sbi->isearch;
208 start_block = 2;
209 nblocks = sbi->ibmap_blocks;
210 limit = sbi->ninodes;
211 }
212 bits_per_block = sbi->block_size * 8;
213
214 block_t *b;
215
216retry:
217
218 for (i = *search / bits_per_block; i < nblocks; ++i) {
219 r = block_get(&b, inst->handle, i + start_block,
220 BLOCK_FLAGS_NONE);
221
222 on_error(r, goto out);
223
224 unsigned tmp = *search % bits_per_block;
225
226 freebit = find_free_bit_and_set(b->data, sbi->block_size,
227 sbi->native, tmp);
228 if (freebit == -1) {
229 /*No free bit in this block*/
230 block_put(b);
231 continue;
232 }
233
234 /*Free bit found in this block, compute the real index*/
235 *idx = freebit + bits_per_block * i;
236 mfsdebug("alloc index %d %d\n", (int) *idx, i);
237 if (*idx > limit) {
238 /*Index is beyond the limit, it is invalid*/
239 r = block_put(b);
240 on_error(r, goto out);
241 break;
242 }
243
244 *search = *idx;
245 b->dirty = true;
246 r = block_put(b);
247 goto out;
248 }
249
250 if (*search > 0) {
251 /*Repeat the search from the first bitmap block*/
252 *search = 0;
253 goto retry;
254 }
255
256 /*Free bit not found, return error*/
257 return ENOSPC;
258
259out:
260 return r;
261}
262
263static int
264find_free_bit_and_set(bitchunk_t *b, const int bsize,
265 const bool native, unsigned start_bit)
266{
267 int r = -1;
268 unsigned i, j;
269 bitchunk_t chunk;
270 const size_t chunk_bits = sizeof(bitchunk_t) * 8;
271
272 for (i = start_bit / chunk_bits;
273 i < bsize / sizeof(bitchunk_t); ++i) {
274 if (!(~b[i])) {
275 /*No free bit in this chunk*/
276 continue;
277 }
278
279 chunk = conv32(native, b[i]);
280
281 for (j = 0; j < chunk_bits; ++j) {
282 if (!(chunk & (1 << j))) {
283 r = i * chunk_bits + j;
284 chunk |= 1 << j;
285 b[i] = conv32(native, chunk);
286 goto found;
287 }
288 }
289 }
290found:
291 return r;
292}
293
294/**
295 * @}
296 */
297
Note: See TracBrowser for help on using the repository browser.