summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Brüns <stefan.bruens@rwth-aachen.de>2016-09-06 04:36:49 +0200
committerDongjin Kim <tobetter@gmail.com>2020-02-10 22:44:41 +0900
commitce9ad752eb425031127d04dfd8af13b2f31c00b2 (patch)
tree97a57f039ababb9d0f1a9c9316411d5ec4128844
parentc2e8ecd951ebd31e1d0a595e231790a61f274251 (diff)
downloadu-boot-odroid-c1-ce9ad752eb425031127d04dfd8af13b2f31c00b2.tar.gz
ext4: After completely filled group, scan next group from the beginning
The last free block of a block group may be in its middle. After it has been allocated, the next block group should be scanned from its beginning. The following command triggers the bad behaviour (on a blocksize 1024 fs): ./sandbox/u-boot -c 'i=0; host bind 0 ./disk.raw ; while test $i -lt 260 ; do echo $i; setexpr i $i + 1; ext4write host 0:2 0 /X${i} 0x1450; done ; ext4write host 0:2 0 /X240 0x2000 ; ' When 'X240' is extended from 5200 byte to 8192 byte, the new blocks should start from the first free block (8811), but it uses the blocks 8098-8103 and 16296-16297 -- 8103 + 1 + 8192 = 16296. This can be shown with debugfs, commands 'ffb' and 'stat X240'. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
-rw-r--r--fs/ext4/ext4_common.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 094baa20bf..7864753278 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -911,8 +911,8 @@ uint32_t ext4fs_get_new_blk_no(void)
goto fail;
} else {
-restart:
fs->curr_blkno++;
+restart:
/* get the blockbitmap index respective to blockno */
bg_idx = fs->curr_blkno / blk_per_grp;
if (fs->blksz == 1024) {
@@ -930,8 +930,9 @@ restart:
if (bgd[bg_idx].free_blocks == 0) {
debug("block group %u is full. Skipping\n", bg_idx);
- fs->curr_blkno = fs->curr_blkno + blk_per_grp;
- fs->curr_blkno--;
+ fs->curr_blkno = (bg_idx + 1) * blk_per_grp;
+ if (fs->blksz == 1024)
+ fs->curr_blkno += 1;
goto restart;
}
@@ -948,6 +949,7 @@ restart:
bg_idx) != 0) {
debug("going for restart for the block no %ld %u\n",
fs->curr_blkno, bg_idx);
+ fs->curr_blkno++;
goto restart;
}