1 /* This files manages blocks allocation and deallocation.
3 * The entry points into this file are:
4 * discard_preallocated_blocks: Discard preallocated blocks.
5 * alloc_block: somebody wants to allocate a block; find one.
6 * free_block: indicate that a block is available for new allocation.
9 * June 2010 (Evgeniy Ivanov)
15 #include <minix/com.h>
16 #include <minix/u64.h>
23 static block_t
alloc_block_bit(struct super_block
*sp
, block_t origin
,
26 /*===========================================================================*
27 * discard_preallocated_blocks *
28 *===========================================================================*/
29 void discard_preallocated_blocks(struct inode
*rip
)
31 /* When called for rip, discard (free) blocks preallocated for rip,
32 * otherwise discard all preallocated blocks.
33 * Normally it should be called in following situations:
35 * 2. File is truncated.
36 * 3. Non-sequential write.
37 * 4. inode is "unloaded" from the memory.
38 * 5. No free blocks left (discard all preallocated blocks).
43 rip
->i_prealloc_count
= rip
->i_prealloc_index
= 0;
44 for (i
= 0; i
< EXT2_PREALLOC_BLOCKS
; i
++) {
45 if (rip
->i_prealloc_blocks
[i
] != NO_BLOCK
) {
46 free_block(rip
->i_sp
, rip
->i_prealloc_blocks
[i
]);
47 rip
->i_prealloc_blocks
[i
] = NO_BLOCK
;
53 /* Discard all allocated blocks.
54 * Probably there are just few blocks on the disc, so forbid preallocation.*/
55 for(rip
= &inode
[0]; rip
< &inode
[NR_INODES
]; rip
++) {
56 rip
->i_prealloc_count
= rip
->i_prealloc_index
= 0;
57 rip
->i_preallocation
= 0; /* forbid preallocation */
58 for (i
= 0; i
< EXT2_PREALLOC_BLOCKS
; i
++) {
59 if (rip
->i_prealloc_blocks
[i
] != NO_BLOCK
) {
60 free_block(rip
->i_sp
, rip
->i_prealloc_blocks
[i
]);
61 rip
->i_prealloc_blocks
[i
] = NO_BLOCK
;
68 /*===========================================================================*
70 *===========================================================================*/
71 block_t
alloc_block(struct inode
*rip
, block_t block
)
73 /* Allocate a block for inode. If block is provided, then use it as a goal:
74 * try to allocate this block or his neghbors.
75 * If block is not provided then goal is group, where inode lives.
79 struct super_block
*sp
= rip
->i_sp
;
82 panic("can't alloc block on read-only filesys.");
84 /* Check for free blocks. First time discard preallocation,
85 * next time return NO_BLOCK
87 if (!opt
.use_reserved_blocks
&&
88 sp
->s_free_blocks_count
<= sp
->s_r_blocks_count
) {
89 discard_preallocated_blocks(NULL
);
90 } else if (sp
->s_free_blocks_count
<= EXT2_PREALLOC_BLOCKS
) {
91 discard_preallocated_blocks(NULL
);
94 if (!opt
.use_reserved_blocks
&&
95 sp
->s_free_blocks_count
<= sp
->s_r_blocks_count
) {
97 } else if (sp
->s_free_blocks_count
== 0) {
101 if (block
!= NO_BLOCK
) {
103 if (rip
->i_preallocation
&& rip
->i_prealloc_count
> 0) {
104 /* check if goal is preallocated */
105 b
= rip
->i_prealloc_blocks
[rip
->i_prealloc_index
];
106 if (block
== b
|| (block
+ 1) == b
) {
107 /* use preallocated block */
108 rip
->i_prealloc_blocks
[rip
->i_prealloc_index
] = NO_BLOCK
;
109 rip
->i_prealloc_count
--;
110 rip
->i_prealloc_index
++;
111 if (rip
->i_prealloc_index
>= EXT2_PREALLOC_BLOCKS
) {
112 rip
->i_prealloc_index
= 0;
113 ASSERT(rip
->i_prealloc_count
== 0);
118 /* probably non-sequential write operation,
119 * disable preallocation for this inode.
121 rip
->i_preallocation
= 0;
122 discard_preallocated_blocks(rip
);
126 int group
= (rip
->i_num
- 1) / sp
->s_inodes_per_group
;
127 goal
= sp
->s_blocks_per_group
*group
+ sp
->s_first_data_block
;
130 if (rip
->i_preallocation
&& rip
->i_prealloc_count
) {
131 ext2_debug("There're preallocated blocks, but they're\
132 neither used or freed!");
135 b
= alloc_block_bit(sp
, goal
, rip
);
144 static void check_block_number(block_t block
, struct super_block
*sp
,
145 struct group_desc
*gd
);
147 /*===========================================================================*
149 *===========================================================================*/
150 static block_t
alloc_block_bit(sp
, goal
, rip
)
151 struct super_block
*sp
; /* the filesystem to allocate from */
152 block_t goal
; /* try to allocate near this block */
153 struct inode
*rip
; /* used for preallocation */
155 block_t block
= NO_BLOCK
; /* allocated block */
156 int word
; /* word in block bitmap */
159 char update_bsearch
= FALSE
;
162 if (goal
>= sp
->s_blocks_count
||
163 (goal
< sp
->s_first_data_block
&& goal
!= 0)) {
164 goal
= sp
->s_bsearch
;
167 if (goal
<= sp
->s_bsearch
) {
168 /* No reason to search in a place with no free blocks */
169 goal
= sp
->s_bsearch
;
170 update_bsearch
= TRUE
;
173 /* Figure out where to start the bit search. */
174 word
= ((goal
- sp
->s_first_data_block
) % sp
->s_blocks_per_group
)
177 /* Try to allocate block at any group starting from the goal's group.
178 * First time goal's group is checked from the word=goal, after all
179 * groups checked, it's checked again from word=0, that's why "i <=".
181 group
= (goal
- sp
->s_first_data_block
) / sp
->s_blocks_per_group
;
182 for (i
= 0; i
<= sp
->s_groups_count
; i
++, group
++) {
184 struct group_desc
*gd
;
186 if (group
>= sp
->s_groups_count
)
189 gd
= get_group_desc(group
);
191 panic("can't get group_desc to alloc block");
193 if (gd
->free_blocks_count
== 0) {
198 bp
= get_block(sp
->s_dev
, gd
->block_bitmap
, NORMAL
);
200 if (rip
->i_preallocation
&&
201 gd
->free_blocks_count
>= (EXT2_PREALLOC_BLOCKS
* 4) ) {
202 /* Try to preallocate blocks */
203 if (rip
->i_prealloc_count
!= 0) {
204 /* kind of glitch... */
205 discard_preallocated_blocks(rip
);
206 ext2_debug("warning, discarding previously preallocated\
207 blocks! It had to be done by another code.");
209 ASSERT(rip
->i_prealloc_count
== 0);
210 /* we preallocate bytes only */
211 ASSERT(EXT2_PREALLOC_BLOCKS
== sizeof(char)*CHAR_BIT
);
213 bit
= setbyte(b_bitmap(bp
), sp
->s_blocks_per_group
);
215 block
= bit
+ sp
->s_first_data_block
+
216 group
* sp
->s_blocks_per_group
;
217 check_block_number(block
, sp
, gd
);
219 /* We preallocate a byte starting from block.
220 * First preallocated block will be returned as
221 * normally allocated block.
223 for (i
= 1; i
< EXT2_PREALLOC_BLOCKS
; i
++) {
224 check_block_number(block
+ i
, sp
, gd
);
225 rip
->i_prealloc_blocks
[i
-1] = block
+ i
;
227 rip
->i_prealloc_index
= 0;
228 rip
->i_prealloc_count
= EXT2_PREALLOC_BLOCKS
- 1;
231 put_block(bp
, MAP_BLOCK
);
233 gd
->free_blocks_count
-= EXT2_PREALLOC_BLOCKS
;
234 sp
->s_free_blocks_count
-= EXT2_PREALLOC_BLOCKS
;
235 group_descriptors_dirty
= 1;
240 bit
= setbit(b_bitmap(bp
), sp
->s_blocks_per_group
, word
);
243 panic("ext2: allocator failed to allocate a bit in bitmap\
251 block
= sp
->s_first_data_block
+ group
* sp
->s_blocks_per_group
+ bit
;
252 check_block_number(block
, sp
, gd
);
255 put_block(bp
, MAP_BLOCK
);
257 gd
->free_blocks_count
--;
258 sp
->s_free_blocks_count
--;
259 group_descriptors_dirty
= 1;
261 if (update_bsearch
&& block
!= -1 && block
!= NO_BLOCK
) {
262 /* We searched from the beginning, update bsearch. */
263 sp
->s_bsearch
= block
;
273 /*===========================================================================*
275 *===========================================================================*/
276 void free_block(struct super_block
*sp
, bit_t bit_returned
)
278 /* Return a block by turning off its bitmap bit. */
279 int group
; /* group number of bit_returned */
280 int bit
; /* bit_returned number within its group */
282 struct group_desc
*gd
;
285 panic("can't free bit on read-only filesys.");
287 if (bit_returned
>= sp
->s_blocks_count
||
288 bit_returned
< sp
->s_first_data_block
)
289 panic("trying to free block %d beyond blocks scope.",
292 /* At first search group, to which bit_returned belongs to
293 * and figure out in what word bit is stored.
295 group
= (bit_returned
- sp
->s_first_data_block
) / sp
->s_blocks_per_group
;
296 bit
= (bit_returned
- sp
->s_first_data_block
) % sp
->s_blocks_per_group
;
298 gd
= get_group_desc(group
);
300 panic("can't get group_desc to alloc block");
302 /* We might be buggy (No way! :P), so check if we deallocate
303 * data block, but not control (system) block.
304 * This should never happen.
306 if (bit_returned
== gd
->inode_bitmap
|| bit_returned
== gd
->block_bitmap
307 || (bit_returned
>= gd
->inode_table
308 && bit_returned
< (gd
->inode_table
+ sp
->s_itb_per_group
))) {
309 ext2_debug("ext2: freeing non-data block %d\n", bit_returned
);
310 panic("trying to deallocate \
311 system/control block, hardly poke author.");
314 bp
= get_block(sp
->s_dev
, gd
->block_bitmap
, NORMAL
);
316 if (unsetbit(b_bitmap(bp
), bit
))
317 panic("Tried to free unused block", bit_returned
);
320 put_block(bp
, MAP_BLOCK
);
322 gd
->free_blocks_count
++;
323 sp
->s_free_blocks_count
++;
325 group_descriptors_dirty
= 1;
327 if (bit_returned
< sp
->s_bsearch
)
328 sp
->s_bsearch
= bit_returned
;
332 static void check_block_number(block_t block
, struct super_block
*sp
,
333 struct group_desc
*gd
)
336 /* Check if we allocated a data block, but not control (system) block.
337 * Only major bug can cause us to allocate wrong block. If it happens,
338 * we panic (and don't bloat filesystem's bitmap).
340 if (block
== gd
->inode_bitmap
|| block
== gd
->block_bitmap
||
341 (block
>= gd
->inode_table
342 && block
< (gd
->inode_table
+ sp
->s_itb_per_group
))) {
343 ext2_debug("ext2: allocating non-data block %d\n", block
);
344 panic("ext2: block allocator tryed to return \
345 system/control block, poke author.\n");
348 if (block
>= sp
->s_blocks_count
) {
349 panic("ext2: allocator returned blocknum greater, than \
350 total number of blocks.\n");