From patchwork Sun Apr 17 05:06:52 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baidu Boy X-Patchwork-Id: 91529 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 19ED7B6F29 for ; Sun, 17 Apr 2011 15:07:43 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B048D280F8; Sun, 17 Apr 2011 07:07:39 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nxzn+CwcWoKJ; Sun, 17 Apr 2011 07:07:39 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6498E280EB; Sun, 17 Apr 2011 07:07:37 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7D787280EB for ; Sun, 17 Apr 2011 07:07:35 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6pV05SC5cE8S for ; Sun, 17 Apr 2011 07:07:34 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pv0-f172.google.com (mail-pv0-f172.google.com [74.125.83.172]) by theia.denx.de (Postfix) with ESMTPS id 04BBA280E5 for ; Sun, 17 Apr 2011 07:07:31 +0200 (CEST) Received: by pvh1 with SMTP id 1so1763839pvh.3 for ; Sat, 16 Apr 2011 22:07:28 -0700 (PDT) Received: by 10.68.46.200 with SMTP id x8mr4865330pbm.102.1303016848385; Sat, 16 Apr 2011 22:07:28 -0700 (PDT) Received: from LENOVOE5CA6843 ([117.88.187.169]) by mx.google.com with ESMTPS id n7sm1464593pbi.2.2011.04.16.22.07.12 (version=SSLv3 cipher=OTHER); Sat, 16 Apr 2011 22:07:27 -0700 (PDT) From: "Baidu Liu" To: , , Date: Sun, 17 Apr 2011 13:06:52 +0800 Message-ID: <000001cbfcbd$59578ec0$6401a8c0@LENOVOE5CA6843> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 11 Thread-Index: Acv8vUOr6b0uFi/+Q5GlIfsOqixmmg== X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3664 Subject: [U-Boot] [PATCH,V2] JFFS2: accelerate scanning. X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Syncs up with jffs2 in the linux kernel: 1/ Change DEFAULT_EMPTY_SCAN_SIZE from 4KB to 256 Bytes. 2/ If the 1KB data is 0xFF after the cleanmarker, skip and scan the next sector. 3/ Change the buffer size from 4KB to 128KB which is the common size of erase block. For the 16MB nor flash, the scanning time is accelerated from about 9s to 1s. Signed-off-by: Baidu Liu --- Changes for V2: - Add detail description for the patch. - Move DEFAULT_EMPTY_SCAN_SIZE to jffs2.h --- fs/jffs2/jffs2_1pass.c | 30 +++++++++++++++++++----------- fs/jffs2/jffs2_nand_1pass.c | 11 +++++------ include/jffs2/jffs2.h | 2 ++ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 5ddc2b9..2077d2f 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -1428,8 +1428,6 @@ dump_dirents(struct b_lists *pL) } #endif -#define DEFAULT_EMPTY_SCAN_SIZE 4096 - static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) { if (sector_size < DEFAULT_EMPTY_SCAN_SIZE) @@ -1449,7 +1447,7 @@ jffs2_1pass_build_lists(struct part_info * part) u32 counterF = 0; u32 counterN = 0; u32 max_totlen = 0; - u32 buf_size = DEFAULT_EMPTY_SCAN_SIZE; + u32 buf_size = 128*1024; char *buf; /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ @@ -1540,14 +1538,17 @@ jffs2_1pass_build_lists(struct part_info * part) /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ ofs = 0; - /* Scan only 4KiB of 0xFF before declaring it's empty */ + /* Scan only EMPTY_SCAN_SIZE of 0xFF before declaring it's empty */ while (ofs < EMPTY_SCAN_SIZE(part->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) ofs += 4; - if (ofs == EMPTY_SCAN_SIZE(part->sector_size)) + if (ofs == EMPTY_SCAN_SIZE(part->sector_size)) { + printf("Block at 0x%08x is empty (erased)\n", sector_ofs); continue; + } + /* Now ofs is a complete physical flash offset as it always was... */ ofs += sector_ofs; prevofs = ofs - 1; @@ -1575,16 +1576,14 @@ jffs2_1pass_build_lists(struct part_info * part) if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { uint32_t inbuf_ofs; - uint32_t empty_start, scan_end; + uint32_t empty_start; empty_start = ofs; ofs += 4; - scan_end = min_t(uint32_t, EMPTY_SCAN_SIZE( - part->sector_size)/8, - buf_len); + more_empty: inbuf_ofs = ofs - buf_ofs; - while (inbuf_ofs < scan_end) { + while (inbuf_ofs < buf_len) { if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) goto scan_more; @@ -1594,6 +1593,15 @@ jffs2_1pass_build_lists(struct part_info * part) } /* Ran off end. */ + /* If we're only checking the beginning of a block with a cleanmarker, + bail now */ + if((buf_ofs == sector_ofs) && + (empty_start == sector_ofs +sizeof(struct jffs2_unknown_node))) { + printf("%d bytes at start of block seems clean... assuming all clean\n", + EMPTY_SCAN_SIZE(part->sector_size)); + break; + } + /* See how much more there is to read in this * eraseblock... */ @@ -1608,12 +1616,12 @@ jffs2_1pass_build_lists(struct part_info * part) */ break; } - scan_end = buf_len; get_fl_mem((u32)part->offset + ofs, buf_len, buf); buf_ofs = ofs; goto more_empty; } + if (node->magic != JFFS2_MAGIC_BITMASK || !hdr_crc(node)) { ofs += 4; diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c index 740f787..6d205c1 100644 --- a/fs/jffs2/jffs2_nand_1pass.c +++ b/fs/jffs2/jffs2_nand_1pass.c @@ -779,7 +779,6 @@ jffs2_fill_scan_buf(nand_info_t *nand, unsigned char *buf, return 0; } -#define EMPTY_SCAN_SIZE 1024 static u32 jffs2_1pass_build_lists(struct part_info * part) { @@ -816,17 +815,17 @@ jffs2_1pass_build_lists(struct part_info * part) if (nand_block_isbad(nand, offset)) continue; - if (jffs2_fill_scan_buf(nand, buf, offset, EMPTY_SCAN_SIZE)) + if (jffs2_fill_scan_buf(nand, buf, offset, DEFAULT_EMPTY_SCAN_SIZE)) return 0; ofs = 0; - /* Scan only 4KiB of 0xFF before declaring it's empty */ - while (ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) + /* Scan only DEFAULT_EMPTY_SCAN_SIZE of 0xFF before declaring it's empty */ + while (ofs < DEFAULT_EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) ofs += 4; - if (ofs == EMPTY_SCAN_SIZE) + if (ofs == DEFAULT_EMPTY_SCAN_SIZE) continue; - if (jffs2_fill_scan_buf(nand, buf + EMPTY_SCAN_SIZE, offset + EMPTY_SCAN_SIZE, sectorsize - EMPTY_SCAN_SIZE)) + if (jffs2_fill_scan_buf(nand, buf + DEFAULT_EMPTY_SCAN_SIZE, offset + DEFAULT_EMPTY_SCAN_SIZE, sectorsize - DEFAULT_EMPTY_SCAN_SIZE)) return 0; offset += ofs; diff --git a/include/jffs2/jffs2.h b/include/jffs2/jffs2.h index 651f94c..75c68b8 100644 --- a/include/jffs2/jffs2.h +++ b/include/jffs2/jffs2.h @@ -41,6 +41,8 @@ #include #include +#define DEFAULT_EMPTY_SCAN_SIZE 256 + #define JFFS2_SUPER_MAGIC 0x72b6 /* Values we may expect to find in the 'magic' field */