mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-17 12:41:32 +00:00
fs:ext4:write:fix: Reinitialize global variables after updating a file
This bug shows up when file stored on the ext4 file system is updated. The ext4fs_delete_file() is responsible for deleting file's (e.g. uImage) data. However some global data (especially ext4fs_indir2_block), which is used during file deletion are left unchanged. The ext4fs_indir2_block pointer stores reference to old ext4 double indirect allocated blocks. When it is unchanged, after file deletion, ext4fs_write_file() uses the same pointer (since it is already initialized - i.e. not NULL) to return number of blocks to write. This trunks larger file when previous one was smaller. Lets consider following scenario: 1. Flash target with ext4 formatted boot.img (which has uImage [*] on itself) 2. Developer wants to upload their custom uImage [**] - When new uImage [**] is smaller than the [*] - everything works correctly - we are able to store the whole smaller file with corrupted ext4fs_indir2_block pointer - When new uImage [**] is larger than the [*] - theCRC is corrupted, since truncation on data stored at eMMC was done. 3. When uImage CRC error appears, then reboot and LTHOR/DFU reflashing causes proper setting of ext4fs_indir2_block() and after that uImage[**] is successfully stored (correct uImage [*] metadata is stored at an eMMC on the first flashing). Due to above the bug was very difficult to reproduce. This patch sets default values for all ext4fs_indir* pointers/variables. Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
This commit is contained in:
parent
35dd055b94
commit
8b454eeeea
3 changed files with 28 additions and 9 deletions
|
@ -1841,16 +1841,20 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
|
|||
return blknr;
|
||||
}
|
||||
|
||||
void ext4fs_close(void)
|
||||
/**
|
||||
* ext4fs_reinit_global() - Reinitialize values of ext4 write implementation's
|
||||
* global pointers
|
||||
*
|
||||
* This function assures that for a file with the same name but different size
|
||||
* the sequential store on the ext4 filesystem will be correct.
|
||||
*
|
||||
* In this function the global data, responsible for internal representation
|
||||
* of the ext4 data are initialized to the reset state. Without this, during
|
||||
* replacement of the smaller file with the bigger truncation of new file was
|
||||
* performed.
|
||||
*/
|
||||
void ext4fs_reinit_global(void)
|
||||
{
|
||||
if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
|
||||
ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
|
||||
ext4fs_file = NULL;
|
||||
}
|
||||
if (ext4fs_root != NULL) {
|
||||
free(ext4fs_root);
|
||||
ext4fs_root = NULL;
|
||||
}
|
||||
if (ext4fs_indir1_block != NULL) {
|
||||
free(ext4fs_indir1_block);
|
||||
ext4fs_indir1_block = NULL;
|
||||
|
@ -1870,6 +1874,19 @@ void ext4fs_close(void)
|
|||
ext4fs_indir3_blkno = -1;
|
||||
}
|
||||
}
|
||||
void ext4fs_close(void)
|
||||
{
|
||||
if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
|
||||
ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
|
||||
ext4fs_file = NULL;
|
||||
}
|
||||
if (ext4fs_root != NULL) {
|
||||
free(ext4fs_root);
|
||||
ext4fs_root = NULL;
|
||||
}
|
||||
|
||||
ext4fs_reinit_global();
|
||||
}
|
||||
|
||||
int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
|
||||
struct ext2fs_node **fnode, int *ftype)
|
||||
|
|
|
@ -562,6 +562,7 @@ static int ext4fs_delete_file(int inodeno)
|
|||
|
||||
ext4fs_update();
|
||||
ext4fs_deinit();
|
||||
ext4fs_reinit_global();
|
||||
|
||||
if (ext4fs_init() != 0) {
|
||||
printf("error in File System init\n");
|
||||
|
|
|
@ -133,6 +133,7 @@ int ext4fs_open(const char *filename);
|
|||
int ext4fs_read(char *buf, unsigned len);
|
||||
int ext4fs_mount(unsigned part_length);
|
||||
void ext4fs_close(void);
|
||||
void ext4fs_reinit_global(void);
|
||||
int ext4fs_ls(const char *dirname);
|
||||
int ext4fs_exists(const char *filename);
|
||||
void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
|
||||
|
|
Loading…
Add table
Reference in a new issue