diff options
Diffstat (limited to 'fs/jffs2/build.c')
-rw-r--r-- | fs/jffs2/build.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c index d58f845ccb85..c5e1450d79f9 100644 --- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c | |||
@@ -46,7 +46,7 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c) | |||
46 | 46 | ||
47 | 47 | ||
48 | static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, | 48 | static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, |
49 | struct jffs2_inode_cache *ic) | 49 | struct jffs2_inode_cache *ic) |
50 | { | 50 | { |
51 | struct jffs2_full_dirent *fd; | 51 | struct jffs2_full_dirent *fd; |
52 | 52 | ||
@@ -68,11 +68,17 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, | |||
68 | continue; | 68 | continue; |
69 | } | 69 | } |
70 | 70 | ||
71 | if (child_ic->nlink++ && fd->type == DT_DIR) { | 71 | if (fd->type == DT_DIR) { |
72 | JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", | 72 | if (child_ic->pino_nlink) { |
73 | fd->name, fd->ino, ic->ino); | 73 | JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", |
74 | /* TODO: What do we do about it? */ | 74 | fd->name, fd->ino, ic->ino); |
75 | } | 75 | /* TODO: What do we do about it? */ |
76 | } else { | ||
77 | child_ic->pino_nlink = ic->ino; | ||
78 | } | ||
79 | } else | ||
80 | child_ic->pino_nlink++; | ||
81 | |||
76 | dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino); | 82 | dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino); |
77 | /* Can't free scan_dents so far. We might need them in pass 2 */ | 83 | /* Can't free scan_dents so far. We might need them in pass 2 */ |
78 | } | 84 | } |
@@ -125,7 +131,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) | |||
125 | dbg_fsbuild("pass 2 starting\n"); | 131 | dbg_fsbuild("pass 2 starting\n"); |
126 | 132 | ||
127 | for_each_inode(i, c, ic) { | 133 | for_each_inode(i, c, ic) { |
128 | if (ic->nlink) | 134 | if (ic->pino_nlink) |
129 | continue; | 135 | continue; |
130 | 136 | ||
131 | jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); | 137 | jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); |
@@ -232,16 +238,19 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, | |||
232 | /* Reduce nlink of the child. If it's now zero, stick it on the | 238 | /* Reduce nlink of the child. If it's now zero, stick it on the |
233 | dead_fds list to be cleaned up later. Else just free the fd */ | 239 | dead_fds list to be cleaned up later. Else just free the fd */ |
234 | 240 | ||
235 | child_ic->nlink--; | 241 | if (fd->type == DT_DIR) |
242 | child_ic->pino_nlink = 0; | ||
243 | else | ||
244 | child_ic->pino_nlink--; | ||
236 | 245 | ||
237 | if (!child_ic->nlink) { | 246 | if (!child_ic->pino_nlink) { |
238 | dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n", | 247 | dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n", |
239 | fd->ino, fd->name); | 248 | fd->ino, fd->name); |
240 | fd->next = *dead_fds; | 249 | fd->next = *dead_fds; |
241 | *dead_fds = fd; | 250 | *dead_fds = fd; |
242 | } else { | 251 | } else { |
243 | dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", | 252 | dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", |
244 | fd->ino, fd->name, child_ic->nlink); | 253 | fd->ino, fd->name, child_ic->pino_nlink); |
245 | jffs2_free_full_dirent(fd); | 254 | jffs2_free_full_dirent(fd); |
246 | } | 255 | } |
247 | } | 256 | } |