[U-Boot] [PATCH 3/8] JFFS2: Only list each directory entry once
Heiko Schocher denx
hs at denx.de
Tue Jun 30 11:07:46 CEST 2015
Hello Mark,
Am 29.06.2015 um 07:02 schrieb Mark Tomlinson:
> If multiple versions of a file exist, only the most recent version
> should be used. The scheme to write 0 for the inode in older versions
> did not work, since this would have required writing to flash.
>
> The only time this caused an issue was listing a directory, where older
> versions of the file would still be seen. Since the directory entries
> are sorted, just look at the next entry in the list, and if it's the same
> move to that entry instead.
>
> Signed-off-by: Mark Tomlinson <mark.tomlinson at alliedtelesis.co.nz>
> ---
>
> fs/jffs2/jffs2_1pass.c | 37 ++++++++++++++++++++++++++++++++-----
> 1 file changed, 32 insertions(+), 5 deletions(-)
Reviewed-by: Heiko Schocher <hs at denx.de>
bye,
Heiko
>
> diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
> index 079bb73..1f6eea7 100644
> --- a/fs/jffs2/jffs2_1pass.c
> +++ b/fs/jffs2/jffs2_1pass.c
> @@ -840,7 +840,6 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)
> jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
> pL->readbuf);
> if ((pino == jDir->pino) && (len == jDir->nsize) &&
> - (jDir->ino) && /* 0 for unlink */
> (!strncmp((char *)jDir->name, name, len))) { /* a match */
> if (jDir->version < version) {
> put_fl_mem(jDir, pL->readbuf);
> @@ -961,13 +960,42 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
> for (b = pL->dir.listHead; b; b = b->next) {
> jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset,
> pL->readbuf);
> - if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */
> + if (pino == jDir->pino) {
> u32 i_version = 0;
> struct jffs2_raw_inode ojNode;
> struct jffs2_raw_inode *jNode, *i = NULL;
> - struct b_node *b2 = pL->frag.listHead;
> + struct b_node *b2;
>
> - while (b2) {
> +#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS
> + /* Check for more recent versions of this file */
> + int match;
> + do {
> + struct b_node *next = b->next;
> + struct jffs2_raw_dirent *jDirNext;
> + if (!next)
> + break;
> + jDirNext = (struct jffs2_raw_dirent *)
> + get_node_mem(next->offset, NULL);
> + match = jDirNext->pino == jDir->pino &&
> + jDirNext->nsize == jDir->nsize &&
> + strncmp((char *)jDirNext->name,
> + (char *)jDir->name,
> + jDir->nsize) == 0;
> + if (match) {
> + /* Use next. It is more recent */
> + b = next;
> + /* Update buffer with the new info */
> + *jDir = *jDirNext;
> + put_fl_mem(jDirNext, NULL);
> + }
> + } while (match);
> +#endif
> + if (jDir->ino == 0) {
> + /* Deleted file */
> + continue;
> + }
> +
> + for (b2 = pL->frag.listHead; b2; b2 = b2->next) {
> jNode = (struct jffs2_raw_inode *)
> get_fl_mem(b2->offset, sizeof(ojNode), &ojNode);
> if (jNode->ino == jDir->ino && jNode->version >= i_version) {
> @@ -983,7 +1011,6 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)
> sizeof(*i),
> NULL);
> }
> - b2 = b2->next;
> }
>
> dump_inode(pL, jDir, i);
>
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
More information about the U-Boot
mailing list