From patchwork Sat Sep 9 17:15:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811968 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="YjDjuXA1"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLTy3swlz9t16 for ; Sun, 10 Sep 2017 03:17:26 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 1D39CC21E54; Sat, 9 Sep 2017 17:16:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id A7B4DC21F14; Sat, 9 Sep 2017 17:16:29 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 22AA7C21DBF; Sat, 9 Sep 2017 17:16:26 +0000 (UTC) Received: from mail-qt0-f193.google.com (mail-qt0-f193.google.com [209.85.216.193]) by lists.denx.de (Postfix) with ESMTPS id E558AC21D65 for ; Sat, 9 Sep 2017 17:16:22 +0000 (UTC) Received: by mail-qt0-f193.google.com with SMTP id k2so3284744qte.5 for ; Sat, 09 Sep 2017 10:16:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Rwe9iiSkwfR2II8s0SPmCSJtn3Oys4FC2KKNrCSa/Uk=; b=YjDjuXA1CRdDG6CYPmL5tIGUSOU+BDThIdrMO/ixH7Q3aJoF8bL+59LiEKSSHJTw+h KZKkrd9pCXAwgtNeuM2hCj9ApV3u6aThiUcmbUYkzNflMzApy+c1O0GZ91Mxpe+B9JlT L3DcEhYModVqjaGAr/oDoklvLidWdx95sgHUfZ3kwXCWYx4Hu/6ifmn0g4hKN9mKcsAB p1OYfOXqonRWZGxmpGZRLzYjlF0wIC2cTq51AP0nr2DU3QF3/PDxLuKatB75WxCKCI15 gusOcmo5WwSpJJXqYeT7NqfPXvV6NL/mMkDptxqhpxot/C/W4e49tVVZVf65TbR2zB1m 3wgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Rwe9iiSkwfR2II8s0SPmCSJtn3Oys4FC2KKNrCSa/Uk=; b=XtZQjTT/28ohqAPRzli9cB1ccNXp+FEDDmRxq64AVq6ZvbQO7DZezZLefPwslrLt/g wgMK4buYX7rjkQVmwju+vrtehSEg/Y08vPhyqgop9/PaM2z3U/Oo0EmIM6dYfyYlKBeL 9turubiQPsruEzoLvW2LDaFCUdZQLXoCYEP2FDdYx1MyL3Qb0oB7m+RPHrgQW8DTi4Wx 3JPxRcdT4Z+QXgrv/qPygHIIc6JWrTN3qqWMi7KRH+GctGauwTozh4LlCnk0yaWT4wkr WxaJvdfzu0Y/EdgcHLjK2bY91Dwcorg5yu6YwWzoUGh96DeBoqIBZzudMu4/lRn0mATr 8czg== X-Gm-Message-State: AHPjjUiGGMIUPT/sQ2CDyynibNiiU23U7Fu0zDGW/uZZcmgkiqEHXx9L 1JMCH8T9Nzb0vg+0tqw= X-Google-Smtp-Source: AOwi7QCf7eutxCXgxzJ8iaf7eiRJ2u3N1zYAdxgiwaZhP5JHBTcsOxsPfrIq3+htlLa5fInnk49Mpg== X-Received: by 10.200.34.167 with SMTP id f36mr9297204qta.236.1504977381643; Sat, 09 Sep 2017 10:16:21 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id i41sm3280727qta.23.2017.09.09.10.16.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:20 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:52 -0400 Message-Id: <20170909171606.20029-2-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Heinrich Schuchardt , Genevieve Chan , Tien Fong Chee Subject: [U-Boot] [PATCH v3 1/9] fs/fat: split out helper to init fsdata X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Want to re-use this in fat dirent iterator in next patch. Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski Reviewed-by: Simon Glass --- fs/fat/fat.c | 73 +++++++++++++++++++++++++++++++++++------------------------ include/fat.h | 1 + 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 465a6875ed..e1c0a15dc7 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -808,35 +808,17 @@ exit: return ret; } -__u8 do_fat_read_at_block[MAX_CLUSTSIZE] - __aligned(ARCH_DMA_MINALIGN); - -int do_fat_read_at(const char *filename, loff_t pos, void *buffer, - loff_t maxsize, int dols, int dogetsize, loff_t *size) +static int get_fs_info(fsdata *mydata) { - char fnamecopy[2048]; boot_sector bs; volume_info volinfo; - fsdata datablock; - fsdata *mydata = &datablock; - dir_entry *dentptr = NULL; - __u16 prevcksum = 0xffff; - char *subname = ""; - __u32 cursect; - int idx, isdir = 0; - int files = 0, dirs = 0; - int ret = -1; - int firsttime; __u32 root_cluster = 0; - __u32 read_blk; - int rootdir_size = 0; - int buffer_blk_cnt; - int do_read; - __u8 *dir_ptr; + int ret; - if (read_bootsectandvi(&bs, &volinfo, &mydata->fatsize)) { + ret = read_bootsectandvi(&bs, &volinfo, &mydata->fatsize); + if (ret) { debug("Error: reading boot sector\n"); - return -1; + return ret; } if (mydata->fatsize == 32) { @@ -848,8 +830,7 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer, mydata->fat_sect = bs.reserved; - cursect = mydata->rootdir_sect - = mydata->fat_sect + mydata->fatlength * bs.fats; + mydata->rootdir_sect = mydata->fat_sect + mydata->fatlength * bs.fats; mydata->sect_size = (bs.sector_size[1] << 8) + bs.sector_size[0]; mydata->clust_size = bs.cluster_size; @@ -863,12 +844,12 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer, mydata->data_begin = mydata->rootdir_sect - (mydata->clust_size * 2); } else { - rootdir_size = ((bs.dir_entries[1] * (int)256 + - bs.dir_entries[0]) * - sizeof(dir_entry)) / - mydata->sect_size; + mydata->rootdir_size = ((bs.dir_entries[1] * (int)256 + + bs.dir_entries[0]) * + sizeof(dir_entry)) / + mydata->sect_size; mydata->data_begin = mydata->rootdir_sect + - rootdir_size - + mydata->rootdir_size - (mydata->clust_size * 2); } @@ -893,6 +874,38 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer, debug("Sector size: %d, cluster size: %d\n", mydata->sect_size, mydata->clust_size); + return 0; +} + +__u8 do_fat_read_at_block[MAX_CLUSTSIZE] + __aligned(ARCH_DMA_MINALIGN); + +int do_fat_read_at(const char *filename, loff_t pos, void *buffer, + loff_t maxsize, int dols, int dogetsize, loff_t *size) +{ + char fnamecopy[2048]; + fsdata datablock; + fsdata *mydata = &datablock; + dir_entry *dentptr = NULL; + __u16 prevcksum = 0xffff; + char *subname = ""; + __u32 cursect; + int idx, isdir = 0; + int files = 0, dirs = 0; + int ret = -1; + int firsttime; + __u32 root_cluster = 0; + __u32 read_blk; + int rootdir_size = 0; + int buffer_blk_cnt; + int do_read; + __u8 *dir_ptr; + + if (get_fs_info(mydata)) + return -1; + + cursect = mydata->rootdir_sect; + /* "cwd" is always the root... */ while (ISDIRDELIM(*filename)) filename++; diff --git a/include/fat.h b/include/fat.h index 71879f01ca..b671ee8f81 100644 --- a/include/fat.h +++ b/include/fat.h @@ -174,6 +174,7 @@ typedef struct { __u16 clust_size; /* Size of clusters in sectors */ int data_begin; /* The sector of the first cluster, can be negative */ int fatbufnum; /* Used by get_fatent, init to -1 */ + int rootdir_size; /* Size of root dir for non-FAT32 */ } fsdata; typedef int (file_detectfs_func)(void); From patchwork Sat Sep 9 17:15:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811973 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="k7e1O3sX"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLYJ6VNFz9t16 for ; Sun, 10 Sep 2017 03:20:20 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 9456EC21F03; Sat, 9 Sep 2017 17:18:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 3BFF8C21EB1; Sat, 9 Sep 2017 17:17:42 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 49CD2C21E92; Sat, 9 Sep 2017 17:16:30 +0000 (UTC) Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by lists.denx.de (Postfix) with ESMTPS id A73A8C21EDC for ; Sat, 9 Sep 2017 17:16:28 +0000 (UTC) Received: by mail-qk0-f195.google.com with SMTP id g128so3247223qke.0 for ; Sat, 09 Sep 2017 10:16:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=olLHt/LWSXBdsV2nZv8WrqeymB/JReM33i5ffkISCXc=; b=k7e1O3sXbFtCZ8DKJRQqJjIxZeKPBgLUxo3TyfRX6FXW4W0s4HGNB7nA8cmYROgof0 iQ1CM4WLpCkPGAgl5dpcLzn38XcX/r+a1MdorED0tgmmWtYI7wfU9dPDfF6w6If/B4Id eV6owJSwEaB4jDhIqAdDAiF9sL9nx38HHJPfe4uVCFa+GMMZ5UQPl92v1fg+kf0+J23A kJP3/Vmdi92iY73jK0iiXVEoAsJYVH2y9SRCzXVHKKMpSEbbD9//R/bJTe951TeW9qCb +uRPGHRLx0BQVslnxnwodV3ziuew3xt+0nN7ejovHzDPPVHbiqONjIzL1KdiuFZpSVUL 8ujA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=olLHt/LWSXBdsV2nZv8WrqeymB/JReM33i5ffkISCXc=; b=WY5gahQ5kkGXmGObTAHC2GuhIQAYvgiJAZuHlQemLYGSDzkPO5r3xSir33gkk5MYsv 3mJg2C7fbNR5xRr0UuY3pe7Ab7beOEr7nBGq1sr3Qcbu99of1kuy51U8HLhTdGUePOSs KI9bOzBZpi7+txp7BFH1uwZ2qg9aTbZCAjdq0ONalOTWZSb0KBS9N6iYx97tFZiAwCgj kqiMm8X1c4Qk2Ov2uvRekxYZdDj0lAc9o/bF/A3/0exv4QfT00OK5/JGQFe8DHyw1ty4 FjYp8SM5XrN5+qa+gF+BwB2T2XxQ5U7SM5nbMQ+bwH7Oc9Kz++568Z7KZwzM3qk61V++ 10rA== X-Gm-Message-State: AHPjjUi00BrBfpQCgzGK2kngascPTgGzehWtKn30+SaYW6YFzBrteNH5 zjFvn+BiOHAu14PheCA= X-Google-Smtp-Source: AOwi7QAhqp/3/meoqE0Y/FCeL9ngSxRZBRn5v4HCJkvPoG93E7Apl4ZHtPMtz35RQYk6Hz2mEPg6yA== X-Received: by 10.55.20.210 with SMTP id 79mr8578216qku.194.1504977386941; Sat, 09 Sep 2017 10:16:26 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id t26sm3276058qkt.89.2017.09.09.10.16.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:25 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:53 -0400 Message-Id: <20170909171606.20029-3-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Heinrich Schuchardt , Genevieve Chan , Tien Fong Chee Subject: [U-Boot] [PATCH v3 2/9] fs/fat: introduce new director iterators X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Untangle directory traversal into a simple iterator, to replace the existing multi-purpose do_fat_read_at() + get_dentfromdir(). Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski --- fs/fat/fat.c | 356 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- include/fat.h | 7 ++ 2 files changed, 360 insertions(+), 3 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index e1c0a15dc7..ee2bbe38f1 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -812,7 +812,6 @@ static int get_fs_info(fsdata *mydata) { boot_sector bs; volume_info volinfo; - __u32 root_cluster = 0; int ret; ret = read_bootsectandvi(&bs, &volinfo, &mydata->fatsize); @@ -822,7 +821,6 @@ static int get_fs_info(fsdata *mydata) } if (mydata->fatsize == 32) { - root_cluster = bs.root_cluster; mydata->fatlength = bs.fat32_length; } else { mydata->fatlength = bs.fat_length; @@ -843,6 +841,7 @@ static int get_fs_info(fsdata *mydata) if (mydata->fatsize == 32) { mydata->data_begin = mydata->rootdir_sect - (mydata->clust_size * 2); + mydata->root_cluster = bs.root_cluster; } else { mydata->rootdir_size = ((bs.dir_entries[1] * (int)256 + bs.dir_entries[0]) * @@ -851,6 +850,9 @@ static int get_fs_info(fsdata *mydata) mydata->data_begin = mydata->rootdir_sect + mydata->rootdir_size - (mydata->clust_size * 2); + mydata->root_cluster = (mydata->rootdir_sect - + mydata->data_begin) / + mydata->clust_size; } mydata->fatbufnum = -1; @@ -868,7 +870,7 @@ static int get_fs_info(fsdata *mydata) mydata->fatsize, mydata->fat_sect, mydata->fatlength); debug("Rootdir begins at cluster: %d, sector: %d, offset: %x\n" "Data begins at: %d\n", - root_cluster, + mydata->root_cluster, mydata->rootdir_sect, mydata->rootdir_sect * mydata->sect_size, mydata->data_begin); debug("Sector size: %d, cluster size: %d\n", mydata->sect_size, @@ -1245,6 +1247,354 @@ exit: return ret; } + +/* + * Directory iterator, to simplify filesystem traversal + * + * Implements an iterator pattern to traverse directory tables, + * transparently handling directory tables split across multiple + * clusters, and the difference between FAT12/FAT16 root directory + * (contiguous) and subdirectories + FAT32 root (chained). + * + * Rough usage: + * + * for (fat_itr_root(&itr, fsdata); fat_itr_next(&itr); ) { + * // to traverse down to a subdirectory pointed to by + * // current iterator position: + * fat_itr_child(&itr, &itr); + * } + * + * For more complete example, see fat_itr_resolve() + */ + +typedef struct { + fsdata *fsdata; /* filesystem parameters */ + unsigned clust; /* current cluster */ + int last_cluster; /* set once we've read last cluster */ + int is_root; /* is iterator at root directory */ + int remaining; /* remaining dent's in current cluster */ + + /* current iterator position values: */ + dir_entry *dent; /* current directory entry */ + char l_name[VFAT_MAXLEN_BYTES]; /* long (vfat) name */ + char s_name[14]; /* short 8.3 name */ + char *name; /* l_name if there is one, else s_name */ + + /* storage for current cluster in memory: */ + u8 block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); +} fat_itr; + +static int fat_itr_isdir(fat_itr *itr); + +/** + * fat_itr_root() - initialize an iterator to start at the root + * directory + * + * @itr: iterator to initialize + * @fsdata: filesystem data for the partition + * @return 0 on success, else -errno + */ +static int fat_itr_root(fat_itr *itr, fsdata *fsdata) +{ + if (get_fs_info(fsdata)) + return -ENXIO; + + itr->fsdata = fsdata; + itr->clust = fsdata->root_cluster; + itr->dent = NULL; + itr->remaining = 0; + itr->last_cluster = 0; + itr->is_root = 1; + + return 0; +} + +/** + * fat_itr_child() - initialize an iterator to descend into a sub- + * directory + * + * Initializes 'itr' to iterate the contents of the directory at + * the current cursor position of 'parent'. It is an error to + * call this if the current cursor of 'parent' is pointing at a + * regular file. + * + * Note that 'itr' and 'parent' can be the same pointer if you do + * not need to preserve 'parent' after this call, which is useful + * for traversing directory structure to resolve a file/directory. + * + * @itr: iterator to initialize + * @parent: the iterator pointing at a directory entry in the + * parent directory of the directory to iterate + */ +static void fat_itr_child(fat_itr *itr, fat_itr *parent) +{ + fsdata *mydata = parent->fsdata; /* for silly macros */ + unsigned clustnum = START(parent->dent); + + assert(fat_itr_isdir(parent)); + + itr->fsdata = parent->fsdata; + if (clustnum > 0) { + itr->clust = clustnum; + } else { + itr->clust = parent->fsdata->root_cluster; + } + itr->dent = NULL; + itr->remaining = 0; + itr->last_cluster = 0; + itr->is_root = 0; +} + +static void *next_cluster(fat_itr *itr) +{ + fsdata *mydata = itr->fsdata; /* for silly macros */ + int ret; + u32 sect; + + /* have we reached the end? */ + if (itr->last_cluster) + return NULL; + + sect = clust_to_sect(itr->fsdata, itr->clust); + + debug("FAT read(sect=%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n", + sect, itr->fsdata->clust_size, DIRENTSPERBLOCK); + + /* + * NOTE: do_fat_read_at() had complicated logic to deal w/ + * vfat names that span multiple clusters in the fat16 case, + * which get_dentfromdir() probably also needed (and was + * missing). And not entirely sure what fat32 didn't have + * the same issue.. We solve that by only caring about one + * dent at a time and iteratively constructing the vfat long + * name. + */ + ret = disk_read(sect, itr->fsdata->clust_size, + itr->block); + if (ret < 0) { + debug("Error: reading block\n"); + return NULL; + } + + if (itr->is_root && itr->fsdata->fatsize != 32) { + itr->clust++; + sect = clust_to_sect(itr->fsdata, itr->clust); + if (sect - itr->fsdata->rootdir_sect >= + itr->fsdata->rootdir_size) { + debug("cursect: 0x%x\n", itr->clust); + itr->last_cluster = 1; + } + } else { + itr->clust = get_fatent(itr->fsdata, itr->clust); + if (CHECK_CLUST(itr->clust, itr->fsdata->fatsize)) { + debug("cursect: 0x%x\n", itr->clust); + itr->last_cluster = 1; + } + } + + return itr->block; +} + +static dir_entry *next_dent(fat_itr *itr) +{ + if (itr->remaining == 0) { + struct dir_entry *dent = next_cluster(itr); + unsigned nbytes = itr->fsdata->sect_size * + itr->fsdata->clust_size; + + /* have we reached the last cluster? */ + if (!dent) + return NULL; + + itr->remaining = nbytes / sizeof(dir_entry) - 1; + itr->dent = dent; + } else { + itr->remaining--; + itr->dent++; + } + + /* have we reached the last valid entry? */ + if (itr->dent->name[0] == 0) + return NULL; + + return itr->dent; +} + +static dir_entry *extract_vfat_name(fat_itr *itr) +{ + struct dir_entry *dent = itr->dent; + int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK; + u8 chksum, alias_checksum = ((dir_slot *)dent)->alias_checksum; + int n = 0; + + while (seqn--) { + char buf[13]; + int idx = 0; + + slot2str((dir_slot *)dent, buf, &idx); + + /* shift accumulated long-name up and copy new part in: */ + memmove(itr->l_name + idx, itr->l_name, n); + memcpy(itr->l_name, buf, idx); + n += idx; + + dent = next_dent(itr); + if (!dent) + return NULL; + } + + itr->l_name[n] = '\0'; + + chksum = mkcksum(dent->name, dent->ext); + + /* checksum mismatch could mean deleted file, etc.. skip it: */ + if (chksum != alias_checksum) { + debug("** chksum=%x, alias_checksum=%x, l_name=%s, s_name=%8s.%3s\n", + chksum, alias_checksum, itr->l_name, dent->name, dent->ext); + return NULL; + } + + return dent; +} + +/** + * fat_itr_next() - step to the next entry in a directory + * + * Must be called once on a new iterator before the cursor is valid. + * + * @itr: the iterator to iterate + * @return boolean, 1 if success or 0 if no more entries in the + * current directory + */ +static int fat_itr_next(fat_itr *itr) +{ + dir_entry *dent; + + itr->name = NULL; + + while (1) { + dent = next_dent(itr); + if (!dent) + return 0; + + if (dent->name[0] == DELETED_FLAG || + dent->name[0] == aRING) + continue; + + if (dent->attr & ATTR_VOLUME) { + if (vfat_enabled && + (dent->attr & ATTR_VFAT) == ATTR_VFAT && + (dent->name[0] & LAST_LONG_ENTRY_MASK)) { + dent = extract_vfat_name(itr); + if (!dent) + continue; + itr->name = itr->l_name; + break; + } else { + /* Volume label or VFAT entry, skip */ + continue; + } + } + + break; + } + + get_name(dent, itr->s_name); + if (!itr->name) + itr->name = itr->s_name; + + return 1; +} + +/** + * fat_itr_isdir() - is current cursor position pointing to a directory + * + * @itr: the iterator + * @return true if cursor is at a directory + */ +static int fat_itr_isdir(fat_itr *itr) +{ + return !!(itr->dent->attr & ATTR_DIR); +} + +/* + * Helpers: + */ + +#define TYPE_FILE 0x1 +#define TYPE_DIR 0x2 +#define TYPE_ANY (TYPE_FILE | TYPE_DIR) + +/** + * fat_itr_resolve() - traverse directory structure to resolve the + * requested path. + * + * Traverse directory structure to the requested path. If the specified + * path is to a directory, this will descend into the directory and + * leave it iterator at the start of the directory. If the path is to a + * file, it will leave the iterator in the parent directory with current + * cursor at file's entry in the directory. + * + * @itr: iterator initialized to root + * @path: the requested path + * @type: bitmask of allowable file types + * @return 0 on success or -errno + */ +static int fat_itr_resolve(fat_itr *itr, const char *path, unsigned type) +{ + const char *next; + + /* chomp any extra leading slashes: */ + while (path[0] && ISDIRDELIM(path[0])) + path++; + + /* are we at the end? */ + if (strlen(path) == 0) { + if (!(type & TYPE_DIR)) + return -ENOENT; + return 0; + } + + /* find length of next path entry: */ + next = path; + while (next[0] && !ISDIRDELIM(next[0])) + next++; + + while (fat_itr_next(itr)) { + int match = 0; + unsigned n = max(strlen(itr->name), (size_t)(next - path)); + + /* check both long and short name: */ + if (!strncasecmp(path, itr->name, n)) + match = 1; + else if (itr->name != itr->s_name && + !strncasecmp(path, itr->s_name, n)) + match = 1; + + if (!match) + continue; + + if (fat_itr_isdir(itr)) { + /* recurse into directory: */ + fat_itr_child(itr, itr); + return fat_itr_resolve(itr, next, type); + } else if (next[0]) { + /* + * If next is not empty then we have a case + * like: /path/to/realfile/nonsense + */ + debug("bad trailing path: %s\n", next); + return -ENOENT; + } else if (!(type & TYPE_FILE)) { + return -ENOTDIR; + } else { + return 0; + } + } + + return -ENOENT; +} + int do_fat_read(const char *filename, void *buffer, loff_t maxsize, int dols, loff_t *actread) { diff --git a/include/fat.h b/include/fat.h index b671ee8f81..21bb6666cf 100644 --- a/include/fat.h +++ b/include/fat.h @@ -175,8 +175,15 @@ typedef struct { int data_begin; /* The sector of the first cluster, can be negative */ int fatbufnum; /* Used by get_fatent, init to -1 */ int rootdir_size; /* Size of root dir for non-FAT32 */ + __u32 root_cluster; /* First cluster of root dir for FAT32 */ } fsdata; +/* TODO clean up places that are open-coding this: */ +static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) +{ + return fsdata->data_begin + clust * fsdata->clust_size; +} + typedef int (file_detectfs_func)(void); typedef int (file_ls_func)(const char *dir); typedef int (file_read_func)(const char *filename, void *buffer, From patchwork Sat Sep 9 17:15:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811971 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="QfH4k2SC"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLXf5gjqz9t16 for ; Sun, 10 Sep 2017 03:19:46 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7C105C21EA8; Sat, 9 Sep 2017 17:17:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 40EC2C21E8C; Sat, 9 Sep 2017 17:17:15 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id F39AFC21DC3; Sat, 9 Sep 2017 17:16:37 +0000 (UTC) Received: from mail-qt0-f194.google.com (mail-qt0-f194.google.com [209.85.216.194]) by lists.denx.de (Postfix) with ESMTPS id A9331C21D99 for ; Sat, 9 Sep 2017 17:16:33 +0000 (UTC) Received: by mail-qt0-f194.google.com with SMTP id k2so3284943qte.5 for ; Sat, 09 Sep 2017 10:16:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rBXu5viO0nx6ilNLUFtFtvPu5flOKRAP0NAR3BsKh8w=; b=QfH4k2SCOgpJaBNYESTMRaPgAs1S+egvaBlTU1osHGLymWbZU7R3nsRUDrtW6cFDqe KXjWfPe7u17RiNwpScO3hmxoZhqiF/1C5lnHxu7BxERZYaOyve/+UI8UkMNBSdBP16mx w5IkzbFhDofXFUzInvEIVEufFZSs+vK5rAhiPqL4r5MwYRrKw9XB8Fbh/nD5J9GGsE7d c4gHWiNJ+vVsI5Ee53rP5Wuz3Ev8tvr5eBzex5rvKdciMyY6eWV27/tvmGZ/MM/a3dqv 1d1sCI9NzI+xQI6SrLZVglmcz0ryOLG8jqW+ES/AcN6AZ9VYE95oobpgEJcDDhYUJACc MUFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rBXu5viO0nx6ilNLUFtFtvPu5flOKRAP0NAR3BsKh8w=; b=E75iMm8cFXlEJhZ1ysyWooNbeujkgq19xCS7sAUzgzJuki6f/9xbFEF/pLXCRi+ibT J7AUEJqJQabeibab3xUUnyYfW+oilCNDORqi9F5vVYjrFF27DikJXIst15d6oOZvrKAt Egk/K8K/l0YVvtWpEdXLCMYM1posyr7WKQVPRcb31KicCLLg3tc8aERyFqA6syLgZvnd d7GycqRHyRJ9Sdt+t221kUBTUbBPqPu3gQjIGII9vGXCUonP3GHlWmhZ6W1Gl6gWEnCp OVgalqN321srLUqBL0wHGy3IewkRDYw4LE9fuiPOD8zfmz3ek5mH+sMLR9NSIzPQdsqW xaUg== X-Gm-Message-State: AHPjjUi5SQwMhY++DH/7ZN8Ee3/opjaGWCSMWP0l1yIj4nvF2bShvd04 w2491u0gN4pkv+XS4/A= X-Google-Smtp-Source: AOwi7QBG5Cltcw9a33hbtgJT5zBJfH8/uBXBMasxzngKG4fV+RPl+bgCGLIMOFEFGJJY0w27FwVA3Q== X-Received: by 10.237.42.35 with SMTP id c32mr9684886qtd.171.1504977392153; Sat, 09 Sep 2017 10:16:32 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id n85sm3153515qke.53.2017.09.09.10.16.30 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:30 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:54 -0400 Message-Id: <20170909171606.20029-4-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Heinrich Schuchardt , Tien Fong Chee Subject: [U-Boot] [PATCH v3 3/9] fat/fs: convert to directory iterators X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" And drop a whole lot of ugly code! Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski Reviewed-by: Simon Glass --- fs/fat/fat.c | 722 +++++++--------------------------------------------------- include/fat.h | 6 - 2 files changed, 76 insertions(+), 652 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index ee2bbe38f1..bbba7947ee 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -119,22 +119,6 @@ int fat_register_device(struct blk_desc *dev_desc, int part_no) } /* - * Get the first occurence of a directory delimiter ('/' or '\') in a string. - * Return index into string if found, -1 otherwise. - */ -static int dirdelim(char *str) -{ - char *start = str; - - while (*str != '\0') { - if (ISDIRDELIM(*str)) - return str - start; - str++; - } - return -1; -} - -/* * Extract zero terminated short name from a directory entry. */ static void get_name(dir_entry *dirent, char *s_name) @@ -468,95 +452,6 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx) return 0; } -/* - * Extract the full long filename starting at 'retdent' (which is really - * a slot) into 'l_name'. If successful also copy the real directory entry - * into 'retdent' - * Return 0 on success, -1 otherwise. - */ -static int -get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, - dir_entry *retdent, char *l_name) -{ - dir_entry *realdent; - dir_slot *slotptr = (dir_slot *)retdent; - __u8 *buflimit = cluster + mydata->sect_size * ((curclust == 0) ? - PREFETCH_BLOCKS : - mydata->clust_size); - __u8 counter = (slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff; - int idx = 0; - - if (counter > VFAT_MAXSEQ) { - debug("Error: VFAT name is too long\n"); - return -1; - } - - while ((__u8 *)slotptr < buflimit) { - if (counter == 0) - break; - if (((slotptr->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) - return -1; - slotptr++; - counter--; - } - - if ((__u8 *)slotptr >= buflimit) { - dir_slot *slotptr2; - - if (curclust == 0) - return -1; - curclust = get_fatent(mydata, curclust); - if (CHECK_CLUST(curclust, mydata->fatsize)) { - debug("curclust: 0x%x\n", curclust); - printf("Invalid FAT entry\n"); - return -1; - } - - if (get_cluster(mydata, curclust, get_contents_vfatname_block, - mydata->clust_size * mydata->sect_size) != 0) { - debug("Error: reading directory block\n"); - return -1; - } - - slotptr2 = (dir_slot *)get_contents_vfatname_block; - while (counter > 0) { - if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) - & 0xff) != counter) - return -1; - slotptr2++; - counter--; - } - - /* Save the real directory entry */ - realdent = (dir_entry *)slotptr2; - while ((__u8 *)slotptr2 > get_contents_vfatname_block) { - slotptr2--; - slot2str(slotptr2, l_name, &idx); - } - } else { - /* Save the real directory entry */ - realdent = (dir_entry *)slotptr; - } - - do { - slotptr--; - if (slot2str(slotptr, l_name, &idx)) - break; - } while (!(slotptr->id & LAST_LONG_ENTRY_MASK)); - - l_name[idx] = '\0'; - if (*l_name == DELETED_FLAG) - *l_name = '\0'; - else if (*l_name == aRING) - *l_name = DELETED_FLAG; - downcase(l_name); - - /* Return the real directory entry */ - memcpy(retdent, realdent, sizeof(dir_entry)); - - return 0; -} - /* Calculate short name checksum */ static __u8 mkcksum(const char name[8], const char ext[3]) { @@ -573,169 +468,13 @@ static __u8 mkcksum(const char name[8], const char ext[3]) } /* - * Get the directory entry associated with 'filename' from the directory - * starting at 'startsect' + * TODO these should go away once fat_write is reworked to use the + * directory iterator */ __u8 get_dentfromdir_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); - -static dir_entry *get_dentfromdir(fsdata *mydata, int startsect, - char *filename, dir_entry *retdent, - int dols) -{ - __u16 prevcksum = 0xffff; - __u32 curclust = START(retdent); - int files = 0, dirs = 0; - - debug("get_dentfromdir: %s\n", filename); - - while (1) { - dir_entry *dentptr; - - int i; - - if (get_cluster(mydata, curclust, get_dentfromdir_block, - mydata->clust_size * mydata->sect_size) != 0) { - debug("Error: reading directory block\n"); - return NULL; - } - - dentptr = (dir_entry *)get_dentfromdir_block; - - for (i = 0; i < DIRENTSPERCLUST; i++) { - char s_name[14], l_name[VFAT_MAXLEN_BYTES]; - - l_name[0] = '\0'; - if (dentptr->name[0] == DELETED_FLAG) { - dentptr++; - continue; - } - if ((dentptr->attr & ATTR_VOLUME)) { - if (vfat_enabled && - (dentptr->attr & ATTR_VFAT) == ATTR_VFAT && - (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { - prevcksum = ((dir_slot *)dentptr)->alias_checksum; - get_vfatname(mydata, curclust, - get_dentfromdir_block, - dentptr, l_name); - if (dols) { - int isdir; - char dirc; - int doit = 0; - - isdir = (dentptr->attr & ATTR_DIR); - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (l_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - l_name, - dirc); - } else { - printf(" %s%c\n", - l_name, - dirc); - } - } - dentptr++; - continue; - } - debug("vfatname: |%s|\n", l_name); - } else { - /* Volume label or VFAT entry */ - dentptr++; - continue; - } - } - if (dentptr->name[0] == 0) { - if (dols) { - printf("\n%d file(s), %d dir(s)\n\n", - files, dirs); - } - debug("Dentname == NULL - %d\n", i); - return NULL; - } - if (vfat_enabled) { - __u8 csum = mkcksum(dentptr->name, dentptr->ext); - if (dols && csum == prevcksum) { - prevcksum = 0xffff; - dentptr++; - continue; - } - } - - get_name(dentptr, s_name); - if (dols) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (s_name[0] != 0) { - files++; - doit = 1; - } - } - - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - s_name, dirc); - } else { - printf(" %s%c\n", - s_name, dirc); - } - } - - dentptr++; - continue; - } - - if (strcmp(filename, s_name) - && strcmp(filename, l_name)) { - debug("Mismatch: |%s|%s|\n", s_name, l_name); - dentptr++; - continue; - } - - memcpy(retdent, dentptr, sizeof(dir_entry)); - - debug("DentName: %s", s_name); - debug(", start: 0x%x", START(dentptr)); - debug(", size: 0x%x %s\n", - FAT2CPU32(dentptr->size), - (dentptr->attr & ATTR_DIR) ? "(DIR)" : ""); - - return retdent; - } - - curclust = get_fatent(mydata, curclust); - if (CHECK_CLUST(curclust, mydata->fatsize)) { - debug("curclust: 0x%x\n", curclust); - printf("Invalid FAT entry\n"); - return NULL; - } - } - - return NULL; -} +__u8 do_fat_read_at_block[MAX_CLUSTSIZE] + __aligned(ARCH_DMA_MINALIGN); /* * Read boot sector and volume info from a FAT filesystem @@ -879,374 +618,6 @@ static int get_fs_info(fsdata *mydata) return 0; } -__u8 do_fat_read_at_block[MAX_CLUSTSIZE] - __aligned(ARCH_DMA_MINALIGN); - -int do_fat_read_at(const char *filename, loff_t pos, void *buffer, - loff_t maxsize, int dols, int dogetsize, loff_t *size) -{ - char fnamecopy[2048]; - fsdata datablock; - fsdata *mydata = &datablock; - dir_entry *dentptr = NULL; - __u16 prevcksum = 0xffff; - char *subname = ""; - __u32 cursect; - int idx, isdir = 0; - int files = 0, dirs = 0; - int ret = -1; - int firsttime; - __u32 root_cluster = 0; - __u32 read_blk; - int rootdir_size = 0; - int buffer_blk_cnt; - int do_read; - __u8 *dir_ptr; - - if (get_fs_info(mydata)) - return -1; - - cursect = mydata->rootdir_sect; - - /* "cwd" is always the root... */ - while (ISDIRDELIM(*filename)) - filename++; - - /* Make a copy of the filename and convert it to lowercase */ - strcpy(fnamecopy, filename); - downcase(fnamecopy); - -root_reparse: - if (*fnamecopy == '\0') { - if (!dols) - goto exit; - - dols = LS_ROOT; - } else if ((idx = dirdelim(fnamecopy)) >= 0) { - isdir = 1; - fnamecopy[idx] = '\0'; - subname = fnamecopy + idx + 1; - - /* Handle multiple delimiters */ - while (ISDIRDELIM(*subname)) - subname++; - } else if (dols) { - isdir = 1; - } - - buffer_blk_cnt = 0; - firsttime = 1; - while (1) { - int i; - - if (mydata->fatsize == 32 || firsttime) { - dir_ptr = do_fat_read_at_block; - firsttime = 0; - } else { - /** - * FAT16 sector buffer modification: - * Each loop, the second buffered block is moved to - * the buffer begin, and two next sectors are read - * next to the previously moved one. So the sector - * buffer keeps always 3 sectors for fat16. - * And the current sector is the buffer second sector - * beside the "firsttime" read, when it is the first one. - * - * PREFETCH_BLOCKS is 2 for FAT16 == loop[0:1] - * n = computed root dir sector - * loop | cursect-1 | cursect | cursect+1 | - * 0 | sector n+0 | sector n+1 | none | - * 1 | none | sector n+0 | sector n+1 | - * 0 | sector n+1 | sector n+2 | sector n+3 | - * 1 | sector n+3 | ... - */ - dir_ptr = (do_fat_read_at_block + mydata->sect_size); - memcpy(do_fat_read_at_block, dir_ptr, mydata->sect_size); - } - - do_read = 1; - - if (mydata->fatsize == 32 && buffer_blk_cnt) - do_read = 0; - - if (do_read) { - read_blk = (mydata->fatsize == 32) ? - mydata->clust_size : PREFETCH_BLOCKS; - - debug("FAT read(sect=%d, cnt:%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n", - cursect, read_blk, mydata->clust_size, DIRENTSPERBLOCK); - - if (disk_read(cursect, read_blk, dir_ptr) < 0) { - debug("Error: reading rootdir block\n"); - goto exit; - } - - dentptr = (dir_entry *)dir_ptr; - } - - for (i = 0; i < DIRENTSPERBLOCK; i++) { - char s_name[14], l_name[VFAT_MAXLEN_BYTES]; - __u8 csum; - - l_name[0] = '\0'; - if (dentptr->name[0] == DELETED_FLAG) { - dentptr++; - continue; - } - - if (vfat_enabled) - csum = mkcksum(dentptr->name, dentptr->ext); - - if (dentptr->attr & ATTR_VOLUME) { - if (vfat_enabled && - (dentptr->attr & ATTR_VFAT) == ATTR_VFAT && - (dentptr->name[0] & LAST_LONG_ENTRY_MASK)) { - prevcksum = - ((dir_slot *)dentptr)->alias_checksum; - - get_vfatname(mydata, - root_cluster, - dir_ptr, - dentptr, l_name); - - if (dols == LS_ROOT) { - char dirc; - int doit = 0; - int isdir = - (dentptr->attr & ATTR_DIR); - - if (isdir) { - dirs++; - dirc = '/'; - doit = 1; - } else { - dirc = ' '; - if (l_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - l_name, - dirc); - } else { - printf(" %s%c\n", - l_name, - dirc); - } - } - dentptr++; - continue; - } - debug("Rootvfatname: |%s|\n", - l_name); - } else { - /* Volume label or VFAT entry */ - dentptr++; - continue; - } - } else if (dentptr->name[0] == 0) { - debug("RootDentname == NULL - %d\n", i); - if (dols == LS_ROOT) { - printf("\n%d file(s), %d dir(s)\n\n", - files, dirs); - ret = 0; - } - goto exit; - } - else if (vfat_enabled && - dols == LS_ROOT && csum == prevcksum) { - prevcksum = 0xffff; - dentptr++; - continue; - } - - get_name(dentptr, s_name); - - if (dols == LS_ROOT) { - int isdir = (dentptr->attr & ATTR_DIR); - char dirc; - int doit = 0; - - if (isdir) { - dirc = '/'; - if (s_name[0] != 0) { - dirs++; - doit = 1; - } - } else { - dirc = ' '; - if (s_name[0] != 0) { - files++; - doit = 1; - } - } - if (doit) { - if (dirc == ' ') { - printf(" %8u %s%c\n", - FAT2CPU32(dentptr->size), - s_name, dirc); - } else { - printf(" %s%c\n", - s_name, dirc); - } - } - dentptr++; - continue; - } - - if (strcmp(fnamecopy, s_name) - && strcmp(fnamecopy, l_name)) { - debug("RootMismatch: |%s|%s|\n", s_name, - l_name); - dentptr++; - continue; - } - - if (isdir && !(dentptr->attr & ATTR_DIR)) - goto exit; - - debug("RootName: %s", s_name); - debug(", start: 0x%x", START(dentptr)); - debug(", size: 0x%x %s\n", - FAT2CPU32(dentptr->size), - isdir ? "(DIR)" : ""); - - goto rootdir_done; /* We got a match */ - } - debug("END LOOP: buffer_blk_cnt=%d clust_size=%d\n", buffer_blk_cnt, - mydata->clust_size); - - /* - * On FAT32 we must fetch the FAT entries for the next - * root directory clusters when a cluster has been - * completely processed. - */ - ++buffer_blk_cnt; - int rootdir_end = 0; - if (mydata->fatsize == 32) { - if (buffer_blk_cnt == mydata->clust_size) { - int nxtsect = 0; - int nxt_clust = 0; - - nxt_clust = get_fatent(mydata, root_cluster); - rootdir_end = CHECK_CLUST(nxt_clust, 32); - - nxtsect = mydata->data_begin + - (nxt_clust * mydata->clust_size); - - root_cluster = nxt_clust; - - cursect = nxtsect; - buffer_blk_cnt = 0; - } - } else { - if (buffer_blk_cnt == PREFETCH_BLOCKS) - buffer_blk_cnt = 0; - - rootdir_end = (++cursect - mydata->rootdir_sect >= - rootdir_size); - } - - /* If end of rootdir reached */ - if (rootdir_end) { - if (dols == LS_ROOT) { - printf("\n%d file(s), %d dir(s)\n\n", - files, dirs); - *size = 0; - } - goto exit; - } - } -rootdir_done: - - firsttime = 1; - - while (isdir) { - int startsect = mydata->data_begin - + START(dentptr) * mydata->clust_size; - dir_entry dent; - char *nextname = NULL; - - dent = *dentptr; - dentptr = &dent; - - idx = dirdelim(subname); - - if (idx >= 0) { - subname[idx] = '\0'; - nextname = subname + idx + 1; - /* Handle multiple delimiters */ - while (ISDIRDELIM(*nextname)) - nextname++; - if (dols && *nextname == '\0') - firsttime = 0; - } else { - if (dols && firsttime) { - firsttime = 0; - } else { - isdir = 0; - } - } - - if (get_dentfromdir(mydata, startsect, subname, dentptr, - isdir ? 0 : dols) == NULL) { - if (dols && !isdir) - *size = 0; - goto exit; - } - - if (isdir && !(dentptr->attr & ATTR_DIR)) - goto exit; - - /* - * If we are looking for a directory, and found a directory - * type entry, and the entry is for the root directory (as - * denoted by a cluster number of 0), jump back to the start - * of the function, since at least on FAT12/16, the root dir - * lives in a hard-coded location and needs special handling - * to parse, rather than simply following the cluster linked - * list in the FAT, like other directories. - */ - if (isdir && (dentptr->attr & ATTR_DIR) && !START(dentptr)) { - /* - * Modify the filename to remove the prefix that gets - * back to the root directory, so the initial root dir - * parsing code can continue from where we are without - * confusion. - */ - strcpy(fnamecopy, nextname ?: ""); - /* - * Set up state the same way as the function does when - * first started. This is required for the root dir - * parsing code operates in its expected environment. - */ - subname = ""; - cursect = mydata->rootdir_sect; - isdir = 0; - goto root_reparse; - } - - if (idx >= 0) - subname = nextname; - } - - if (dogetsize) { - *size = FAT2CPU32(dentptr->size); - ret = 0; - } else { - ret = get_contents(mydata, dentptr, pos, buffer, maxsize, size); - } - debug("Size: %u, got: %llu\n", FAT2CPU32(dentptr->size), *size); - -exit: - free(mydata->fatbuf); - return ret; -} - /* * Directory iterator, to simplify filesystem traversal @@ -1595,12 +966,6 @@ static int fat_itr_resolve(fat_itr *itr, const char *path, unsigned type) return -ENOENT; } -int do_fat_read(const char *filename, void *buffer, loff_t maxsize, int dols, - loff_t *actread) -{ - return do_fat_read_at(filename, 0, buffer, maxsize, dols, 0, actread); -} - int file_fat_detectfs(void) { boot_sector bs; @@ -1665,31 +1030,96 @@ int file_fat_detectfs(void) int file_fat_ls(const char *dir) { - loff_t size; + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; + int files = 0, dirs = 0; + int ret; + + ret = fat_itr_root(itr, &fsdata); + if (ret) + return ret; + + ret = fat_itr_resolve(itr, dir, TYPE_DIR); + if (ret) + return ret; + + while (fat_itr_next(itr)) { + if (fat_itr_isdir(itr)) { + printf(" %s/\n", itr->name); + dirs++; + } else { + printf(" %8u %s\n", + FAT2CPU32(itr->dent->size), + itr->name); + files++; + } + } - return do_fat_read(dir, NULL, 0, LS_YES, &size); + printf("\n%d file(s), %d dir(s)\n\n", files, dirs); + + return 0; } int fat_exists(const char *filename) { + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; int ret; - loff_t size; - ret = do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, &size); + ret = fat_itr_root(itr, &fsdata); + if (ret) + return 0; + + ret = fat_itr_resolve(itr, filename, TYPE_ANY); return ret == 0; } int fat_size(const char *filename, loff_t *size) { - return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1, size); + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; + int ret; + + ret = fat_itr_root(itr, &fsdata); + if (ret) + return ret; + + ret = fat_itr_resolve(itr, filename, TYPE_FILE); + if (ret) { + /* + * Directories don't have size, but fs_size() is not + * expected to fail if passed a directory path: + */ + fat_itr_root(itr, &fsdata); + if (!fat_itr_resolve(itr, filename, TYPE_DIR)) { + *size = 0; + return 0; + } + return ret; + } + + *size = FAT2CPU32(itr->dent->size); + + return 0; } int file_fat_read_at(const char *filename, loff_t pos, void *buffer, loff_t maxsize, loff_t *actread) { + fsdata fsdata; + fat_itr itrblock, *itr = &itrblock; + int ret; + + ret = fat_itr_root(itr, &fsdata); + if (ret) + return ret; + + ret = fat_itr_resolve(itr, filename, TYPE_FILE); + if (ret) + return ret; + printf("reading %s\n", filename); - return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO, 0, - actread); + return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread); } int file_fat_read(const char *filename, void *buffer, int maxsize) diff --git a/include/fat.h b/include/fat.h index 21bb6666cf..18d8981c48 100644 --- a/include/fat.h +++ b/include/fat.h @@ -58,12 +58,6 @@ */ #define LAST_LONG_ENTRY_MASK 0x40 -/* Flags telling whether we should read a file or list a directory */ -#define LS_NO 0 -#define LS_YES 1 -#define LS_DIR 1 -#define LS_ROOT 2 - #define ISDIRDELIM(c) ((c) == '/' || (c) == '\\') #define FSTYPE_NONE (-1) From patchwork Sat Sep 9 17:15:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811970 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="YW25BJ/Y"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLWT60hBz9t16 for ; Sun, 10 Sep 2017 03:18:45 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id A335DC21F04; Sat, 9 Sep 2017 17:16:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C0F24C21E54; Sat, 9 Sep 2017 17:16:55 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 93C35C21C35; Sat, 9 Sep 2017 17:16:43 +0000 (UTC) Received: from mail-qk0-f193.google.com (mail-qk0-f193.google.com [209.85.220.193]) by lists.denx.de (Postfix) with ESMTPS id E563EC21EFC for ; Sat, 9 Sep 2017 17:16:38 +0000 (UTC) Received: by mail-qk0-f193.google.com with SMTP id o77so3234277qke.2 for ; Sat, 09 Sep 2017 10:16:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H/PHz9M1Onapa4r2mUlmZrc6JQMTaIbCS4SXtWVnBXA=; b=YW25BJ/Yc6PCj0pKkRzmWNeflRLmWRIJ0K+DRZM02rMGjmzeF+l4PGLbMPsTBG7cWS esjm0IdVKSRAsSv5+1Vd/eblmfplRbdPCCCxws77ymVgPv9dT+zWo+vVhiLZyUx2GxGx sQD897Ct2pmdfr1P3zDTVzLAFgd7lpWfKowHXNw3qlv2rxU+SI5w5Y1+PBa7AmVPL9ii JWlmIaKTalLJmYG7d43RWOzdcvmrA2JpS2dfjsHbT0Z1by9opmyQBc7yc/f2qSaJbXs9 UyC7euvzQbvN7uo3m7Kk7tH1RlsxW8DJakxWVnZsWIbjidI6LhqovAoGfa9pLS2VUChS hWvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H/PHz9M1Onapa4r2mUlmZrc6JQMTaIbCS4SXtWVnBXA=; b=sYDmPbiCzGrcBwML7HKvPvfeyvmJnjp+CkTEedA7AFYMjCsUlTdfn5+evxBJ9AYq8w fA6ORUA1FMF/+dlkntBrn5qhNWSgKhJaHwcRD8r8CiwO/Hx4FLtVaYOr88eHyXtF8dJv eOaoLGIbSt3qqCrrCO3fa+eGYKmKsa++Z+9rarhImFCiyQyga4wEmVOJsCoqDH21Aj6X 7qWB5rtvI5fQGM5BEi2b4nMVtTvVKGR9bw7TqZ6FYRbEES1WaekiCg3UfFU0Ngj08VlE jZGFjY6YLFGtl9dgPHwJFOBc/+Rz1Za8Dwo3iqlJbhWmjDEbkfYd/QuCH/uj3NYRQfH4 208w== X-Gm-Message-State: AHPjjUi0N4HPnYzmy8OheJoHlZkyMyCjzmcXTfsD0Yqsku+bR+3haDWa G1bIa9VRP06FFGG0u3w= X-Google-Smtp-Source: AOwi7QAFLS4uj4W5P7yBmI06muJ5+2dAloFk0nk/dPTMmEuTBD9zhzyZIs76XevfQrqY6lkGKJSIAw== X-Received: by 10.55.52.19 with SMTP id b19mr8598444qka.77.1504977397444; Sat, 09 Sep 2017 10:16:37 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id g15sm3202553qtk.47.2017.09.09.10.16.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:36 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:55 -0400 Message-Id: <20170909171606.20029-5-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Petr Kulhavy , Heinrich Schuchardt , Zhikang Zhang , Alison Chaiken , Steve Rae , Maxime Ripard Subject: [U-Boot] [PATCH v3 4/9] fs: add fs_readdir() X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Needed to support efi file protocol. The fallback.efi loader wants to be able to read the contents of the /EFI directory to find an OS to boot. Modelled after POSIX opendir()/readdir()/closedir(). Unlike the other fs APIs, this is stateful (ie. state is held in the FS_DIR "directory stream"), to avoid re-traversing of the directory structure at each step. The directory stream must be released with closedir() when it is no longer needed. Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski Reviewed-by: Simon Glass --- disk/part.c | 31 ++++++++++------- fs/fs.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/fs.h | 67 +++++++++++++++++++++++++++++++++++++ include/part.h | 9 +++++ 4 files changed, 199 insertions(+), 12 deletions(-) diff --git a/disk/part.c b/disk/part.c index c67fdacc79..aa9183d696 100644 --- a/disk/part.c +++ b/disk/part.c @@ -331,6 +331,24 @@ int part_get_info(struct blk_desc *dev_desc, int part, return -1; } +int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info) +{ + info->start = 0; + info->size = dev_desc->lba; + info->blksz = dev_desc->blksz; + info->bootable = 0; + strcpy((char *)info->type, BOOT_PART_TYPE); + strcpy((char *)info->name, "Whole Disk"); +#if CONFIG_IS_ENABLED(PARTITION_UUIDS) + info->uuid[0] = 0; +#endif +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; +#endif + + return 0; +} + int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, struct blk_desc **dev_desc) { @@ -523,18 +541,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str, (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); - info->start = 0; - info->size = (*dev_desc)->lba; - info->blksz = (*dev_desc)->blksz; - info->bootable = 0; - strcpy((char *)info->type, BOOT_PART_TYPE); - strcpy((char *)info->name, "Whole Disk"); -#if CONFIG_IS_ENABLED(PARTITION_UUIDS) - info->uuid[0] = 0; -#endif -#ifdef CONFIG_PARTITION_TYPE_GUID - info->type_guid[0] = 0; -#endif + part_get_info_whole_disk(*dev_desc, info); ret = 0; goto cleanup; diff --git a/fs/fs.c b/fs/fs.c index 13cd3626c6..fc0c953fcb 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -21,6 +21,7 @@ DECLARE_GLOBAL_DATA_PTR; static struct blk_desc *fs_dev_desc; +static int fs_dev_part; static disk_partition_t fs_partition; static int fs_type = FS_TYPE_ANY; @@ -69,6 +70,12 @@ static inline int fs_uuid_unsupported(char *uuid_str) return -1; } +static inline int fs_opendir_unsupported(const char *filename, + struct fs_dir_stream **dirs) +{ + return -EACCES; +} + struct fstype_info { int fstype; char *name; @@ -92,6 +99,20 @@ struct fstype_info { loff_t len, loff_t *actwrite); void (*close)(void); int (*uuid)(char *uuid_str); + /* + * Open a directory stream. On success return 0 and directory + * stream pointer via 'dirsp'. On error, return -errno. See + * fs_opendir(). + */ + int (*opendir)(const char *filename, struct fs_dir_stream **dirsp); + /* + * Read next entry from directory stream. On success return 0 + * and directory entry pointer via 'dentp'. On error return + * -errno. See fs_readdir(). + */ + int (*readdir)(struct fs_dir_stream *dirs, struct fs_dirent **dentp); + /* see fs_closedir() */ + void (*closedir)(struct fs_dir_stream *dirs); }; static struct fstype_info fstypes[] = { @@ -112,6 +133,7 @@ static struct fstype_info fstypes[] = { .write = fs_write_unsupported, #endif .uuid = fs_uuid_unsupported, + .opendir = fs_opendir_unsupported, }, #endif #ifdef CONFIG_FS_EXT4 @@ -131,6 +153,7 @@ static struct fstype_info fstypes[] = { .write = fs_write_unsupported, #endif .uuid = ext4fs_uuid, + .opendir = fs_opendir_unsupported, }, #endif #ifdef CONFIG_SANDBOX @@ -146,6 +169,7 @@ static struct fstype_info fstypes[] = { .read = fs_read_sandbox, .write = fs_write_sandbox, .uuid = fs_uuid_unsupported, + .opendir = fs_opendir_unsupported, }, #endif #ifdef CONFIG_CMD_UBIFS @@ -161,6 +185,7 @@ static struct fstype_info fstypes[] = { .read = ubifs_read, .write = fs_write_unsupported, .uuid = fs_uuid_unsupported, + .opendir = fs_opendir_unsupported, }, #endif { @@ -175,6 +200,7 @@ static struct fstype_info fstypes[] = { .read = fs_read_unsupported, .write = fs_write_unsupported, .uuid = fs_uuid_unsupported, + .opendir = fs_opendir_unsupported, }, }; @@ -228,6 +254,31 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype) if (!info->probe(fs_dev_desc, &fs_partition)) { fs_type = info->fstype; + fs_dev_part = part; + return 0; + } + } + + return -1; +} + +/* set current blk device w/ blk_desc + partition # */ +int fs_set_blk_dev_with_part(struct blk_desc *desc, int part) +{ + struct fstype_info *info; + int ret, i; + + if (part >= 1) + ret = part_get_info(desc, part, &fs_partition); + else + ret = part_get_info_whole_disk(desc, &fs_partition); + if (ret) + return ret; + fs_dev_desc = desc; + + for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes); i++, info++) { + if (!info->probe(fs_dev_desc, &fs_partition)) { + fs_type = info->fstype; return 0; } } @@ -334,6 +385,59 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, return ret; } +struct fs_dir_stream *fs_opendir(const char *filename) +{ + struct fstype_info *info = fs_get_info(fs_type); + struct fs_dir_stream *dirs = NULL; + int ret; + + ret = info->opendir(filename, &dirs); + fs_close(); + if (ret) { + errno = -ret; + return NULL; + } + + dirs->desc = fs_dev_desc; + dirs->part = fs_dev_part; + + return dirs; +} + +struct fs_dirent *fs_readdir(struct fs_dir_stream *dirs) +{ + struct fstype_info *info; + struct fs_dirent *dirent; + int ret; + + fs_set_blk_dev_with_part(dirs->desc, dirs->part); + info = fs_get_info(fs_type); + + ret = info->readdir(dirs, &dirent); + fs_close(); + if (ret) { + errno = -ret; + return NULL; + } + + return dirent; +} + +void fs_closedir(struct fs_dir_stream *dirs) +{ + struct fstype_info *info; + + if (!dirs) + return; + + fs_set_blk_dev_with_part(dirs->desc, dirs->part); + info = fs_get_info(fs_type); + + info->closedir(dirs); + fs_close(); +} + + int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int fstype) { diff --git a/include/fs.h b/include/fs.h index 2f2aca8378..0869ad6e80 100644 --- a/include/fs.h +++ b/include/fs.h @@ -27,6 +27,17 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype); /* + * fs_set_blk_dev_with_part - Set current block device + partition + * + * Similar to fs_set_blk_dev(), but useful for cases where you already + * know the blk_desc and part number. + * + * Returns 0 on success. + * Returns non-zero if invalid partition or error accessing the disk. + */ +int fs_set_blk_dev_with_part(struct blk_desc *desc, int part); + +/* * Print the list of files on the partition previously set by fs_set_blk_dev(), * in directory "dirname". * @@ -79,6 +90,62 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, loff_t *actwrite); /* + * Directory entry types, matches the subset of DT_x in posix readdir() + * which apply to u-boot. + */ +#define FS_DT_DIR 4 /* directory */ +#define FS_DT_REG 8 /* regular file */ +#define FS_DT_LNK 10 /* symbolic link */ + +/* + * A directory entry, returned by fs_readdir(). Returns information + * about the file/directory at the current directory entry position. + */ +struct fs_dirent { + unsigned type; /* one of FS_DT_x (not a mask) */ + loff_t size; /* size in bytes */ + char name[256]; +}; + +/* Note: fs_dir_stream should be treated as opaque to the user of fs layer */ +struct fs_dir_stream { + /* private to fs. layer: */ + struct blk_desc *desc; + int part; +}; + +/* + * fs_opendir - Open a directory + * + * @filename: the path to directory to open + * @return a pointer to the directory stream or NULL on error and errno + * set appropriately + */ +struct fs_dir_stream *fs_opendir(const char *filename); + +/* + * fs_readdir - Read the next directory entry in the directory stream. + * + * Works in an analogous way to posix readdir(). The previously returned + * directory entry is no longer valid after calling fs_readdir() again. + * After fs_closedir() is called, the returned directory entry is no + * longer valid. + * + * @dirs: the directory stream + * @return the next directory entry (only valid until next fs_readdir() or + * fs_closedir() call, do not attempt to free()) or NULL if the end of + * the directory is reached. + */ +struct fs_dirent *fs_readdir(struct fs_dir_stream *dirs); + +/* + * fs_closedir - close a directory stream + * + * @dirs: the directory stream + */ +void fs_closedir(struct fs_dir_stream *dirs); + +/* * Common implementation for various filesystem commands, optionally limited * to a specific filesystem type via the fstype parameter. */ diff --git a/include/part.h b/include/part.h index 0d5c99836b..86117a7ce5 100644 --- a/include/part.h +++ b/include/part.h @@ -98,6 +98,12 @@ int host_get_dev_err(int dev, struct blk_desc **blk_devp); /* disk/part.c */ int part_get_info(struct blk_desc *dev_desc, int part, disk_partition_t *info); +/** + * part_get_info_whole_disk() - get partition info for the special case of + * a partition occupying the entire disk. + */ +int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info); + void part_print(struct blk_desc *dev_desc); void part_init(struct blk_desc *dev_desc); void dev_print(struct blk_desc *dev_desc); @@ -203,6 +209,9 @@ static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; } static inline int part_get_info(struct blk_desc *dev_desc, int part, disk_partition_t *info) { return -1; } +static inline int part_get_info_whole_disk(struct blk_desc *dev_desc, + disk_partition_t *info) +{ return -1; } static inline void part_print(struct blk_desc *dev_desc) {} static inline void part_init(struct blk_desc *dev_desc) {} static inline void dev_print(struct blk_desc *dev_desc) {} From patchwork Sat Sep 9 17:15:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811969 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="n+lkT5oE"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLVV1xNkz9t16 for ; Sun, 10 Sep 2017 03:17:54 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id E07C3C21EDC; Sat, 9 Sep 2017 17:17:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 15E14C21E0C; Sat, 9 Sep 2017 17:17:07 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 18BE9C21E92; Sat, 9 Sep 2017 17:16:46 +0000 (UTC) Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by lists.denx.de (Postfix) with ESMTPS id D1A06C21E99 for ; Sat, 9 Sep 2017 17:16:42 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id l25so380199qtf.2 for ; Sat, 09 Sep 2017 10:16:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JQFBMriCF8kpLl5pw7gQ935N+34SJvcfPBpLESISXgc=; b=n+lkT5oE8xIR2+0kIXrJdBpsMPPLaeGYEQTu/uav0OLWhYpNyiodNLigFHYDmxtlfv 8AGu+GLffXmtYXporaKgRl96+WjMaCdQdScbesgAWlEONGnHnXP8d647Q5eJoRCGbCkk Pj/N0ZvoRO/UtQVY0vU80tpGZmqQjSdcTY45b7NpTCT5I+H4fNr+VVTuDharD3uWkfeo 3K6lwryIo6kqf4nMn5eokcLUXxudw7dIMWZDY3brO+S6Sq3eBz+tKKz6zTa6EGNwKMpx HVFrf4UzcFB5LIVEaDEN1o2ItDHCT4kjLhGtsgNNUwz6z9PEmvCqg2VfB4u/Reqbigc0 OwHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JQFBMriCF8kpLl5pw7gQ935N+34SJvcfPBpLESISXgc=; b=eZ4+/NVrLQ7fjeuDwLXNYTKpkw23wQZky9NLv2U8W/O1ZD8TCCbe0aePLSd99e+wOv lWh5uH3do0Vw3mC3/Xv806y0ZwxT2tbL8SNAeWuKaNfHX+HYfHW1T9/ABMiWZeog4/4G NjuOdtH/X6SYYjsfaHvcJAzDvL5wfzPOWwiuX/H/h4+BtnJD51dTjYCAZMu/itxirspF hH/48rs/oA8GwWXkvsbaCgui3bfIuotHC1V+CqaPAq1IfEzVTRpQ/QovHk5tbUUgrIg2 xR7wN2PBHTLV2Z9Pu7CjaC+CH+6MfXz3N+7nFXlrQrtcev+DExi86D+6rNLsXtL8xwdS sTCA== X-Gm-Message-State: AHPjjUjkes6fJYf+JiRYnpeFrwoM+TvgclK7abmsYlFj7n2UH3u6Y0/L A/tjF/xk3fE+hu0dG3Q= X-Google-Smtp-Source: AOwi7QC0UJgOy6PL+uo/Het+6RGft+Ib0mdD+Svol7m6GY2xxUvzJBqVcfarOXt0N8NernL8Ha3sxA== X-Received: by 10.200.17.136 with SMTP id d8mr8992585qtj.26.1504977401592; Sat, 09 Sep 2017 10:16:41 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id r48sm3160472qte.81.2017.09.09.10.16.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:40 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:56 -0400 Message-Id: <20170909171606.20029-6-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Heinrich Schuchardt Subject: [U-Boot] [PATCH v3 5/9] fs/fat: implement opendir/readdir/closedir X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Implement the readdir interface using the directory iterators. Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski Reviewed-by: Simon Glass --- fs/fat/fat.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index bbba7947ee..82ddb7eab1 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1146,6 +1147,66 @@ int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len, return ret; } +typedef struct { + struct fs_dir_stream parent; + struct fs_dirent dirent; + fsdata fsdata; + fat_itr itr; +} fat_dir; + +int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) +{ + fat_dir *dir = malloc(sizeof(*dir)); + int ret; + + if (!dir) + return -ENOMEM; + + ret = fat_itr_root(&dir->itr, &dir->fsdata); + if (ret) + goto fail; + + ret = fat_itr_resolve(&dir->itr, filename, TYPE_DIR); + if (ret) + goto fail; + + *dirsp = (struct fs_dir_stream *)dir; + return 0; + +fail: + free(dir); + return ret; +} + +int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp) +{ + fat_dir *dir = (fat_dir *)dirs; + struct fs_dirent *dent = &dir->dirent; + + if (!fat_itr_next(&dir->itr)) + return -ENOENT; + + memset(dent, 0, sizeof(*dent)); + strcpy(dent->name, dir->itr.name); + + if (fat_itr_isdir(&dir->itr)) { + dent->type = FS_DT_DIR; + } else { + dent->type = FS_DT_REG; + dent->size = FAT2CPU32(dir->itr.dent->size); + } + + *dentp = dent; + + return 0; +} + +void fat_closedir(struct fs_dir_stream *dirs) +{ + fat_dir *dir = (fat_dir *)dirs; + free(dir); +} + void fat_close(void) { } From patchwork Sat Sep 9 17:15:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811974 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UkUWI05G"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLbD1HJ6z9t16 for ; Sun, 10 Sep 2017 03:22:00 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id CA482C21EB1; Sat, 9 Sep 2017 17:18:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 569E8C21F12; Sat, 9 Sep 2017 17:17:33 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B13B4C21F28; Sat, 9 Sep 2017 17:16:48 +0000 (UTC) Received: from mail-qk0-f195.google.com (mail-qk0-f195.google.com [209.85.220.195]) by lists.denx.de (Postfix) with ESMTPS id 5C3F6C21E68 for ; Sat, 9 Sep 2017 17:16:47 +0000 (UTC) Received: by mail-qk0-f195.google.com with SMTP id o77so3234392qke.2 for ; Sat, 09 Sep 2017 10:16:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PymlcJay5TBoRrL4RcwklBXHDDJILXqutTw+bvDSHWU=; b=UkUWI05GpK5jicSZT9rrQM6HZ6ggLy341AombgLXCtggxGhPJFMOcMv6FJ5TcRPNK5 TNr6hZCt266xiL4bQF0+cxOUiDMP/xkZGiBGMNN9VxUGv++bTM5oquiFA3hUnOR9tJMQ V6ziB2aL1LUdWttZ+QvYIEx9HTMnt6WK6l8MoGGSi5cihDibhgyTcASP0Ja6M6+KQpK7 IjGPy8k+kUpnjDMN2m0fYX8bXl9wvpOoC3nUexrlXcL5fVWqfePfPaaTi9AjzsbmcoQE KDbxQfWhvg2kDsWoGgoPigifXfnfU1dOcbHjEBHrsfyHR9ZSqBhtcSrcEFmOX8gz5ukW dVHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PymlcJay5TBoRrL4RcwklBXHDDJILXqutTw+bvDSHWU=; b=K/Qzeh3KBzm5POeBwaTHgzyCLq3mcyQYxNKbsbpLLPjp4DNvsb3Dr+p3xtlYC7U9TI +kKyVZ5itbwDKoN1zdhgI3ULAuO/pq6ZyyyI+Za4U0YmwLZf5/m270NcEdZfSSDDpLx5 Mz5hUwkrbJtIgL3gqXeIhdGjI/10pdMRtmwbzRr0jV6jIC0hJRN98bDwNCmita2M8LEW 4fsK81ipkOEXIk99OOQCQutNl7JX5t3ZLMDQqYAAyLx3SRy24f8cPHU5cO8flqBq5syu erCYfp3Xyx8uGen+PfdxZrLL5qInjjSADhednoqw87pm91i+QGp+6qbrF4Xdf5Y5ibsH TJ9A== X-Gm-Message-State: AHPjjUjWlmBwWNH73X3KRY6dKMLn2DQYBhdz+p7eTl1bqzYkUHfaH9Tr +wSLQfdw2B1PTtY9GHU= X-Google-Smtp-Source: AOwi7QAnwIWBH8j4tfFzah6kHlqUvw7sV7P75GsAd5cubx8AWMkE1HfbPFeK0ztV1GiA6fDb3hGL1g== X-Received: by 10.55.158.68 with SMTP id h65mr6301730qke.322.1504977406024; Sat, 09 Sep 2017 10:16:46 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id p7sm3204046qke.78.2017.09.09.10.16.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:44 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:57 -0400 Message-Id: <20170909171606.20029-7-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Heinrich Schuchardt , Tien Fong Chee Subject: [U-Boot] [PATCH v3 6/9] fat/fs: remove a bunch of dead code X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Spotted by chance, when trying to remove file_fat_ls(), I noticed there were some dead users of the API. Signed-off-by: Rob Clark Acked-by: Stefan Brüns Reviewed-by: Simon Glass --- fs/fat/Makefile | 4 -- fs/fat/file.c | 183 -------------------------------------------------------- include/fat.h | 20 ------- 3 files changed, 207 deletions(-) delete mode 100644 fs/fat/file.c diff --git a/fs/fat/Makefile b/fs/fat/Makefile index b60e8486c4..3e2a6b01a8 100644 --- a/fs/fat/Makefile +++ b/fs/fat/Makefile @@ -5,7 +5,3 @@ obj-$(CONFIG_FS_FAT) := fat.o obj-$(CONFIG_FAT_WRITE):= fat_write.o - -ifndef CONFIG_SPL_BUILD -obj-$(CONFIG_FS_FAT) += file.o -endif diff --git a/fs/fat/file.c b/fs/fat/file.c deleted file mode 100644 index 89706117b9..0000000000 --- a/fs/fat/file.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * file.c - * - * Mini "VFS" by Marcus Sundberg - * - * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 - * 2003-03-10 - kharris@nexus-tech.net - ported to uboot - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include - -/* Supported filesystems */ -static const struct filesystem filesystems[] = { - { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" }, -}; -#define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem)) - -/* The filesystem which was last detected */ -static int current_filesystem = FSTYPE_NONE; - -/* The current working directory */ -#define CWD_LEN 511 -char file_cwd[CWD_LEN+1] = "/"; - -const char * -file_getfsname(int idx) -{ - if (idx < 0 || idx >= NUM_FILESYS) - return NULL; - - return filesystems[idx].name; -} - -static void -pathcpy(char *dest, const char *src) -{ - char *origdest = dest; - - do { - if (dest-file_cwd >= CWD_LEN) { - *dest = '\0'; - return; - } - *(dest) = *(src); - if (*src == '\0') { - if (dest-- != origdest && ISDIRDELIM(*dest)) { - *dest = '\0'; - } - return; - } - ++dest; - - if (ISDIRDELIM(*src)) - while (ISDIRDELIM(*src)) src++; - else - src++; - } while (1); -} - -int -file_cd(const char *path) -{ - if (ISDIRDELIM(*path)) { - while (ISDIRDELIM(*path)) path++; - strncpy(file_cwd+1, path, CWD_LEN-1); - } else { - const char *origpath = path; - char *tmpstr = file_cwd; - int back = 0; - - while (*tmpstr != '\0') tmpstr++; - do { - tmpstr--; - } while (ISDIRDELIM(*tmpstr)); - - while (*path == '.') { - path++; - while (*path == '.') { - path++; - back++; - } - if (*path != '\0' && !ISDIRDELIM(*path)) { - path = origpath; - back = 0; - break; - } - while (ISDIRDELIM(*path)) path++; - origpath = path; - } - - while (back--) { - /* Strip off path component */ - while (!ISDIRDELIM(*tmpstr)) { - tmpstr--; - } - if (tmpstr == file_cwd) { - /* Incremented again right after the loop. */ - tmpstr--; - break; - } - /* Skip delimiters */ - while (ISDIRDELIM(*tmpstr)) tmpstr--; - } - tmpstr++; - if (*path == '\0') { - if (tmpstr == file_cwd) { - *tmpstr = '/'; - tmpstr++; - } - *tmpstr = '\0'; - return 0; - } - *tmpstr = '/'; - pathcpy(tmpstr+1, path); - } - - return 0; -} - -int -file_detectfs(void) -{ - int i; - - current_filesystem = FSTYPE_NONE; - - for (i = 0; i < NUM_FILESYS; i++) { - if (filesystems[i].detect() == 0) { - strcpy(file_cwd, "/"); - current_filesystem = i; - break; - } - } - - return current_filesystem; -} - -int -file_ls(const char *dir) -{ - char fullpath[1024]; - const char *arg; - - if (current_filesystem == FSTYPE_NONE) { - printf("Can't list files without a filesystem!\n"); - return -1; - } - - if (ISDIRDELIM(*dir)) { - arg = dir; - } else { - sprintf(fullpath, "%s/%s", file_cwd, dir); - arg = fullpath; - } - return filesystems[current_filesystem].ls(arg); -} - -int file_read(const char *filename, void *buffer, int maxsize) -{ - char fullpath[1024]; - const char *arg; - - if (current_filesystem == FSTYPE_NONE) { - printf("Can't load file without a filesystem!\n"); - return -1; - } - - if (ISDIRDELIM(*filename)) { - arg = filename; - } else { - sprintf(fullpath, "%s/%s", file_cwd, filename); - arg = fullpath; - } - - return filesystems[current_filesystem].read(arg, buffer, maxsize); -} diff --git a/include/fat.h b/include/fat.h index 18d8981c48..b255ce5337 100644 --- a/include/fat.h +++ b/include/fat.h @@ -178,25 +178,6 @@ static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) return fsdata->data_begin + clust * fsdata->clust_size; } -typedef int (file_detectfs_func)(void); -typedef int (file_ls_func)(const char *dir); -typedef int (file_read_func)(const char *filename, void *buffer, - int maxsize); - -struct filesystem { - file_detectfs_func *detect; - file_ls_func *ls; - file_read_func *read; - const char name[12]; -}; - -/* FAT tables */ -file_detectfs_func file_fat_detectfs; -file_ls_func file_fat_ls; -file_read_func file_fat_read; - -/* Currently this doesn't check if the dir exists or is valid... */ -int file_cd(const char *path); int file_fat_detectfs(void); int file_fat_ls(const char *dir); int fat_exists(const char *filename); @@ -204,7 +185,6 @@ int fat_size(const char *filename, loff_t *size); int file_fat_read_at(const char *filename, loff_t pos, void *buffer, loff_t maxsize, loff_t *actread); int file_fat_read(const char *filename, void *buffer, int maxsize); -const char *file_getfsname(int idx); int fat_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info); int fat_register_device(struct blk_desc *dev_desc, int part_no); From patchwork Sat Sep 9 17:15:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811975 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mEcmliIj"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLcG07s0z9t16 for ; Sun, 10 Sep 2017 03:22:53 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id C2278C21C58; Sat, 9 Sep 2017 17:19:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 70CAAC21E74; Sat, 9 Sep 2017 17:19:01 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 605A6C21F14; Sat, 9 Sep 2017 17:16:51 +0000 (UTC) Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by lists.denx.de (Postfix) with ESMTPS id F1044C21EFC for ; Sat, 9 Sep 2017 17:16:50 +0000 (UTC) Received: by mail-qt0-f196.google.com with SMTP id u48so400900qtc.4 for ; Sat, 09 Sep 2017 10:16:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UGWkoFliRrSUA/JZSO1m2p6u+Wt51fM3gKGKCoQ5dpU=; b=mEcmliIjiwhGeEDWle4e0Z1b2nBV/zzHH/2RgAhysvOHFqe4fOqbfw06cJ2jWHFPqd fhRN3t/r+oB+Ug8LZIB6HjzoSnLjsbL4xyXBEdo2AE6LRswue9OlwnMhv4tTWcXjcqGA syfiBcUfojn6WHrxp6Bb4a+7Q88y1LMHNecP9e7nrFZAOwWcbJiZnK38+IfEYgcKKmTy M914S1IXfmL0Vj2hFWV05nKhDO3koduasLA9nETSjQgh5iK5WEfo3Mts49S5nu4tG9A5 UKAXg03VRptj3WSe2cHt0qdV77NNOOyaZx3n087AWZN0Kvzlb/ZNgW36oMLYQq44ASC4 ++QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UGWkoFliRrSUA/JZSO1m2p6u+Wt51fM3gKGKCoQ5dpU=; b=RmWtNZGCI7pIS+Mi/UZCkgAo8O3Rx53dtQhjaClmtPQSauPCXjC7FaPyxcnsAci8Dl UuJPUrUKehDU0IH51C9fbeDp6rSdUnv0BtI1kLcQpTeyJ/fNAN1J6L9dHR4SHHPpNy7S 5GU68/jD24gedDEemjZptyF3R28r8fw9TpIfEPazGlOLCXr+zRkojDHVXrUxHBs5ZgwT XV2Qct+pDzMARTQr4WQFAVCOp1IOZJR796aQiPQA7IvyEeRUi9K/coKbp3CjySom7fO2 Nv90izaR3ns+p6e18P90MZkDrj51fgoVLNz65DBIzzcsDS0SihrsSCwMwglSgQ3bq1jp cx3w== X-Gm-Message-State: AHPjjUhDhnfaMEDvFSfzkzKxLxJl956La1MXdQdtQhGqbg/gWsJSCbKg Ps51mZAhtvw/YaUwIP8= X-Google-Smtp-Source: AOwi7QCeoUTIZ3b+kxK8bU04atf2K/c+X0inpFH9RLHe5gzN9csHpHpcyEeBWcsw8sdjxvbL5H9g1w== X-Received: by 10.237.62.200 with SMTP id o8mr9532670qtf.294.1504977409712; Sat, 09 Sep 2017 10:16:49 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id z50sm3490640qta.19.2017.09.09.10.16.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:48 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:58 -0400 Message-Id: <20170909171606.20029-8-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Heinrich Schuchardt , Genevieve Chan , Tien Fong Chee Subject: [U-Boot] [PATCH v3 7/9] fat/fs: move ls to generic implementation X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add a generic implementation of 'ls' using opendir/readdir/closedir, and replace fat's custom implementation. Other filesystems should move to the generic implementation after they add opendir/readdir/closedir support. Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski Reviewed-by: Simon Glass --- fs/fat/fat.c | 32 -------------------------------- fs/fs.c | 35 +++++++++++++++++++++++++++++++++-- include/fat.h | 5 ++++- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 82ddb7eab1..c951d84f57 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1029,38 +1029,6 @@ int file_fat_detectfs(void) return 0; } -int file_fat_ls(const char *dir) -{ - fsdata fsdata; - fat_itr itrblock, *itr = &itrblock; - int files = 0, dirs = 0; - int ret; - - ret = fat_itr_root(itr, &fsdata); - if (ret) - return ret; - - ret = fat_itr_resolve(itr, dir, TYPE_DIR); - if (ret) - return ret; - - while (fat_itr_next(itr)) { - if (fat_itr_isdir(itr)) { - printf(" %s/\n", itr->name); - dirs++; - } else { - printf(" %8u %s\n", - FAT2CPU32(itr->dent->size), - itr->name); - files++; - } - } - - printf("\n%d file(s), %d dir(s)\n\n", files, dirs); - - return 0; -} - int fat_exists(const char *filename) { fsdata fsdata; diff --git a/fs/fs.c b/fs/fs.c index fc0c953fcb..3481229aa6 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -37,6 +37,35 @@ static inline int fs_ls_unsupported(const char *dirname) return -1; } +/* generic implementation of ls in terms of opendir/readdir/closedir */ +__maybe_unused +static int fs_ls_generic(const char *dirname) +{ + struct fs_dir_stream *dirs; + struct fs_dirent *dent; + int nfiles = 0, ndirs = 0; + + dirs = fs_opendir(dirname); + if (!dirs) + return -errno; + + while ((dent = fs_readdir(dirs))) { + if (dent->type == FS_DT_DIR) { + printf(" %s/\n", dent->name); + ndirs++; + } else { + printf(" %8lld %s\n", dent->size, dent->name); + nfiles++; + } + } + + fs_closedir(dirs); + + printf("\n%d file(s), %d dir(s)\n\n", nfiles, ndirs); + + return 0; +} + static inline int fs_exists_unsupported(const char *filename) { return 0; @@ -123,7 +152,7 @@ static struct fstype_info fstypes[] = { .null_dev_desc_ok = false, .probe = fat_set_blk_dev, .close = fat_close, - .ls = file_fat_ls, + .ls = fs_ls_generic, .exists = fat_exists, .size = fat_size, .read = fat_read_file, @@ -133,7 +162,9 @@ static struct fstype_info fstypes[] = { .write = fs_write_unsupported, #endif .uuid = fs_uuid_unsupported, - .opendir = fs_opendir_unsupported, + .opendir = fat_opendir, + .readdir = fat_readdir, + .closedir = fat_closedir, }, #endif #ifdef CONFIG_FS_EXT4 diff --git a/include/fat.h b/include/fat.h index b255ce5337..83cd90017e 100644 --- a/include/fat.h +++ b/include/fat.h @@ -11,6 +11,7 @@ #define _FAT_H_ #include +#include #define CONFIG_SUPPORT_VFAT /* Maximum Long File Name length supported here is 128 UTF-16 code units */ @@ -179,7 +180,6 @@ static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) } int file_fat_detectfs(void); -int file_fat_ls(const char *dir); int fat_exists(const char *filename); int fat_size(const char *filename, loff_t *size); int file_fat_read_at(const char *filename, loff_t pos, void *buffer, @@ -192,5 +192,8 @@ int file_fat_write(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actwrite); int fat_read_file(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actread); +int fat_opendir(const char *filename, struct fs_dir_stream **dirsp); +int fat_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp); +void fat_closedir(struct fs_dir_stream *dirs); void fat_close(void); #endif /* _FAT_H_ */ From patchwork Sat Sep 9 17:15:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811972 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Mmlp/jQx"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLXx51cRz9t16 for ; Sun, 10 Sep 2017 03:20:01 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 0ECB7C21C58; Sat, 9 Sep 2017 17:19:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 53097C21F2A; Sat, 9 Sep 2017 17:17:48 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 769C8C21E8C; Sat, 9 Sep 2017 17:17:02 +0000 (UTC) Received: from mail-qt0-f193.google.com (mail-qt0-f193.google.com [209.85.216.193]) by lists.denx.de (Postfix) with ESMTPS id B0316C21E55 for ; Sat, 9 Sep 2017 17:16:56 +0000 (UTC) Received: by mail-qt0-f193.google.com with SMTP id u48so401064qtc.4 for ; Sat, 09 Sep 2017 10:16:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Y9Zc0Nv79pXQfDgDO26uLmB5Oesm4aAENBswlPKEk6U=; b=Mmlp/jQxxLIXqAwGHi8GzVFUySn9GNfQPAtYov09aDH20T+5diaDlvEHKVQcsGbFLe gZqef8z3AhV15T+FcB0bjKdKmk4gB1p7uctSUkz9sF7Z341EgrG8f+Rww4rLzWZSSfUT TjdU2WGDXGqRg5tW1DFa3l2r/RIyF6eZb61Whj/Kab2HuoHLFW19dm6jYdQPfjJLzBns n9zp6hbEX2Id4Rgx2UuqQSm+N1L/FqD0TNj6mismH2RZlPVmnJ+XzaZs63AMw1f02LxG LiN4FCkjRoumwvPTLOQkh8Fv0Gtc9qNmAeyF77RkpyzX1D81HOVBs4OfxZB2j12hjk3H qOtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Y9Zc0Nv79pXQfDgDO26uLmB5Oesm4aAENBswlPKEk6U=; b=GmBocJMBBqfeeqbZz3poA6SvWH/vNJVfJpu1tDz3bUiViFoUR8aLZGAOXOvGk4D7yP 6ljnbG7QYZ0j4ktRJQ4hSAh950ZkrhhrDjiucAuYEpNgraCWs/JB4tRFyQPd2uFLRzOH Q1CWH809icAlVuK/B5BdtH1UwS1Ww/roU17tiyB9DWxRBlSiWBtFZRRsc8bCkwSTVrE7 GOZ8Oy48HfOMAcB96NnW4Br3BiNj0+UFsk4oaRpfJx6jIFPQ5ER4F2Ri7kTO9H/H0qCv LzexkQ2CJ0TH1KYqCKtHKzHlme0Nv+tTRQEKNYAysCi5DWBxJEgPQqkLd2qlqBnrLRRl Fksg== X-Gm-Message-State: AHPjjUizteH/l05UgQZD7taWexq46/YniU/4uMABrihrAJ3bu7oUpu7k jt2QI30QcrhoJn28TVc= X-Google-Smtp-Source: AOwi7QCH0/8DmhtypWQNmslTbKL37M6sl45KkbLDpDuAvKVwXsxLBvsNQ+HhLCGQ5URxVbVUG+5MLQ== X-Received: by 10.237.59.26 with SMTP id p26mr9707063qte.304.1504977415408; Sat, 09 Sep 2017 10:16:55 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id f4sm3310144qte.76.2017.09.09.10.16.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:16:54 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:15:59 -0400 Message-Id: <20170909171606.20029-9-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> MIME-Version: 1.0 Cc: Philipp Skadorov , Heinrich Schuchardt , Genevieve Chan , Tien Fong Chee Subject: [U-Boot] [PATCH v3 8/9] fs/fat: fix case for FAT shortnames X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Noticed when comparing our output to linux. There are some lcase bits which control whether filename and/or extension should be downcase'd. Signed-off-by: Rob Clark Reviewed-by: Łukasz Majewski Reviewed-by: Simon Glass --- fs/fat/fat.c | 16 ++++++++++------ fs/fat/fat_write.c | 4 ++-- include/fat.h | 6 +++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index c951d84f57..65873a2c2a 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -29,11 +29,13 @@ static const int vfat_enabled = 0; #endif /* - * Convert a string to lowercase. + * Convert a string to lowercase. Converts at most 'len' characters, + * 'len' may be larger than the length of 'str' if 'str' is NULL + * terminated. */ -static void downcase(char *str) +static void downcase(char *str, size_t len) { - while (*str != '\0') { + while (*str != '\0' && len--) { *str = tolower(*str); str++; } @@ -131,10 +133,13 @@ static void get_name(dir_entry *dirent, char *s_name) ptr = s_name; while (*ptr && *ptr != ' ') ptr++; + if (dirent->lcase & CASE_LOWER_BASE) + downcase(s_name, (unsigned)(ptr - s_name)); if (dirent->ext[0] && dirent->ext[0] != ' ') { - *ptr = '.'; - ptr++; + *ptr++ = '.'; memcpy(ptr, dirent->ext, 3); + if (dirent->lcase & CASE_LOWER_EXT) + downcase(ptr, 3); ptr[3] = '\0'; while (*ptr && *ptr != ' ') ptr++; @@ -144,7 +149,6 @@ static void get_name(dir_entry *dirent, char *s_name) *s_name = '\0'; else if (*s_name == aRING) *s_name = DELETED_FLAG; - downcase(s_name); } static int flush_dirty_fat_buffer(fsdata *mydata); diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index 4ca024c208..d0468baf8f 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -345,7 +345,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, *l_name = '\0'; else if (*l_name == aRING) *l_name = DELETED_FLAG; - downcase(l_name); + downcase(l_name, INT_MAX); /* Return the real directory entry */ *retdent = realdent; @@ -981,7 +981,7 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size, memcpy(l_filename, filename, name_len); l_filename[name_len] = 0; /* terminate the string */ - downcase(l_filename); + downcase(l_filename, INT_MAX); startsect = mydata->rootdir_sect; retdent = find_directory_entry(mydata, startsect, diff --git a/include/fat.h b/include/fat.h index 83cd90017e..0f58939124 100644 --- a/include/fat.h +++ b/include/fat.h @@ -128,10 +128,14 @@ typedef struct volume_info /* Boot sign comes last, 2 bytes */ } volume_info; +/* see dir_entry::lcase: */ +#define CASE_LOWER_BASE 8 /* base (name) is lower case */ +#define CASE_LOWER_EXT 16 /* extension is lower case */ + typedef struct dir_entry { char name[8],ext[3]; /* Name and extension */ __u8 attr; /* Attribute bits */ - __u8 lcase; /* Case for base and extension */ + __u8 lcase; /* Case for name and ext (CASE_LOWER_x) */ __u8 ctime_ms; /* Creation time, milliseconds */ __u16 ctime; /* Creation time */ __u16 cdate; /* Creation date */ From patchwork Sat Sep 9 17:16:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 811976 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZZW9V8zF"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3xqLcK2YHhz9t16 for ; Sun, 10 Sep 2017 03:22:57 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 1FE12C21E8C; Sat, 9 Sep 2017 17:19:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 18ECBC21E8C; Sat, 9 Sep 2017 17:18:57 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6FDB4C21E7C; Sat, 9 Sep 2017 17:17:08 +0000 (UTC) Received: from mail-qk0-f196.google.com (mail-qk0-f196.google.com [209.85.220.196]) by lists.denx.de (Postfix) with ESMTPS id 779DBC21D04 for ; Sat, 9 Sep 2017 17:17:02 +0000 (UTC) Received: by mail-qk0-f196.google.com with SMTP id i14so3230435qke.3 for ; Sat, 09 Sep 2017 10:17:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jouUYn8AbqMaxmwkCld1nTQE8E82NXJX/dNooW9ErIs=; b=ZZW9V8zFnUvS/zTEclRCsnJqWNfuL100hYRlbNJ6oVszi5yMijUTDrsHEoTFhIEIDg ANRbk47AKZFEjp5dGEl5UFUGrDVobNHCqTaGn4KGFmIm2b7v/uNrrL963Vn6uV8hOQQB iMBW88fU1A8AYZm8zX2r9DAJqI6Ty6pNGPqlErUewXmnD0d6LJNLx94afmRsuXItBYZH dFDn3IVLtUYpZe+pCXNoxxjgGkPzeb6Q+8NnxKWKSo3WwjY2I2ajfIaLWoaUAl4ob3Vl nwtRE/QPtJ3v4HRdUXFbTtRo/30JSF3Bl6IDm90O/MXB6NBv31fe+wEO3r/x4a7+ZeoA 1aTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jouUYn8AbqMaxmwkCld1nTQE8E82NXJX/dNooW9ErIs=; b=BUfo7rzPWRRIKLT/8HLToErOS2RWpX5ssdjUC6lwEFEBPKVVS7wEFaAemnP0yxXUG3 3+KXGrtxuJ1fENS+Fy5JWXly+2xxw4T+KSWz8hTGF+nZISlPiRiBiMuvdPYGrWnlpoeD QDxGB3RGRIUMdRVE9qbYN7qIiToIZGU2+AIQtFCgmMLgQJdY7eWYxFR+208uIIaYT754 jR5DmSRhRuxVSe8gsAXLG+fL9PrI2xbvi+XgZ8CJwNUGRQr/piAQl4O3yzig2ruXUJ8H yV8U5Ohp4gdHDJYC6FcK7m9J1R6EmEURhW2eXdB1MNYO9ZSzg9BOsz9gxceE6KyyHxBD 018g== X-Gm-Message-State: AHPjjUhzqAsaGeg4JMYf9NV4wyrPLjA7bWaRKYeoi+69+zUUqHFSskWC N/FUStl05GgOBg+pwbY= X-Google-Smtp-Source: AOwi7QBPQ3QjAhmBaUvwg5AV9caiWRYvXLBhKrE3tqgiTprYxZFTGzPhhsnLcCz/4h+D6qODC+SIqw== X-Received: by 10.55.52.135 with SMTP id b129mr9259762qka.308.1504977421139; Sat, 09 Sep 2017 10:17:01 -0700 (PDT) Received: from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a]) by smtp.gmail.com with ESMTPSA id 20sm3233360qtu.77.2017.09.09.10.16.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Sep 2017 10:17:00 -0700 (PDT) From: Rob Clark To: U-Boot Mailing List Date: Sat, 9 Sep 2017 13:16:00 -0400 Message-Id: <20170909171606.20029-10-robdclark@gmail.com> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170909171606.20029-1-robdclark@gmail.com> References: <20170909171606.20029-1-robdclark@gmail.com> Cc: Philipp Skadorov , Heinrich Schuchardt , Genevieve Chan , Tien Fong Chee Subject: [U-Boot] [PATCH v3 9/9] fs/fat: Clean up open-coded sector <-> cluster conversions X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Use the clust_to_sect() helper that was introduced earlier, and add an inverse sect_to_clust(), plus update the various spots that open-coded this conversion previously. Signed-off-by: Rob Clark Reviewed-by: Simon Glass --- fs/fat/fat.c | 8 +++----- fs/fat/fat_write.c | 8 +++----- include/fat.h | 6 +++++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 65873a2c2a..f5f74c12ff 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -257,8 +257,7 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) int ret; if (clustnum > 0) { - startsect = mydata->data_begin + - clustnum * mydata->clust_size; + startsect = clust_to_sect(mydata, clustnum); } else { startsect = mydata->rootdir_sect; } @@ -594,9 +593,8 @@ static int get_fs_info(fsdata *mydata) mydata->data_begin = mydata->rootdir_sect + mydata->rootdir_size - (mydata->clust_size * 2); - mydata->root_cluster = (mydata->rootdir_sect - - mydata->data_begin) / - mydata->clust_size; + mydata->root_cluster = + sect_to_clust(mydata, mydata->rootdir_sect); } mydata->fatbufnum = -1; diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index d0468baf8f..9d2e0ed74c 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -502,8 +502,7 @@ set_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, int ret; if (clustnum > 0) - startsect = mydata->data_begin + - clustnum * mydata->clust_size; + startsect = clust_to_sect(mydata, clustnum); else startsect = mydata->rootdir_sect; @@ -751,8 +750,7 @@ static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size) __u32 startsect, sect_num, offset; if (clustnum > 0) { - startsect = mydata->data_begin + - clustnum * mydata->clust_size; + startsect = clust_to_sect(mydata, clustnum); } else { startsect = mydata->rootdir_sect; } @@ -791,7 +789,7 @@ static dir_entry *empty_dentptr; static dir_entry *find_directory_entry(fsdata *mydata, int startsect, char *filename, dir_entry *retdent, __u32 start) { - __u32 curclust = (startsect - mydata->data_begin) / mydata->clust_size; + __u32 curclust = sect_to_clust(mydata, startsect); debug("get_dentfromdir: %s\n", filename); diff --git a/include/fat.h b/include/fat.h index 0f58939124..bdeda95e6d 100644 --- a/include/fat.h +++ b/include/fat.h @@ -177,12 +177,16 @@ typedef struct { __u32 root_cluster; /* First cluster of root dir for FAT32 */ } fsdata; -/* TODO clean up places that are open-coding this: */ static inline u32 clust_to_sect(fsdata *fsdata, u32 clust) { return fsdata->data_begin + clust * fsdata->clust_size; } +static inline u32 sect_to_clust(fsdata *fsdata, u32 sect) +{ + return (sect - fsdata->data_begin) / fsdata->clust_size; +} + int file_fat_detectfs(void); int fat_exists(const char *filename); int fat_size(const char *filename, loff_t *size);