From patchwork Tue May 6 07:36:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?=C5=81ukasz_Majewski?= X-Patchwork-Id: 346064 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 5ED7B141338 for ; Tue, 6 May 2014 17:36:56 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9168E4B98E; Tue, 6 May 2014 09:36:51 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lrPwWviBQloK; Tue, 6 May 2014 09:36:51 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B6F024B984; Tue, 6 May 2014 09:36:49 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 965AC4B986 for ; Tue, 6 May 2014 09:36:45 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hIJcA00lLSBb for ; Tue, 6 May 2014 09:36:42 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by theia.denx.de (Postfix) with ESMTPS id 369394B984 for ; Tue, 6 May 2014 09:36:42 +0200 (CEST) Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N55006PD6H1DBA0@mailout3.samsung.com> for u-boot@lists.denx.de; Tue, 06 May 2014 16:36:37 +0900 (KST) X-AuditID: cbfee61b-b7f766d00000646c-ad-536891051041 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 01.15.25708.50198635; Tue, 06 May 2014 16:36:37 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N55005P36G7KGA0@mmp2.samsung.com>; Tue, 06 May 2014 16:36:37 +0900 (KST) From: Lukasz Majewski To: u-boot@lists.denx.de, Tom Rini Date: Tue, 06 May 2014 09:36:05 +0200 Message-id: <1399361765-31410-3-git-send-email-l.majewski@samsung.com> X-Mailer: git-send-email 1.7.10.4 In-reply-to: <1399361765-31410-1-git-send-email-l.majewski@samsung.com> References: <1398854380-10778-1-git-send-email-l.majewski@samsung.com> <1399361765-31410-1-git-send-email-l.majewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuplluLIzCtJLcpLzFFi42I5/e+xoC7rxIxgg+1nhS3ePOK2ePNwM6PF jss3WCy+bdnGaDF58Xxmi7d7O9kd2DxmN1xk8Th7Zwejx7ppb5k9+rasYvQ4fmM7UwBrFJdN SmpOZllqkb5dAlfG2qtPWAq+KVZc3djJ2MD4XLqLkZNDQsBEoulQKzuELSZx4d56NhBbSGA6 o8TU+1IQdheTxL0V/CA2m4CexOe7T5lAbBEBQ4lJq+cydjFycTALLGGU+H5nAgtIQlggQWLq 4s1ANgcHi4CqxJKNxiBhXgE3iUtznjBD7FKU6H42gQ2khFPAXeLQwhSQMUICzYwS37ruM05g 5F3AyLCKUTS1ILmgOCk910ivODG3uDQvXS85P3cTIziQnknvYFzVYHGIUYCDUYmH98TK9GAh 1sSy4srcQ4wSHMxKIrz1+RnBQrwpiZVVqUX58UWlOanFhxilOViUxHkPtloHCgmkJ5akZqem FqQWwWSZODilGhiF6zWur7ZgkfN+dHRyuGX0gQRjtbatn2I3K7+ZstAgxiXG3vrs/ORX/RtZ 3fTcVrw9WbPBaMbGS6lWlz95rGM79ebuCmu/1vcT3NhmcloGnqt6fXn17lMVX6QbftzNkg99 wKf77Ffoip8dJ/Y7a87ZvvfcRD3BJ/8mWXRcimgwtjAUP6QzNfO7EktxRqKhFnNRcSIAeDNs fSACAAA= Cc: Przemyslaw Marczak Subject: [U-Boot] [PATCH v2 2/2] fs:ext4:write:fix: Reinitialize global variables after updating a file X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 --- Changes for v2: - Add comment describing the purpose of ext4fs_reinit_global() function --- fs/ext4/ext4_common.c | 35 ++++++++++++++++++++++++++--------- fs/ext4/ext4_write.c | 1 + include/ext4fs.h | 1 + 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index 62e2e80..1c11721 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -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) diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c index 3db22f8..c42add9 100644 --- a/fs/ext4/ext4_write.c +++ b/fs/ext4/ext4_write.c @@ -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"); diff --git a/include/ext4fs.h b/include/ext4fs.h index aacb147..fbbb002 100644 --- a/include/ext4fs.h +++ b/include/ext4fs.h @@ -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);