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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ee257b2 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
RevLine 
[77bb55b]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
[ba5beaf]33#include <stdlib.h>
34#include "mfs.h"
35
36static int
[147c9f6]37find_free_bit_and_set(bitchunk_t *b, const int bsize,
[44c6091f]38 const bool native, unsigned start_bit);
[ba5beaf]39
[70ac0af]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
[365e5e08]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 */
[70ac0af]54int
55mfs_alloc_inode(struct mfs_instance *inst, uint32_t *inum)
56{
[76b7622]57 int r = mfs_alloc_bit(inst, inum, BMAP_INODE);
58
59 *inum += 1;
60 return r;
[70ac0af]61}
62
[365e5e08]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 */
[70ac0af]70int
71mfs_free_inode(struct mfs_instance *inst, uint32_t inum)
72{
[b489f66]73 return mfs_free_bit(inst, inum - 1, BMAP_INODE);
[70ac0af]74}
75
[365e5e08]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 */
[70ac0af]84int
85mfs_alloc_zone(struct mfs_instance *inst, uint32_t *zone)
86{
87 int r = mfs_alloc_bit(inst, zone, BMAP_ZONE);
88
[38224615]89 *zone += inst->sbi->firstdatazone - 1;
[70ac0af]90 return r;
91}
92
[365e5e08]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 */
[2cf95e8]100int
[70ac0af]101mfs_free_zone(struct mfs_instance *inst, uint32_t zone)
102{
[38224615]103 zone -= inst->sbi->firstdatazone - 1;
[70ac0af]104
105 return mfs_free_bit(inst, zone, BMAP_ZONE);
106}
107
[365e5e08]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 */
[70ac0af]117static int
[2cf95e8]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;
[b489f66]123 unsigned *search;
[2cf95e8]124 block_t *b;
125
126 assert(inst != NULL);
127 sbi = inst->sbi;
128 assert(sbi != NULL);
129
130 if (bid == BMAP_ZONE) {
[b489f66]131 search = &sbi->zsearch;
[2cf95e8]132 start_block = 2 + sbi->ibmap_blocks;
133 if (idx > sbi->nzones) {
134 printf(NAME ": Error! Trying to free beyond the" \
[44c6091f]135 "bitmap max size\n");
[2cf95e8]136 return -1;
137 }
138 } else {
139 /*bid == BMAP_INODE*/
[b489f66]140 search = &sbi->isearch;
[2cf95e8]141 start_block = 2;
142 if (idx > sbi->ninodes) {
143 printf(NAME ": Error! Trying to free beyond the" \
[44c6091f]144 "bitmap max size\n");
[2cf95e8]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);
[8a49fed]153 on_error(r, goto out_err);
[2cf95e8]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;
[8829e33]159 const size_t chunk_bits = sizeof(bitchunk_t) * 8;
[2cf95e8]160
[8829e33]161 chunk = conv32(sbi->native, ptr[idx / chunk_bits]);
162 chunk &= ~(1 << (idx % chunk_bits));
163 ptr[idx / chunk_bits] = conv32(sbi->native, chunk);
[76b7622]164
[2cf95e8]165 b->dirty = true;
[8a49fed]166 r = block_put(b);
[a5bad72]167 mfsdebug("free index %u\n", idx);
[2cf95e8]168
[b489f66]169 if (*search > idx)
170 *search = idx;
171
[2cf95e8]172out_err:
173 return r;
174}
175
[365e5e08]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 */
[70ac0af]186static int
[ba5beaf]187mfs_alloc_bit(struct mfs_instance *inst, uint32_t *idx, bmap_id_t bid)
188{
189 struct mfs_sb_info *sbi;
[77a2d77]190 uint32_t limit;
[ba5beaf]191 unsigned long nblocks;
[77a2d77]192 unsigned *search, i, start_block;
[147c9f6]193 unsigned bits_per_block;
[ba5beaf]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;
[77a2d77]204 limit = sbi->nzones;
[ba5beaf]205 } else {
206 /*bid == BMAP_INODE*/
207 search = &sbi->isearch;
208 start_block = 2;
209 nblocks = sbi->ibmap_blocks;
[77a2d77]210 limit = sbi->ninodes;
[ba5beaf]211 }
[147c9f6]212 bits_per_block = sbi->block_size * 8;
[ba5beaf]213
214 block_t *b;
215
216retry:
217
[147c9f6]218 for (i = *search / bits_per_block; i < nblocks; ++i) {
[106743d]219 r = block_get(&b, inst->handle, i + start_block,
[44c6091f]220 BLOCK_FLAGS_NONE);
[ba5beaf]221
[8a49fed]222 on_error(r, goto out);
[ba5beaf]223
[40949d5]224 unsigned tmp = *search % bits_per_block;
225
[ba5beaf]226 freebit = find_free_bit_and_set(b->data, sbi->block_size,
[40949d5]227 sbi->native, tmp);
[ba5beaf]228 if (freebit == -1) {
229 /*No free bit in this block*/
230 block_put(b);
231 continue;
232 }
233
[8829e33]234 /*Free bit found in this block, compute the real index*/
[a900fb1]235 *idx = freebit + bits_per_block * i;
236 mfsdebug("alloc index %d %d\n", (int) *idx, i);
[77a2d77]237 if (*idx > limit) {
238 /*Index is beyond the limit, it is invalid*/
[8a49fed]239 r = block_put(b);
240 on_error(r, goto out);
[77a2d77]241 break;
242 }
243
[8829e33]244 *search = *idx;
[ba5beaf]245 b->dirty = true;
[8a49fed]246 r = block_put(b);
247 goto out;
[ba5beaf]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
[147c9f6]264find_free_bit_and_set(bitchunk_t *b, const int bsize,
[44c6091f]265 const bool native, unsigned start_bit)
[ba5beaf]266{
267 int r = -1;
268 unsigned i, j;
269 bitchunk_t chunk;
[8829e33]270 const size_t chunk_bits = sizeof(bitchunk_t) * 8;
[ba5beaf]271
[40949d5]272 for (i = start_bit / chunk_bits;
273 i < bsize / sizeof(bitchunk_t); ++i) {
[6fcc03a]274 if (!(~b[i])) {
[ba5beaf]275 /*No free bit in this chunk*/
276 continue;
277 }
278
[147c9f6]279 chunk = conv32(native, b[i]);
[ba5beaf]280
[8829e33]281 for (j = 0; j < chunk_bits; ++j) {
[a900fb1]282 if (!(chunk & (1 << j))) {
[8829e33]283 r = i * chunk_bits + j;
[ba5beaf]284 chunk |= 1 << j;
[147c9f6]285 b[i] = conv32(native, chunk);
[ba5beaf]286 goto found;
287 }
288 }
289 }
290found:
291 return r;
292}
293
[77bb55b]294/**
295 * @}
[44c6091f]296 */
[77bb55b]297
Note: See TracBrowser for help on using the repository browser.