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;
233 gd
->free_blocks_count
-= EXT2_PREALLOC_BLOCKS
;
234 sp
->s_free_blocks_count
-= EXT2_PREALLOC_BLOCKS
;
235 lmfs_change_blockusage(EXT2_PREALLOC_BLOCKS
);
236 group_descriptors_dirty
= 1;
241 bit
= setbit(b_bitmap(bp
), sp
->s_blocks_per_group
, word
);
244 panic("ext2: allocator failed to allocate a bit in bitmap\
252 block
= sp
->s_first_data_block
+ group
* sp
->s_blocks_per_group
+ bit
;
253 check_block_number(block
, sp
, gd
);
258 gd
->free_blocks_count
--;
259 sp
->s_free_blocks_count
--;
260 lmfs_change_blockusage(1);
261 group_descriptors_dirty
= 1;
263 if (update_bsearch
&& block
!= -1 && block
!= NO_BLOCK
) {
264 /* We searched from the beginning, update bsearch. */
265 sp
->s_bsearch
= block
;
275 /*===========================================================================*
277 *===========================================================================*/
278 void free_block(struct super_block
*sp
, bit_t bit_returned
)
280 /* Return a block by turning off its bitmap bit. */
281 int group
; /* group number of bit_returned */
282 int bit
; /* bit_returned number within its group */
284 struct group_desc
*gd
;
287 panic("can't free bit on read-only filesys.");
289 if (bit_returned
>= sp
->s_blocks_count
||
290 bit_returned
< sp
->s_first_data_block
)
291 panic("trying to free block %d beyond blocks scope.",
294 /* At first search group, to which bit_returned belongs to
295 * and figure out in what word bit is stored.
297 group
= (bit_returned
- sp
->s_first_data_block
) / sp
->s_blocks_per_group
;
298 bit
= (bit_returned
- sp
->s_first_data_block
) % sp
->s_blocks_per_group
;
300 gd
= get_group_desc(group
);
302 panic("can't get group_desc to alloc block");
304 /* We might be buggy (No way! :P), so check if we deallocate
305 * data block, but not control (system) block.
306 * This should never happen.
308 if (bit_returned
== gd
->inode_bitmap
|| bit_returned
== gd
->block_bitmap
309 || (bit_returned
>= gd
->inode_table
310 && bit_returned
< (gd
->inode_table
+ sp
->s_itb_per_group
))) {
311 ext2_debug("ext2: freeing non-data block %d\n", bit_returned
);
312 panic("trying to deallocate \
313 system/control block, hardly poke author.");
316 bp
= get_block(sp
->s_dev
, gd
->block_bitmap
, NORMAL
);
318 if (unsetbit(b_bitmap(bp
), bit
))
319 panic("Tried to free unused block %d", bit_returned
);
324 gd
->free_blocks_count
++;
325 sp
->s_free_blocks_count
++;
326 lmfs_change_blockusage(-1);
328 group_descriptors_dirty
= 1;
330 if (bit_returned
< sp
->s_bsearch
)
331 sp
->s_bsearch
= bit_returned
;
333 /* Also tell libminixfs, so that 1) if it has this block in its cache, it can
334 * mark it as clean, thus reducing useless writes, and 2) it can tell VM that
335 * any previous inode association is to be broken for this block, so that the
336 * block will not be mapped in erroneously later on.
338 lmfs_free_block(sp
->s_dev
, (block_t
)bit_returned
);
342 static void check_block_number(block_t block
, struct super_block
*sp
,
343 struct group_desc
*gd
)
346 /* Check if we allocated a data block, but not control (system) block.
347 * Only major bug can cause us to allocate wrong block. If it happens,
348 * we panic (and don't bloat filesystem's bitmap).
350 if (block
== gd
->inode_bitmap
|| block
== gd
->block_bitmap
||
351 (block
>= gd
->inode_table
352 && block
< (gd
->inode_table
+ sp
->s_itb_per_group
))) {
353 ext2_debug("ext2: allocating non-data block %d\n", block
);
354 panic("ext2: block allocator tryed to return \
355 system/control block, poke author.\n");
358 if (block
>= sp
->s_blocks_count
) {
359 panic("ext2: allocator returned blocknum greater, than \
360 total number of blocks.\n");