From patchwork Tue Dec 20 17:41:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyle Moffett X-Patchwork-Id: 132476 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 DD6FAB706E for ; Wed, 21 Dec 2011 04:42:30 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A5AD928127; Tue, 20 Dec 2011 18:42:21 +0100 (CET) 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 SMgF4GZUm9Te; Tue, 20 Dec 2011 18:42:21 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DACEA2812B; Tue, 20 Dec 2011 18:42:08 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 777F9280E8 for ; Tue, 20 Dec 2011 18:42:05 +0100 (CET) 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 fVp42jEBBBUS for ; Tue, 20 Dec 2011 18:42:03 +0100 (CET) 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 border.exmeritus.com (border.exmeritus.com [70.167.241.26]) by theia.denx.de (Postfix) with ESMTP id 510F82810A for ; Tue, 20 Dec 2011 18:42:03 +0100 (CET) Received: from ysera.exmeritus.com (firewall2.exmeritus.com [10.13.38.2]) by border.exmeritus.com (Postfix) with ESMTP id 94FCAAC081; Tue, 20 Dec 2011 12:42:02 -0500 (EST) From: Kyle Moffett To: u-boot@lists.denx.de Date: Tue, 20 Dec 2011 12:41:13 -0500 Message-Id: <1324402874-15400-3-git-send-email-Kyle.D.Moffett@boeing.com> X-Mailer: git-send-email 1.7.7.3 In-Reply-To: <1324402874-15400-1-git-send-email-Kyle.D.Moffett@boeing.com> References: <1324402874-15400-1-git-send-email-Kyle.D.Moffett@boeing.com> Subject: [U-Boot] [PATCH 2/3] fs/fat: Improve error handling 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 The FAT filesystem fails silently in inexplicable ways when given a filesystem with a block-size that does not match the device sector size. In theory this is not an unsupportable combination but requires a major rewrite of a lot of the filesystem. Until that occurs, the filesystem should detect that scenario and display a helpful error message. This scenario in particular occurred on a 512-byte blocksize FAT fs stored in an El-Torito boot volume on a CD-ROM (2048-byte sector size). Additionally, in many circumstances the ->block_read method will not return a negative number to indicate an error but instead return 0 to indicate the number of blocks successfully read (IE: None). The FAT filesystem should defensively check to ensure that it got all of the sectors that it asked for when reading. Signed-off-by: Kyle Moffett --- fs/fat/fat.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 13bab8f..2136cd7 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -282,6 +282,8 @@ get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, { __u32 idx = 0; __u32 startsect; + __u32 nr_sect; + int ret; if (clustnum > 0) { startsect = mydata->data_begin + @@ -292,16 +294,19 @@ get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, debug("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); - if (disk_read(startsect, size / mydata->sect_size, buffer) < 0) { - debug("Error reading data\n"); + nr_sect = size / mydata->sect_size; + ret = disk_read(startsect, nr_sect, buffer); + if (ret != nr_sect) { + debug("Error reading data (got %d)\n", ret); return -1; } if (size % mydata->sect_size) { __u8 tmpbuf[mydata->sect_size]; idx = size / mydata->sect_size; - if (disk_read(startsect + idx, 1, tmpbuf) < 0) { - debug("Error reading data\n"); + ret = disk_read(startsect + idx, 1, tmpbuf); + if (ret != 1) { + debug("Error reading data (got %d)\n", ret); return -1; } buffer += idx * mydata->sect_size; @@ -810,6 +815,11 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize, mydata->sect_size = (bs.sector_size[1] << 8) + bs.sector_size[0]; mydata->clust_size = bs.cluster_size; + if (mydata->sect_size != cur_part_info.blksz) { + printf("Error: FAT sector size mismatch (fs=%hu, dev=%lu)\n", + mydata->sect_size, cur_part_info.blksz); + return -1; + } if (mydata->fatsize == 32) { mydata->data_begin = mydata->rootdir_sect -