source: mainline/uspace/lib/ext4/libext4_bitmap.c@ 35f48f2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 35f48f2 was 35f48f2, checked in by Frantisek Princ <frantisek.princ@…>, 14 years ago

succesful writing (only for direct block)

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2011 Frantisek Princ
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 libext4
30 * @{
31 */
32
33/**
34 * @file libext4_bitmap.c
35 * @brief Ext4 bitmap (block & inode) operations.
36 */
37
38#include <errno.h>
39#include <libblock.h>
40#include <sys/types.h>
41#include "libext4.h"
42
43static void ext4_bitmap_free_bit(uint8_t *bitmap, uint32_t index)
44{
45 uint32_t byte_index = index / 8;
46 uint32_t bit_index = index % 8;
47
48 uint8_t *target = bitmap + byte_index;
49 uint8_t old_value = *target;
50
51 uint8_t new_value = old_value & (~ (1 << bit_index));
52
53 *target = new_value;
54}
55
56static int ext4_bitmap_find_free_bit_and_set(uint8_t *bitmap, uint32_t *index, uint32_t size)
57{
58 uint8_t *pos = bitmap;
59 int i;
60 uint32_t idx = 0;
61
62 while (pos < bitmap + size) {
63 if ((*pos & 255) != 255) {
64 // free bit found
65 break;
66 }
67
68 ++pos;
69 idx += 8;
70 }
71
72 if (pos < bitmap + size) {
73
74 for(i = 0; i < 8; ++i) {
75 if ((*pos & (1 << i)) == 0) {
76 // free bit found
77 *pos |= (1 << i);
78 *index = idx;
79 return EOK;
80 }
81
82 idx++;
83 }
84 }
85
86 return ENOSPC;
87}
88
89int ext4_bitmap_free_block(ext4_filesystem_t *fs, uint32_t block_index)
90{
91 int rc;
92 uint32_t blocks_per_group;
93 uint32_t block_group;
94 uint32_t index_in_group;
95 uint32_t bitmap_block;
96 ext4_block_group_ref_t *bg_ref;
97 block_t *block;
98
99 blocks_per_group = ext4_superblock_get_blocks_per_group(fs->superblock);
100 block_group = block_index / blocks_per_group;
101 index_in_group = block_index % blocks_per_group;
102
103 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
104 if (rc != EOK) {
105 return rc;
106 }
107
108 bitmap_block = ext4_block_group_get_block_bitmap(bg_ref->block_group);
109
110 rc = block_get(&block, fs->device, bitmap_block, 0);
111 if (rc != EOK) {
112 return rc;
113 }
114
115 ext4_bitmap_free_bit(block->data, index_in_group);
116
117 block->dirty = true;
118 rc = block_put(block);
119 if (rc != EOK) {
120 return rc;
121 }
122
123 uint32_t free_blocks = ext4_block_group_get_free_blocks_count(bg_ref->block_group);
124 free_blocks++;
125 ext4_block_group_set_free_blocks_count(bg_ref->block_group, free_blocks);
126 bg_ref->dirty = true;
127
128 // TODO change free blocks count in superblock
129
130 rc = ext4_filesystem_put_block_group_ref(bg_ref);
131 if (rc != EOK) {
132 // TODO error
133 return rc;
134 }
135
136 return EOK;
137}
138
139int ext4_bitmap_alloc_block(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, uint32_t *fblock)
140{
141 int rc;
142 uint32_t inodes_per_group, block_group, blocks_per_group;
143 ext4_block_group_ref_t *bg_ref;
144 uint32_t bitmap_block;
145 block_t *block;
146 uint32_t rel_block_idx = 0;
147 uint32_t block_size;
148
149 inodes_per_group = ext4_superblock_get_inodes_per_group(fs->superblock);
150 block_group = inode_ref->index / inodes_per_group;
151
152 block_size = ext4_superblock_get_block_size(fs->superblock);
153
154 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
155 if (rc != EOK) {
156 return rc;
157 }
158
159 bitmap_block = ext4_block_group_get_block_bitmap(bg_ref->block_group);
160
161 rc = block_get(&block, fs->device, bitmap_block, 0);
162 if (rc != EOK) {
163 ext4_filesystem_put_block_group_ref(bg_ref);
164 return rc;
165 }
166
167 rc = ext4_bitmap_find_free_bit_and_set(block->data, &rel_block_idx, block_size);
168
169
170 if (rc != EOK) {
171 EXT4FS_DBG("no block found");
172 // TODO if ENOSPC - try next block group - try next block groups
173 }
174
175 // TODO decrement superblock free blocks count
176 //uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
177 //sb_free_blocks--;
178 //ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
179
180 uint32_t bg_free_blocks = ext4_block_group_get_free_blocks_count(bg_ref->block_group);
181 bg_free_blocks++;
182 ext4_block_group_set_free_blocks_count(bg_ref->block_group, bg_free_blocks);
183 bg_ref->dirty = true;
184
185 // return
186 blocks_per_group = ext4_superblock_get_blocks_per_group(fs->superblock);
187 *fblock = blocks_per_group * block_group + rel_block_idx;
188 return EOK;
189
190}
191
192/**
193 * @}
194 */
Note: See TracBrowser for help on using the repository browser.