X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=fs%2Fjffs2%2Fbuild.c;h=a906f538d11ce33d0f9c81e38cbaf95528030638;hb=3e7561636f3f7f9b2942f6f90b021fdaeb0fe0ee;hp=8c27c12816ba4ea131d4d7deb78b828a59fd9b4d;hpb=8fb870df5a1f261294b833dd807bcba3bacface6;p=sfrench%2Fcifs-2.6.git diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c index 8c27c12816ba..a906f538d11c 100644 --- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c @@ -2,6 +2,7 @@ * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright © 2001-2007 Red Hat, Inc. + * Copyright © 2004-2010 David Woodhouse * * Created by David Woodhouse * @@ -46,7 +47,7 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c) static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, - struct jffs2_inode_cache *ic) + struct jffs2_inode_cache *ic) { struct jffs2_full_dirent *fd; @@ -68,11 +69,17 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, continue; } - if (child_ic->nlink++ && fd->type == DT_DIR) { - JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", - fd->name, fd->ino, ic->ino); - /* TODO: What do we do about it? */ - } + if (fd->type == DT_DIR) { + if (child_ic->pino_nlink) { + JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", + fd->name, fd->ino, ic->ino); + /* TODO: What do we do about it? */ + } else { + child_ic->pino_nlink = ic->ino; + } + } else + child_ic->pino_nlink++; + dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino); /* Can't free scan_dents so far. We might need them in pass 2 */ } @@ -125,7 +132,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) dbg_fsbuild("pass 2 starting\n"); for_each_inode(i, c, ic) { - if (ic->nlink) + if (ic->pino_nlink) continue; jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); @@ -232,16 +239,19 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, /* Reduce nlink of the child. If it's now zero, stick it on the dead_fds list to be cleaned up later. Else just free the fd */ - child_ic->nlink--; + if (fd->type == DT_DIR) + child_ic->pino_nlink = 0; + else + child_ic->pino_nlink--; - if (!child_ic->nlink) { - dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n", + if (!child_ic->pino_nlink) { + dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n", fd->ino, fd->name); fd->next = *dead_fds; *dead_fds = fd; } else { dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", - fd->ino, fd->name, child_ic->nlink); + fd->ino, fd->name, child_ic->pino_nlink); jffs2_free_full_dirent(fd); } } @@ -289,7 +299,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c) trigger the GC thread even if we don't _need_ the space. When we can't mark nodes obsolete on the medium, the old dirty nodes cause performance problems because we have to inspect and discard them. */ - c->vdirty_blocks_gctrigger = c->resv_blocks_gcmerge; + c->vdirty_blocks_gctrigger = c->resv_blocks_gctrigger; if (jffs2_can_mark_obsolete(c)) c->vdirty_blocks_gctrigger *= 10; @@ -345,6 +355,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c) INIT_LIST_HEAD(&c->dirty_list); INIT_LIST_HEAD(&c->erasable_list); INIT_LIST_HEAD(&c->erasing_list); + INIT_LIST_HEAD(&c->erase_checking_list); INIT_LIST_HEAD(&c->erase_pending_list); INIT_LIST_HEAD(&c->erasable_pending_wbuf_list); INIT_LIST_HEAD(&c->erase_complete_list);