[U-Boot-Users] PATCH: Update U-Boot EXT2 Filesystem to support dynamic inode size and optimize ext2 read function to fasten read speed!
Ryan CHEN
ryan.chen at st.com
Wed Jul 30 04:00:18 CEST 2008
Hi Wolfgang,
I have modified my patch according to your suggestion. The only question is
that use debug() because I found all debug print msg lines are written as :
#ifdef DEBUG
printf(......);
#endif
Are you sure I need change my debug print to debug()?
commit 4e638f2b97cea8b256eca7eb098d4da45015e10d
Parent: 699f05125509249072a0b865c8d35520d97cd501
Author: Ryan Chen <ryan.chen at st.com>
Date: Wed Jul 30 05:48:16 2008 -0400
Signed-off-by: Ryan Chen <ryan.chen at st.com>
modified: fs/ext2/ext2fs.c
diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
old mode 100644
new mode 100755
index 7833551..4b01463
--- a/fs/ext2/ext2fs.c
+++ b/fs/ext2/ext2fs.c
@@ -29,6 +29,7 @@
#include <ext2fs.h>
#include <malloc.h>
#include <asm/byteorder.h>
+#define CFG_EXT2_SUPPORT_DYNAMIC_REV
extern int ext2fs_devread (int sector, int byte_offset, int byte_len,
char *buf);
@@ -66,6 +67,17 @@ extern int ext2fs_devread (int sector, int byte_offset,
int byte_len,
/* The size of an ext2 block in bytes. */
#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data))
+#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format
*/
+#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes
*/
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+uint32_t ext2_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+#endif
+
/* The ext2 superblock. */
struct ext2_sblock {
uint32_t total_inodes;
@@ -217,7 +229,11 @@ static int ext2fs_read_inode
if (status == 0) {
return (0);
}
+#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
+ inodes_per_block = EXT2_BLOCK_SIZE (data) / ext2_inode_size;
+#else
inodes_per_block = EXT2_BLOCK_SIZE (data) / 128;
+#endif
blkno = (ino % __le32_to_cpu (sblock->inodes_per_group)) /
inodes_per_block;
blkoff = (ino % __le32_to_cpu (sblock->inodes_per_group)) %
@@ -226,10 +242,17 @@ static int ext2fs_read_inode
printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff);
#endif
/* Read the inode. */
+#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
+ status = ext2fs_devread (((__le32_to_cpu (blkgrp.inode_table_id) +
+ blkno) << LOG2_EXT2_BLOCK_SIZE (data)),
+ ext2_inode_size * blkoff,
+ sizeof (struct ext2_inode), (char *)
inode);
+#else
status = ext2fs_devread (((__le32_to_cpu (blkgrp.inode_table_id) +
blkno) << LOG2_EXT2_BLOCK_SIZE (data)),
sizeof (struct ext2_inode) * blkoff,
sizeof (struct ext2_inode), (char *)
inode);
+#endif
if (status == 0) {
return (0);
}
@@ -243,8 +266,13 @@ void ext2fs_free_node (ext2fs_node_t node,
ext2fs_node_t currroot) {
}
}
+#define CFG_OPTIMIZE_EXT2_READ
+#ifdef CFG_OPTIMIZE_EXT2_READ
+static int ext2fs_read_block (ext2fs_node_t node, int fileblock, int
*stream) {
+#else
static int ext2fs_read_block (ext2fs_node_t node, int fileblock) {
+#endif
struct ext2_data *data = node->data;
struct ext2_inode *inode = &node->inode;
int blknr;
@@ -252,9 +280,21 @@ static int ext2fs_read_block (ext2fs_node_t node, int
fileblock) {
int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
int status;
+#ifdef CFG_OPTIMIZE_EXT2_READ
+ *stream = 1;/* itself */
+#endif
+
/* Direct blocks. */
if (fileblock < INDIRECT_BLOCKS) {
blknr = __le32_to_cpu
(inode->b.blocks.dir_blocks[fileblock]);
+#ifdef CFG_OPTIMIZE_EXT2_READ
+ while(((inode->b.blocks.dir_blocks[fileblock + 1] -
+ inode->b.blocks.dir_blocks[fileblock]) == 1) && \
+ (fileblock < INDIRECT_BLOCKS - 1)) {
+ fileblock++;
+ *stream += 1;
+ }
+#endif
}
/* Indirect. */
else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) {
@@ -294,6 +334,14 @@ static int ext2fs_read_block (ext2fs_node_t node, int
fileblock) {
}
blknr = __le32_to_cpu (indir1_block
[fileblock - INDIRECT_BLOCKS]);
+#ifdef CFG_OPTIMIZE_EXT2_READ
+ while(((__le32_to_cpu (indir1_block[fileblock -
INDIRECT_BLOCKS + 1]) - \
+ __le32_to_cpu (indir1_block[fileblock -
INDIRECT_BLOCKS])) == 1) && \
+ (fileblock < (blksz - 1))) {
+ fileblock++;
+ *stream += 1;
+ }
+#endif
}
/* Double indirect. */
else if (fileblock <
@@ -301,6 +349,9 @@ static int ext2fs_read_block (ext2fs_node_t node, int
fileblock) {
unsigned int perblock = blksz / 4;
unsigned int rblock = fileblock - (INDIRECT_BLOCKS
+ blksz / 4);
+#ifdef CFG_OPTIMIZE_EXT2_READ
+ int rbcnt = 0;
+#endif
if (indir1_block == NULL) {
indir1_block = (uint32_t *) malloc (blksz);
@@ -370,6 +421,15 @@ static int ext2fs_read_block (ext2fs_node_t node, int
fileblock) {
__le32_to_cpu (indir1_block[rblock /
perblock]) << log2_blksz;
}
blknr = __le32_to_cpu (indir2_block[rblock % perblock]);
+#ifdef CFG_OPTIMIZE_EXT2_READ
+ rbcnt = rblock % perblock;
+ while(((__le32_to_cpu (indir2_block[rbcnt + 1]) - \
+ __le32_to_cpu (indir2_block[rbcnt])) == 1) \
+ && (rbcnt < (blksz - 1))) {
+ rbcnt++;
+ *stream += 1;
+ }
+#endif
}
/* Tripple indirect. */
else {
@@ -382,7 +442,57 @@ static int ext2fs_read_block (ext2fs_node_t node, int
fileblock) {
return (blknr);
}
+#ifdef CFG_OPTIMIZE_EXT2_READ
+int ext2fs_read_file
+ (ext2fs_node_t node, int pos, unsigned int len, char *buf) {
+ int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data);
+ int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
+ unsigned int filesize = __le32_to_cpu(node->inode.size);
+ int blknr;
+ int blockend;
+ int status;
+ int remain = len;
+ char *buffer = buf;
+ int stream = 0;
+ int cur = pos / blocksize;
+ int blockoff = pos % blocksize;
+
+ /* Adjust len so it we can't read past the end of the file. */
+ if (len > filesize) {
+ len = filesize;
+ }
+ while (remain > 0) {
+ blknr = ext2fs_read_block (node, cur, &stream);
+ if (blknr < 0) {
+ return (-1);
+ }
+ blknr = blknr << log2blocksize;
+
+ if(remain < blocksize * stream) {
+ blockend = remain;
+ } else {
+ blockend = blocksize * stream;
+ }
+
+ status = ext2fs_devread (blknr, blockoff, blockend, buffer);
+ if (status == 0) {
+ return (-1);
+ }
+
+ remain -= blockend;
+ buffer += blockend;
+ cur += stream;
+ blockoff = 0;
+
+ if(remain == 0)
+ return (len);
+ else if(remain < 0)
+ return (-1);
+ }
+ return (len);
+}
+#else
int ext2fs_read_file
(ext2fs_node_t node, int pos, unsigned int len, char *buf) {
int i;
@@ -442,6 +552,7 @@ int ext2fs_read_file
}
return (len);
}
+#endif
static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t
* fnode, int *ftype)
@@ -854,6 +965,18 @@ int ext2fs_mount (unsigned part_length) {
if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) {
goto fail;
}
+#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
+#ifdef DEBUG
+ printf("revision_level = 0x%x, inode_size = 0x%x\n",
data->sblock.revision_level, \
+ data->sblock.inode_size);
+#endif
+ if (__le32_to_cpu (data->sblock.revision_level) ==
EXT2_GOOD_OLD_REV) {
+ ext2_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+ } else {
+ ext2_inode_size = __le16_to_cpu (data->sblock.inode_size);
+ }
+#endif
+
data->diropen.data = data;
data->diropen.ino = 2;
data->diropen.inode_read = 1;
Best Regards,
Ryan Chen
Best Regards,
Ryan Chen
-----Original Message-----
From: wd at denx.de [mailto:wd at denx.de]
Sent: Wednesday, July 30, 2008 7:17 AM
To: Ryan CHEN
Cc: u-boot-users at lists.sourceforge.net; Antonio Maria BORNEO
Subject: Re: [U-Boot-Users] PATCH: Update U-Boot EXT2 Filesystem to support
dynamic inode size and optimize ext2 read function to fasten read speed!
In message <007301c8f157$ed683f20$30065e0a at SHZ.ST.COM> you wrote:
> Description:
> The patch updates /fs/ext2/ext2fs.c file. There are two aims:
> 1. Make U-Boot could support the EXT2 dynamic version that ext2_inode_size
beyond 128bytes.
> One new feature be involved: CFG_EXT2_SUPPORT_DYNAMIC_REV
> Refer to: linux-2.6.24.3 source code.
> 2. Make EXT2 read more fast.
> One new feature be involved: CFG_OPTIMIZE_EXT2_READ
Do we really need new config options and #ifdeffery for these?
> +++ b/fs/ext2/ext2fs.c
...
> @@ -409,7 +516,7 @@ int ext2fs_read_file
> return (-1);
> }
> blknr = blknr << log2blocksize;
> -
> +
You're adding trailing white space here. Please don't.
> +#ifdef DEBUG
> + printf("revision_level = 0x%x, inode_size = 0x%x\n",
> +data->sblock.revision_level, data->sblock.inode_size); #endif
Use debug() instead of #ifdef
And mind the maximum line length.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Certainly there are things in life that money can't buy, but it's very
funny - Did you ever try buying them without money? - Ogden Nash
More information about the U-Boot
mailing list