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

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

Fix bugs in bitmap code

  • Property mode set to 100644
File size: 4.9 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#include "mfs_utils.h"
36
37static int
[147c9f6]38find_free_bit_and_set(bitchunk_t *b, const int bsize,
[44c6091f]39 const bool native, unsigned start_bit);
[ba5beaf]40
[2cf95e8]41int
42mfs_free_bit(struct mfs_instance *inst, uint32_t idx, bmap_id_t bid)
43{
44 struct mfs_sb_info *sbi;
45 int r;
46 unsigned start_block;
47 block_t *b;
48
49 assert(inst != NULL);
50 sbi = inst->sbi;
51 assert(sbi != NULL);
52
53 if (bid == BMAP_ZONE) {
54 start_block = 2 + sbi->ibmap_blocks;
55 if (idx > sbi->nzones) {
56 printf(NAME ": Error! Trying to free beyond the" \
[44c6091f]57 "bitmap max size\n");
[2cf95e8]58 return -1;
59 }
60 } else {
61 /*bid == BMAP_INODE*/
62 start_block = 2;
63 if (idx > sbi->ninodes) {
64 printf(NAME ": Error! Trying to free beyond the" \
[44c6091f]65 "bitmap max size\n");
[2cf95e8]66 return -1;
67 }
68 }
69
70 /*Compute the bitmap block*/
71 uint32_t block = idx / (sbi->block_size * 8) + start_block;
72
73 r = block_get(&b, inst->handle, block, BLOCK_FLAGS_NONE);
[8a49fed]74 on_error(r, goto out_err);
[2cf95e8]75
76 /*Compute the bit index in the block*/
77 idx %= (sbi->block_size * 8);
78 bitchunk_t *ptr = b->data;
79 bitchunk_t chunk;
[8829e33]80 const size_t chunk_bits = sizeof(bitchunk_t) * 8;
[2cf95e8]81
[8829e33]82 chunk = conv32(sbi->native, ptr[idx / chunk_bits]);
83 chunk &= ~(1 << (idx % chunk_bits));
84 ptr[idx / chunk_bits] = conv32(sbi->native, chunk);
[2cf95e8]85 b->dirty = true;
[8a49fed]86 r = block_put(b);
[2cf95e8]87
88out_err:
89 return r;
90}
91
[ba5beaf]92int
93mfs_alloc_bit(struct mfs_instance *inst, uint32_t *idx, bmap_id_t bid)
94{
95 struct mfs_sb_info *sbi;
[77a2d77]96 uint32_t limit;
[ba5beaf]97 unsigned long nblocks;
[77a2d77]98 unsigned *search, i, start_block;
[147c9f6]99 unsigned bits_per_block;
[ba5beaf]100 int r, freebit;
101
102 assert(inst != NULL);
103 sbi = inst->sbi;
104 assert(sbi != NULL);
105
106 if (bid == BMAP_ZONE) {
107 search = &sbi->zsearch;
108 start_block = 2 + sbi->ibmap_blocks;
109 nblocks = sbi->zbmap_blocks;
[77a2d77]110 limit = sbi->nzones;
[ba5beaf]111 } else {
112 /*bid == BMAP_INODE*/
113 search = &sbi->isearch;
114 start_block = 2;
115 nblocks = sbi->ibmap_blocks;
[77a2d77]116 limit = sbi->ninodes;
[ba5beaf]117 }
[147c9f6]118 bits_per_block = sbi->block_size * 8;
[ba5beaf]119
120 block_t *b;
121
122retry:
123
[147c9f6]124 for (i = *search / bits_per_block; i < nblocks; ++i) {
[106743d]125 r = block_get(&b, inst->handle, i + start_block,
[44c6091f]126 BLOCK_FLAGS_NONE);
[ba5beaf]127
[8a49fed]128 on_error(r, goto out);
[ba5beaf]129
[40949d5]130 unsigned tmp = *search % bits_per_block;
131
[ba5beaf]132 freebit = find_free_bit_and_set(b->data, sbi->block_size,
[40949d5]133 sbi->native, tmp);
[ba5beaf]134 if (freebit == -1) {
135 /*No free bit in this block*/
136 block_put(b);
137 continue;
138 }
139
[8829e33]140 /*Free bit found in this block, compute the real index*/
[a900fb1]141 *idx = freebit + bits_per_block * i;
[40949d5]142 *idx += (bid == BMAP_INODE) ? 1 : 0;
[a900fb1]143 mfsdebug("alloc index %d %d\n", (int) *idx, i);
[77a2d77]144 if (*idx > limit) {
145 /*Index is beyond the limit, it is invalid*/
[8a49fed]146 r = block_put(b);
147 on_error(r, goto out);
[77a2d77]148 break;
149 }
150
[8829e33]151 *search = *idx;
[ba5beaf]152 b->dirty = true;
[8a49fed]153 r = block_put(b);
154 goto out;
[ba5beaf]155 }
156
157 if (*search > 0) {
158 /*Repeat the search from the first bitmap block*/
159 *search = 0;
160 goto retry;
161 }
162
163 /*Free bit not found, return error*/
164 return ENOSPC;
165
166out:
167 return r;
168}
169
170static int
[147c9f6]171find_free_bit_and_set(bitchunk_t *b, const int bsize,
[44c6091f]172 const bool native, unsigned start_bit)
[ba5beaf]173{
174 int r = -1;
175 unsigned i, j;
176 bitchunk_t chunk;
[8829e33]177 const size_t chunk_bits = sizeof(bitchunk_t) * 8;
[ba5beaf]178
[40949d5]179 for (i = start_bit / chunk_bits;
180 i < bsize / sizeof(bitchunk_t); ++i) {
[6fcc03a]181 if (!(~b[i])) {
[ba5beaf]182 /*No free bit in this chunk*/
183 continue;
184 }
185
[147c9f6]186 chunk = conv32(native, b[i]);
[ba5beaf]187
[8829e33]188 for (j = 0; j < chunk_bits; ++j) {
[a900fb1]189 if (!(chunk & (1 << j))) {
190 mfsdebug("i = %d j = %d\n", i, j);
[8829e33]191 r = i * chunk_bits + j;
[ba5beaf]192 chunk |= 1 << j;
[147c9f6]193 b[i] = conv32(native, chunk);
[ba5beaf]194 goto found;
195 }
196 }
197 }
198found:
199 return r;
200}
201
[77bb55b]202/**
203 * @}
[44c6091f]204 */
[77bb55b]205
Note: See TracBrowser for help on using the repository browser.