source: mainline/uspace/lib/ext4/libext4_balloc.c@ d2f5148

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

debugged version of splitting root extent node

  • Property mode set to 100644
File size: 18.2 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_balloc.c
35 * @brief Physical block allocator.
36 */
37
38#include <errno.h>
39#include <sys/types.h>
40#include "libext4.h"
41
42static uint32_t ext4_balloc_blockaddr2_index_in_group(ext4_superblock_t *sb,
43 uint32_t block_addr)
44{
45 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
46 uint32_t first_block = ext4_superblock_get_first_data_block(sb);
47
48 // First block == 0 or 1
49 if (first_block == 0) {
50 return block_addr % blocks_per_group;
51 } else {
52 return (block_addr - 1) % blocks_per_group;
53 }
54}
55
56static uint32_t ext4_balloc_index_in_group2blockaddr(ext4_superblock_t *sb,
57 uint32_t index, uint32_t bgid)
58{
59 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
60
61 if (ext4_superblock_get_first_data_block(sb) == 0) {
62 return bgid * blocks_per_group + index;
63 } else {
64 return bgid * blocks_per_group + index + 1;
65 }
66
67}
68
69static uint32_t ext4_balloc_get_bgid_of_block(ext4_superblock_t *sb,
70 uint32_t block_addr)
71{
72 uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
73 uint32_t first_block = ext4_superblock_get_first_data_block(sb);
74
75 // First block == 0 or 1
76 if (first_block == 0) {
77 return block_addr / blocks_per_group;
78 } else {
79 return (block_addr - 1) / blocks_per_group;
80 }
81}
82
83
84int ext4_balloc_free_block(ext4_inode_ref_t *inode_ref, uint32_t block_addr)
85{
86 int rc;
87
88 ext4_filesystem_t *fs = inode_ref->fs;
89 ext4_superblock_t *sb = fs->superblock;
90
91 uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, block_addr);
92 uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, block_addr);
93
94 ext4_block_group_ref_t *bg_ref;
95 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
96 if (rc != EOK) {
97 EXT4FS_DBG("error in loading bg_ref \%d", rc);
98 return rc;
99 }
100
101 uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
102 bg_ref->block_group, sb);
103 block_t *bitmap_block;
104 rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
105 if (rc != EOK) {
106 EXT4FS_DBG("error in loading bitmap \%d", rc);
107 return rc;
108 }
109
110 ext4_bitmap_free_bit(bitmap_block->data, index_in_group);
111 bitmap_block->dirty = true;
112
113 rc = block_put(bitmap_block);
114 if (rc != EOK) {
115 // Error in saving bitmap
116 ext4_filesystem_put_block_group_ref(bg_ref);
117 EXT4FS_DBG("error in saving bitmap \%d", rc);
118 return rc;
119 }
120
121 uint32_t block_size = ext4_superblock_get_block_size(sb);
122
123 // Update superblock free blocks count
124 uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
125 sb_free_blocks++;
126 ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
127
128 // Update inode blocks count
129 uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
130 ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE;
131 ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
132 inode_ref->dirty = true;
133
134 // Update block group free blocks count
135 uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
136 bg_ref->block_group, sb);
137 free_blocks++;
138 ext4_block_group_set_free_blocks_count(bg_ref->block_group,
139 sb, free_blocks);
140 bg_ref->dirty = true;
141
142 rc = ext4_filesystem_put_block_group_ref(bg_ref);
143 if (rc != EOK) {
144 EXT4FS_DBG("error in saving bg_ref \%d", rc);
145 return rc;
146 }
147
148 return EOK;
149}
150
151int ext4_balloc_free_blocks(ext4_inode_ref_t *inode_ref,
152 uint32_t first, uint32_t count)
153{
154 int rc;
155
156 ext4_filesystem_t *fs = inode_ref->fs;
157 ext4_superblock_t *sb = fs->superblock;
158
159 uint32_t block_group_first =
160 ext4_balloc_get_bgid_of_block(sb, first);
161 uint32_t block_group_last =
162 ext4_balloc_get_bgid_of_block(sb, first + count - 1);
163
164 assert(block_group_first == block_group_last);
165
166 ext4_block_group_ref_t *bg_ref;
167 rc = ext4_filesystem_get_block_group_ref(fs, block_group_first, &bg_ref);
168 if (rc != EOK) {
169 EXT4FS_DBG("error in loading bg_ref \%d", rc);
170 return rc;
171 }
172
173 uint32_t index_in_group_first =
174 ext4_balloc_blockaddr2_index_in_group(sb, first);
175
176 uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
177 bg_ref->block_group, sb);
178
179 block_t *bitmap_block;
180 rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
181 if (rc != EOK) {
182 EXT4FS_DBG("error in loading bitmap \%d", rc);
183 return rc;
184 }
185
186 ext4_bitmap_free_bits(bitmap_block->data, index_in_group_first, count);
187
188 bitmap_block->dirty = true;
189
190 rc = block_put(bitmap_block);
191 if (rc != EOK) {
192 // Error in saving bitmap
193 ext4_filesystem_put_block_group_ref(bg_ref);
194 EXT4FS_DBG("error in saving bitmap \%d", rc);
195 return rc;
196 }
197
198 uint32_t block_size = ext4_superblock_get_block_size(sb);
199
200 // Update superblock free blocks count
201 uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
202 sb_free_blocks += count;
203 ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
204
205 // Update inode blocks count
206 uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
207 ino_blocks -= count * (block_size / EXT4_INODE_BLOCK_SIZE);
208 ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
209 inode_ref->dirty = true;
210
211 // Update block group free blocks count
212 uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
213 bg_ref->block_group, sb);
214 free_blocks += count;
215 ext4_block_group_set_free_blocks_count(bg_ref->block_group,
216 sb, free_blocks);
217 bg_ref->dirty = true;
218
219 rc = ext4_filesystem_put_block_group_ref(bg_ref);
220 if (rc != EOK) {
221 EXT4FS_DBG("error in saving bg_ref \%d", rc);
222 return rc;
223 }
224
225 return EOK;
226}
227
228static uint32_t ext4_balloc_get_first_data_block_in_group(
229 ext4_superblock_t *sb, ext4_block_group_t *bg, uint32_t bgid)
230{
231 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
232 uint32_t inode_table_first_block = ext4_block_group_get_inode_table_first_block(
233 bg, sb);
234 uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
235 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
236 uint32_t block_size = ext4_superblock_get_block_size(sb);
237 uint32_t inode_table_bytes;
238
239 if (bgid < block_group_count - 1) {
240 inode_table_bytes = inodes_per_group * inode_table_item_size;
241 } else {
242 // last block group could be smaller
243 uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
244 inode_table_bytes =
245 (inodes_count_total - ((block_group_count - 1) * inodes_per_group))
246 * inode_table_item_size;
247 }
248
249 uint32_t inode_table_blocks = inode_table_bytes / block_size;
250
251 if (inode_table_bytes % block_size) {
252 inode_table_blocks++;
253 }
254
255 return inode_table_first_block + inode_table_blocks;
256}
257
258
259static uint32_t ext4_balloc_find_goal(ext4_inode_ref_t *inode_ref)
260{
261 int rc;
262 uint32_t goal = 0;
263
264 ext4_superblock_t *sb = inode_ref->fs->superblock;
265
266 uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
267 uint32_t block_size = ext4_superblock_get_block_size(sb);
268 uint32_t inode_block_count = inode_size / block_size;
269
270 if (inode_size % block_size != 0) {
271 inode_block_count++;
272 }
273
274 if (inode_block_count > 0) {
275
276 rc = ext4_filesystem_get_inode_data_block_index(inode_ref, inode_block_count - 1, &goal);
277 if (rc != EOK) {
278 return 0;
279 }
280
281 if (goal != 0) {
282 goal++;
283 return goal;
284 }
285
286 // if goal == 0, sparse file -> continue
287 }
288
289 // Identify block group of inode
290 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
291 uint32_t block_group = (inode_ref->index - 1) / inodes_per_group;
292 block_size = ext4_superblock_get_block_size(sb);
293
294 ext4_block_group_ref_t *bg_ref;
295 rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, block_group, &bg_ref);
296 if (rc != EOK) {
297 return 0;
298 }
299
300 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
301 uint32_t inode_table_first_block = ext4_block_group_get_inode_table_first_block(
302 bg_ref->block_group, sb);
303 uint16_t inode_table_item_size = ext4_superblock_get_inode_size(sb);
304 uint32_t inode_table_bytes;
305
306 if (block_group < block_group_count - 1) {
307 inode_table_bytes = inodes_per_group * inode_table_item_size;
308 } else {
309 // last block group could be smaller
310 uint32_t inodes_count_total = ext4_superblock_get_inodes_count(sb);
311 inode_table_bytes =
312 (inodes_count_total - ((block_group_count - 1) * inodes_per_group))
313 * inode_table_item_size;
314 }
315
316 uint32_t inode_table_blocks = inode_table_bytes / block_size;
317
318 if (inode_table_bytes % block_size) {
319 inode_table_blocks++;
320 }
321
322 goal = inode_table_first_block + inode_table_blocks;
323
324 ext4_filesystem_put_block_group_ref(bg_ref);
325
326 return goal;
327}
328
329int ext4_balloc_alloc_block(
330 ext4_inode_ref_t *inode_ref, uint32_t *fblock)
331{
332 int rc;
333 uint32_t allocated_block = 0;
334
335 uint32_t bitmap_block_addr;
336 block_t *bitmap_block;
337 uint32_t rel_block_idx = 0;
338
339 // Find GOAL
340 uint32_t goal = ext4_balloc_find_goal(inode_ref);
341 if (goal == 0) {
342 // no goal found => partition is full
343 EXT4FS_DBG("ERRORR (goal == 0)");
344 return ENOSPC;
345 }
346
347 ext4_superblock_t *sb = inode_ref->fs->superblock;
348
349 // Load block group number for goal and relative index
350 uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal);
351 uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, goal);
352
353
354 ext4_block_group_ref_t *bg_ref;
355 rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, block_group, &bg_ref);
356 if (rc != EOK) {
357 EXT4FS_DBG("initial BG ref not loaded");
358 return rc;
359 }
360
361 uint32_t first_in_group =
362 ext4_balloc_get_first_data_block_in_group(sb,
363 bg_ref->block_group, block_group);
364
365 uint32_t first_in_group_index = ext4_balloc_blockaddr2_index_in_group(
366 sb, first_in_group);
367
368 if (index_in_group < first_in_group_index) {
369 index_in_group = first_in_group_index;
370 }
371
372 // Load bitmap
373 bitmap_block_addr = ext4_block_group_get_block_bitmap(bg_ref->block_group,
374 sb);
375
376 rc = block_get(&bitmap_block, inode_ref->fs->device, bitmap_block_addr, 0);
377 if (rc != EOK) {
378 ext4_filesystem_put_block_group_ref(bg_ref);
379 EXT4FS_DBG("initial bitmap not loaded");
380 return rc;
381 }
382
383 // Check if goal is free
384 if (ext4_bitmap_is_free_bit(bitmap_block->data, index_in_group)) {
385 ext4_bitmap_set_bit(bitmap_block->data, index_in_group);
386 bitmap_block->dirty = true;
387 rc = block_put(bitmap_block);
388 if (rc != EOK) {
389 EXT4FS_DBG("goal check: error in saving bitmap \%d", rc);
390 ext4_filesystem_put_block_group_ref(bg_ref);
391 return rc;
392 }
393
394 allocated_block = goal;
395 goto success;
396
397 }
398
399 uint32_t blocks_in_group = ext4_superblock_get_blocks_in_group(sb, block_group);
400
401 uint32_t end_idx = (index_in_group + 63) & ~63;
402 if (end_idx > blocks_in_group) {
403 end_idx = blocks_in_group;
404 }
405
406 // Try to find free block near to goal
407 for (uint32_t tmp_idx = index_in_group + 1; tmp_idx < end_idx; ++tmp_idx) {
408 if (ext4_bitmap_is_free_bit(bitmap_block->data, tmp_idx)) {
409
410 ext4_bitmap_set_bit(bitmap_block->data, tmp_idx);
411 bitmap_block->dirty = true;
412 rc = block_put(bitmap_block);
413 if (rc != EOK) {
414 EXT4FS_DBG("near blocks: error in saving initial bitmap \%d", rc);
415 return rc;
416 }
417
418 allocated_block = ext4_balloc_index_in_group2blockaddr(
419 sb, tmp_idx, block_group);
420
421 goto success;
422 }
423
424 }
425
426 // Find free BYTE in bitmap
427 rc = ext4_bitmap_find_free_byte_and_set_bit(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
428 if (rc == EOK) {
429 bitmap_block->dirty = true;
430 rc = block_put(bitmap_block);
431 if (rc != EOK) {
432 EXT4FS_DBG("free byte: error in saving initial bitmap \%d", rc);
433 return rc;
434 }
435
436 allocated_block = ext4_balloc_index_in_group2blockaddr(
437 sb, rel_block_idx, block_group);
438
439 goto success;
440 }
441
442 // Find free bit in bitmap
443 rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
444 if (rc == EOK) {
445 bitmap_block->dirty = true;
446 rc = block_put(bitmap_block);
447 if (rc != EOK) {
448 EXT4FS_DBG("free bit: error in saving initial bitmap \%d", rc);
449 return rc;
450 }
451
452 allocated_block = ext4_balloc_index_in_group2blockaddr(
453 sb, rel_block_idx, block_group);
454
455 goto success;
456 }
457
458 // No free block found yet
459 block_put(bitmap_block);
460 ext4_filesystem_put_block_group_ref(bg_ref);
461
462 // Try other block groups
463 uint32_t block_group_count = ext4_superblock_get_block_group_count(sb);
464
465 uint32_t bgid = (block_group + 1) % block_group_count;
466 uint32_t count = block_group_count;
467
468 while (count > 0) {
469 rc = ext4_filesystem_get_block_group_ref(inode_ref->fs, bgid, &bg_ref);
470 if (rc != EOK) {
471 EXT4FS_DBG("ERROR: unable to load block group \%u", bgid);
472 return rc;
473 }
474
475 // Load bitmap
476 bitmap_block_addr = ext4_block_group_get_block_bitmap(
477 bg_ref->block_group, sb);
478
479 rc = block_get(&bitmap_block, inode_ref->fs->device, bitmap_block_addr, 0);
480 if (rc != EOK) {
481 ext4_filesystem_put_block_group_ref(bg_ref);
482 EXT4FS_DBG("ERROR: unable to load bitmap block");
483 return rc;
484 }
485
486 first_in_group = ext4_balloc_get_first_data_block_in_group(
487 sb, bg_ref->block_group, bgid);
488 index_in_group = ext4_balloc_blockaddr2_index_in_group(sb,
489 first_in_group);
490 blocks_in_group = ext4_superblock_get_blocks_in_group(sb, bgid);
491
492 first_in_group_index = ext4_balloc_blockaddr2_index_in_group(
493 sb, first_in_group);
494
495 if (index_in_group < first_in_group_index) {
496 index_in_group = first_in_group_index;
497 }
498
499
500 rc = ext4_bitmap_find_free_byte_and_set_bit(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
501 if (rc == EOK) {
502 bitmap_block->dirty = true;
503 rc = block_put(bitmap_block);
504 if (rc != EOK) {
505 EXT4FS_DBG("ERROR: unable to save bitmap block");
506 return rc;
507 }
508
509 allocated_block = ext4_balloc_index_in_group2blockaddr(
510 sb, rel_block_idx, bgid);
511
512 goto success;
513 }
514
515 // Find free bit in bitmap
516 rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data, index_in_group, &rel_block_idx, blocks_in_group);
517 if (rc == EOK) {
518 bitmap_block->dirty = true;
519 rc = block_put(bitmap_block);
520 if (rc != EOK) {
521 EXT4FS_DBG("ERROR: unable to save bitmap block");
522 return rc;
523 }
524
525 allocated_block = ext4_balloc_index_in_group2blockaddr(
526 sb, rel_block_idx, bgid);
527
528 goto success;
529 }
530
531
532 // Next group
533 block_put(bitmap_block);
534 ext4_filesystem_put_block_group_ref(bg_ref);
535 bgid = (bgid + 1) % block_group_count;
536 count--;
537 }
538
539 return ENOSPC;
540
541success:
542 ; // Empty command - because of syntax
543
544 uint32_t block_size = ext4_superblock_get_block_size(sb);
545
546 // Update superblock free blocks count
547 uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
548 sb_free_blocks--;
549 ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
550
551 // Update inode blocks (different block size!) count
552
553 uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
554 ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
555 ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
556 inode_ref->dirty = true;
557
558 // Update block group free blocks count
559 uint32_t bg_free_blocks = ext4_block_group_get_free_blocks_count(
560 bg_ref->block_group, sb);
561 bg_free_blocks--;
562 ext4_block_group_set_free_blocks_count(bg_ref->block_group, sb, bg_free_blocks);
563 bg_ref->dirty = true;
564
565 ext4_filesystem_put_block_group_ref(bg_ref);
566
567 *fblock = allocated_block;
568 return EOK;
569}
570
571int ext4_balloc_try_alloc_block(ext4_inode_ref_t *inode_ref,
572 uint32_t fblock, bool *free)
573{
574 int rc;
575
576 ext4_filesystem_t *fs = inode_ref->fs;
577 ext4_superblock_t *sb = fs->superblock;
578
579 uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, fblock);
580 uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, fblock);
581
582 ext4_block_group_ref_t *bg_ref;
583 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
584 if (rc != EOK) {
585 EXT4FS_DBG("error in loading bg_ref \%d", rc);
586 return rc;
587 }
588
589 uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
590 bg_ref->block_group, sb);
591 block_t *bitmap_block;
592 rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
593 if (rc != EOK) {
594 EXT4FS_DBG("error in loading bitmap \%d", rc);
595 return rc;
596 }
597
598 *free = ext4_bitmap_is_free_bit(bitmap_block->data, index_in_group);
599
600 if (*free) {
601 ext4_bitmap_set_bit(bitmap_block->data, index_in_group);
602 bitmap_block->dirty = true;
603 }
604
605 rc = block_put(bitmap_block);
606 if (rc != EOK) {
607 // Error in saving bitmap
608 ext4_filesystem_put_block_group_ref(bg_ref);
609 EXT4FS_DBG("error in saving bitmap \%d", rc);
610 return rc;
611 }
612
613 if (!(*free)) {
614 goto terminate;
615 }
616
617 uint32_t block_size = ext4_superblock_get_block_size(sb);
618
619 // Update superblock free blocks count
620 uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
621 sb_free_blocks--;
622 ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
623
624 // Update inode blocks count
625 uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
626 ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
627 ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
628 inode_ref->dirty = true;
629
630 // Update block group free blocks count
631 uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
632 bg_ref->block_group, sb);
633 free_blocks--;
634 ext4_block_group_set_free_blocks_count(bg_ref->block_group,
635 sb, free_blocks);
636 bg_ref->dirty = true;
637
638terminate:
639
640 rc = ext4_filesystem_put_block_group_ref(bg_ref);
641 if (rc != EOK) {
642 EXT4FS_DBG("error in saving bg_ref \%d", rc);
643 return rc;
644 }
645
646 return rc;
647}
648
649/**
650 * @}
651 */
Note: See TracBrowser for help on using the repository browser.