mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-21 04:14:34 +00:00
ext4: Correct block number handling, empty block vs. error code
read_allocated block may return block number 0, which is just an indicator a chunk of the file is not backed by a block, i.e. it is sparse. During file deletions, just continue with the next logical block, for other operations treat blocknumber <= 0 as an error. For writes, blocknumber 0 should never happen, as U-Boot always allocates blocks for the whole file. Reading already handles this correctly, i.e. the read buffer is 0-fillled. Not treating block 0 as sparse block leads to FS corruption, e.g. ./sandbox/u-boot -c 'host bind 0 ./sandbox/test/fs/3GB.ext4.img ; ext4write host 0 0 /2.5GB.file 1 ' The 2.5GB.file from the fs test is actually a sparse file. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
This commit is contained in:
parent
b779e0290a
commit
de9e831675
2 changed files with 13 additions and 4 deletions
|
@ -534,7 +534,7 @@ static int search_dir(struct ext2_inode *parent_inode, char *dirname)
|
||||||
/* get the block no allocated to a file */
|
/* get the block no allocated to a file */
|
||||||
for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
|
for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
|
||||||
blknr = read_allocated_block(parent_inode, blk_idx);
|
blknr = read_allocated_block(parent_inode, blk_idx);
|
||||||
if (blknr == 0)
|
if (blknr <= 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* read the directory block */
|
/* read the directory block */
|
||||||
|
@ -828,7 +828,7 @@ int ext4fs_filename_unlink(char *filename)
|
||||||
/* read the block no allocated to a file */
|
/* read the block no allocated to a file */
|
||||||
for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
|
for (blk_idx = 0; blk_idx < directory_blocks; blk_idx++) {
|
||||||
blknr = read_allocated_block(g_parent_inode, blk_idx);
|
blknr = read_allocated_block(g_parent_inode, blk_idx);
|
||||||
if (blknr == 0)
|
if (blknr <= 0)
|
||||||
break;
|
break;
|
||||||
inodeno = unlink_filename(filename, blknr);
|
inodeno = unlink_filename(filename, blknr);
|
||||||
if (inodeno != -1)
|
if (inodeno != -1)
|
||||||
|
@ -1590,7 +1590,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
printf("** SI ext2fs read block (indir 1)"
|
printf("** SI ext2fs read block (indir 1)"
|
||||||
"failed. **\n");
|
"failed. **\n");
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
ext4fs_indir1_blkno =
|
ext4fs_indir1_blkno =
|
||||||
le32_to_cpu(inode->b.blocks.
|
le32_to_cpu(inode->b.blocks.
|
||||||
|
|
|
@ -461,6 +461,10 @@ static int ext4fs_delete_file(int inodeno)
|
||||||
/* release data blocks */
|
/* release data blocks */
|
||||||
for (i = 0; i < no_blocks; i++) {
|
for (i = 0; i < no_blocks; i++) {
|
||||||
blknr = read_allocated_block(&inode, i);
|
blknr = read_allocated_block(&inode, i);
|
||||||
|
if (blknr == 0)
|
||||||
|
continue;
|
||||||
|
if (blknr < 0)
|
||||||
|
goto fail;
|
||||||
bg_idx = blknr / blk_per_grp;
|
bg_idx = blknr / blk_per_grp;
|
||||||
if (fs->blksz == 1024) {
|
if (fs->blksz == 1024) {
|
||||||
remainder = blknr % blk_per_grp;
|
remainder = blknr % blk_per_grp;
|
||||||
|
@ -718,6 +722,10 @@ void ext4fs_deinit(void)
|
||||||
fs->curr_blkno = 0;
|
fs->curr_blkno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write data to filesystem blocks. Uses same optimization for
|
||||||
|
* contigous sectors as ext4fs_read_file
|
||||||
|
*/
|
||||||
static int ext4fs_write_file(struct ext2_inode *file_inode,
|
static int ext4fs_write_file(struct ext2_inode *file_inode,
|
||||||
int pos, unsigned int len, char *buf)
|
int pos, unsigned int len, char *buf)
|
||||||
{
|
{
|
||||||
|
@ -744,7 +752,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
|
||||||
int blockend = fs->blksz;
|
int blockend = fs->blksz;
|
||||||
int skipfirst = 0;
|
int skipfirst = 0;
|
||||||
blknr = read_allocated_block(file_inode, i);
|
blknr = read_allocated_block(file_inode, i);
|
||||||
if (blknr < 0)
|
if (blknr <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
blknr = blknr << log2_fs_blocksize;
|
blknr = blknr << log2_fs_blocksize;
|
||||||
|
@ -910,6 +918,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
|
||||||
/* copy the file content into data blocks */
|
/* copy the file content into data blocks */
|
||||||
if (ext4fs_write_file(file_inode, 0, sizebytes, (char *)buffer) == -1) {
|
if (ext4fs_write_file(file_inode, 0, sizebytes, (char *)buffer) == -1) {
|
||||||
printf("Error in copying content\n");
|
printf("Error in copying content\n");
|
||||||
|
/* FIXME: Deallocate data blocks */
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ibmap_idx = parent_inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
|
ibmap_idx = parent_inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
|
||||||
|
|
Loading…
Add table
Reference in a new issue