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

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

Add a function to free an entry in the inode or zone bitmap

  • Property mode set to 100644
File size: 3.0 KB
Line 
1#include <stdlib.h>
2#include <assert.h>
3#include <errno.h>
4#include "mfs.h"
5#include "mfs_utils.h"
6
7static int
8find_free_bit_and_set(bitchunk_t *b, const int bsize, const bool native);
9
10int
11mfs_free_bit(struct mfs_instance *inst, uint32_t idx, bmap_id_t bid)
12{
13 struct mfs_sb_info *sbi;
14 int r;
15 unsigned start_block;
16 block_t *b;
17
18 assert(inst != NULL);
19 sbi = inst->sbi;
20 assert(sbi != NULL);
21
22 if (bid == BMAP_ZONE) {
23 start_block = 2 + sbi->ibmap_blocks;
24 if (idx > sbi->nzones) {
25 printf(NAME ": Error! Trying to free beyond the" \
26 "bitmap max size\n");
27 return -1;
28 }
29 } else {
30 /*bid == BMAP_INODE*/
31 start_block = 2;
32 if (idx > sbi->ninodes) {
33 printf(NAME ": Error! Trying to free beyond the" \
34 "bitmap max size\n");
35 return -1;
36 }
37 }
38
39 /*Compute the bitmap block*/
40 uint32_t block = idx / (sbi->block_size * 8) + start_block;
41
42 r = block_get(&b, inst->handle, block, BLOCK_FLAGS_NONE);
43 if (r != EOK)
44 goto out_err;
45
46 /*Compute the bit index in the block*/
47 idx %= (sbi->block_size * 8);
48 bitchunk_t *ptr = b->data;
49 bitchunk_t chunk;
50
51 chunk = conv32(sbi->native, ptr[idx / 32]);
52 chunk &= ~(1 << (idx % 32));
53 ptr[idx / 32] = conv32(sbi->native, chunk);
54 b->dirty = true;
55 r = EOK;
56 block_put(b);
57
58out_err:
59 return r;
60}
61
62int
63mfs_alloc_bit(struct mfs_instance *inst, uint32_t *idx, bmap_id_t bid)
64{
65 struct mfs_sb_info *sbi;
66 uint32_t limit;
67 unsigned long nblocks;
68 unsigned *search, i, start_block;
69 int r, freebit;
70
71 assert(inst != NULL);
72 sbi = inst->sbi;
73 assert(sbi != NULL);
74
75 if (bid == BMAP_ZONE) {
76 search = &sbi->zsearch;
77 start_block = 2 + sbi->ibmap_blocks;
78 nblocks = sbi->zbmap_blocks;
79 limit = sbi->nzones;
80 } else {
81 /*bid == BMAP_INODE*/
82 search = &sbi->isearch;
83 start_block = 2;
84 nblocks = sbi->ibmap_blocks;
85 limit = sbi->ninodes;
86 }
87
88 block_t *b;
89
90retry:
91
92 for (i = *search; i < nblocks; ++i) {
93 r = block_get(&b, inst->handle, i, BLOCK_FLAGS_NONE);
94
95 if (r != EOK)
96 goto out;
97
98 freebit = find_free_bit_and_set(b->data, sbi->block_size,
99 sbi->native);
100 if (freebit == -1) {
101 /*No free bit in this block*/
102 block_put(b);
103 continue;
104 }
105
106 /*Free bit found, compute real index*/
107 *idx = (freebit + sbi->block_size * 8 * i);
108 if (*idx > limit) {
109 /*Index is beyond the limit, it is invalid*/
110 block_put(b);
111 break;
112 }
113
114 *search = i;
115 b->dirty = true;
116 block_put(b);
117 goto found;
118 }
119
120 if (*search > 0) {
121 /*Repeat the search from the first bitmap block*/
122 *search = 0;
123 goto retry;
124 }
125
126 /*Free bit not found, return error*/
127 return ENOSPC;
128
129found:
130 r = EOK;
131
132out:
133 return r;
134}
135
136static int
137find_free_bit_and_set(bitchunk_t *b, const int bsize, const bool native)
138{
139 int r = -1;
140 unsigned i, j;
141 bitchunk_t chunk;
142
143 for (i = 0; i < bsize / sizeof(uint32_t); ++i, ++b) {
144 if (~*b) {
145 /*No free bit in this chunk*/
146 continue;
147 }
148
149 chunk = conv32(native, *b);
150
151 for (j = 0; j < 32; ++j) {
152 if (chunk & (1 << j)) {
153 r = i * 32 + j;
154 chunk |= 1 << j;
155 *b = conv32(native, chunk);
156 goto found;
157 }
158 }
159 }
160found:
161 return r;
162}
163
Note: See TracBrowser for help on using the repository browser.