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

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

Add copyright headers to mfs_balloc.c

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