aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/build.c')
-rw-r--r--fs/jffs2/build.c171
1 files changed, 86 insertions, 85 deletions
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 97dc39796e2c..fff108bb118b 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $ 10 * $Id: build.c,v 1.85 2005/11/07 11:14:38 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -18,7 +18,8 @@
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include "nodelist.h" 19#include "nodelist.h"
20 20
21static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **); 21static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
22 struct jffs2_inode_cache *, struct jffs2_full_dirent **);
22 23
23static inline struct jffs2_inode_cache * 24static inline struct jffs2_inode_cache *
24first_inode_chain(int *i, struct jffs2_sb_info *c) 25first_inode_chain(int *i, struct jffs2_sb_info *c)
@@ -46,11 +47,12 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
46 ic = next_inode(&i, ic, (c))) 47 ic = next_inode(&i, ic, (c)))
47 48
48 49
49static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 50static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
51 struct jffs2_inode_cache *ic)
50{ 52{
51 struct jffs2_full_dirent *fd; 53 struct jffs2_full_dirent *fd;
52 54
53 D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino)); 55 dbg_fsbuild("building directory inode #%u\n", ic->ino);
54 56
55 /* For each child, increase nlink */ 57 /* For each child, increase nlink */
56 for(fd = ic->scan_dents; fd; fd = fd->next) { 58 for(fd = ic->scan_dents; fd; fd = fd->next) {
@@ -58,26 +60,23 @@ static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2
58 if (!fd->ino) 60 if (!fd->ino)
59 continue; 61 continue;
60 62
61 /* XXX: Can get high latency here with huge directories */ 63 /* we can get high latency here with huge directories */
62 64
63 child_ic = jffs2_get_ino_cache(c, fd->ino); 65 child_ic = jffs2_get_ino_cache(c, fd->ino);
64 if (!child_ic) { 66 if (!child_ic) {
65 printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n", 67 dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
66 fd->name, fd->ino, ic->ino); 68 fd->name, fd->ino, ic->ino);
67 jffs2_mark_node_obsolete(c, fd->raw); 69 jffs2_mark_node_obsolete(c, fd->raw);
68 continue; 70 continue;
69 } 71 }
70 72
71 if (child_ic->nlink++ && fd->type == DT_DIR) { 73 if (child_ic->nlink++ && fd->type == DT_DIR) {
72 printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino); 74 JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
73 if (fd->ino == 1 && ic->ino == 1) { 75 fd->name, fd->ino, ic->ino);
74 printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n"); 76 /* TODO: What do we do about it? */
75 printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
76 }
77 /* What do we do about it? */
78 } 77 }
79 D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino)); 78 dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
80 /* Can't free them. We might need them in pass 2 */ 79 /* Can't free scan_dents so far. We might need them in pass 2 */
81 } 80 }
82} 81}
83 82
@@ -94,6 +93,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
94 struct jffs2_full_dirent *fd; 93 struct jffs2_full_dirent *fd;
95 struct jffs2_full_dirent *dead_fds = NULL; 94 struct jffs2_full_dirent *dead_fds = NULL;
96 95
96 dbg_fsbuild("build FS data structures\n");
97
97 /* First, scan the medium and build all the inode caches with 98 /* First, scan the medium and build all the inode caches with
98 lists of physical nodes */ 99 lists of physical nodes */
99 100
@@ -103,60 +104,54 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
103 if (ret) 104 if (ret)
104 goto exit; 105 goto exit;
105 106
106 D1(printk(KERN_DEBUG "Scanned flash completely\n")); 107 dbg_fsbuild("scanned flash completely\n");
107 D2(jffs2_dump_block_lists(c)); 108 jffs2_dbg_dump_block_lists_nolock(c);
108 109
110 dbg_fsbuild("pass 1 starting\n");
109 c->flags |= JFFS2_SB_FLAG_BUILDING; 111 c->flags |= JFFS2_SB_FLAG_BUILDING;
110 /* Now scan the directory tree, increasing nlink according to every dirent found. */ 112 /* Now scan the directory tree, increasing nlink according to every dirent found. */
111 for_each_inode(i, c, ic) { 113 for_each_inode(i, c, ic) {
112 D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
113
114 D1(BUG_ON(ic->ino > c->highest_ino));
115
116 if (ic->scan_dents) { 114 if (ic->scan_dents) {
117 jffs2_build_inode_pass1(c, ic); 115 jffs2_build_inode_pass1(c, ic);
118 cond_resched(); 116 cond_resched();
119 } 117 }
120 } 118 }
121 119
122 D1(printk(KERN_DEBUG "Pass 1 complete\n")); 120 dbg_fsbuild("pass 1 complete\n");
123 121
124 /* Next, scan for inodes with nlink == 0 and remove them. If 122 /* Next, scan for inodes with nlink == 0 and remove them. If
125 they were directories, then decrement the nlink of their 123 they were directories, then decrement the nlink of their
126 children too, and repeat the scan. As that's going to be 124 children too, and repeat the scan. As that's going to be
127 a fairly uncommon occurrence, it's not so evil to do it this 125 a fairly uncommon occurrence, it's not so evil to do it this
128 way. Recursion bad. */ 126 way. Recursion bad. */
129 D1(printk(KERN_DEBUG "Pass 2 starting\n")); 127 dbg_fsbuild("pass 2 starting\n");
130 128
131 for_each_inode(i, c, ic) { 129 for_each_inode(i, c, ic) {
132 D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes));
133 if (ic->nlink) 130 if (ic->nlink)
134 continue; 131 continue;
135 132
136 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); 133 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
137 cond_resched(); 134 cond_resched();
138 } 135 }
139 136
140 D1(printk(KERN_DEBUG "Pass 2a starting\n")); 137 dbg_fsbuild("pass 2a starting\n");
141 138
142 while (dead_fds) { 139 while (dead_fds) {
143 fd = dead_fds; 140 fd = dead_fds;
144 dead_fds = fd->next; 141 dead_fds = fd->next;
145 142
146 ic = jffs2_get_ino_cache(c, fd->ino); 143 ic = jffs2_get_ino_cache(c, fd->ino);
147 D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic));
148 144
149 if (ic) 145 if (ic)
150 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); 146 jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
151 jffs2_free_full_dirent(fd); 147 jffs2_free_full_dirent(fd);
152 } 148 }
153 149
154 D1(printk(KERN_DEBUG "Pass 2 complete\n")); 150 dbg_fsbuild("pass 2a complete\n");
155 151 dbg_fsbuild("freeing temporary data structures\n");
152
156 /* Finally, we can scan again and free the dirent structs */ 153 /* Finally, we can scan again and free the dirent structs */
157 for_each_inode(i, c, ic) { 154 for_each_inode(i, c, ic) {
158 D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
159
160 while(ic->scan_dents) { 155 while(ic->scan_dents) {
161 fd = ic->scan_dents; 156 fd = ic->scan_dents;
162 ic->scan_dents = fd->next; 157 ic->scan_dents = fd->next;
@@ -166,9 +161,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
166 cond_resched(); 161 cond_resched();
167 } 162 }
168 c->flags &= ~JFFS2_SB_FLAG_BUILDING; 163 c->flags &= ~JFFS2_SB_FLAG_BUILDING;
169 164
170 D1(printk(KERN_DEBUG "Pass 3 complete\n")); 165 dbg_fsbuild("FS build complete\n");
171 D2(jffs2_dump_block_lists(c));
172 166
173 /* Rotate the lists by some number to ensure wear levelling */ 167 /* Rotate the lists by some number to ensure wear levelling */
174 jffs2_rotate_lists(c); 168 jffs2_rotate_lists(c);
@@ -189,24 +183,26 @@ exit:
189 return ret; 183 return ret;
190} 184}
191 185
192static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds) 186static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
187 struct jffs2_inode_cache *ic,
188 struct jffs2_full_dirent **dead_fds)
193{ 189{
194 struct jffs2_raw_node_ref *raw; 190 struct jffs2_raw_node_ref *raw;
195 struct jffs2_full_dirent *fd; 191 struct jffs2_full_dirent *fd;
196 192
197 D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino)); 193 dbg_fsbuild("removing ino #%u with nlink == zero.\n", ic->ino);
198 194
199 raw = ic->nodes; 195 raw = ic->nodes;
200 while (raw != (void *)ic) { 196 while (raw != (void *)ic) {
201 struct jffs2_raw_node_ref *next = raw->next_in_ino; 197 struct jffs2_raw_node_ref *next = raw->next_in_ino;
202 D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw))); 198 dbg_fsbuild("obsoleting node at 0x%08x\n", ref_offset(raw));
203 jffs2_mark_node_obsolete(c, raw); 199 jffs2_mark_node_obsolete(c, raw);
204 raw = next; 200 raw = next;
205 } 201 }
206 202
207 if (ic->scan_dents) { 203 if (ic->scan_dents) {
208 int whinged = 0; 204 int whinged = 0;
209 D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino)); 205 dbg_fsbuild("inode #%u was a directory which may have children...\n", ic->ino);
210 206
211 while(ic->scan_dents) { 207 while(ic->scan_dents) {
212 struct jffs2_inode_cache *child_ic; 208 struct jffs2_inode_cache *child_ic;
@@ -216,45 +212,43 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jf
216 212
217 if (!fd->ino) { 213 if (!fd->ino) {
218 /* It's a deletion dirent. Ignore it */ 214 /* It's a deletion dirent. Ignore it */
219 D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name)); 215 dbg_fsbuild("child \"%s\" is a deletion dirent, skipping...\n", fd->name);
220 jffs2_free_full_dirent(fd); 216 jffs2_free_full_dirent(fd);
221 continue; 217 continue;
222 } 218 }
223 if (!whinged) { 219 if (!whinged)
224 whinged = 1; 220 whinged = 1;
225 printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
226 }
227 221
228 D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n", 222 dbg_fsbuild("removing child \"%s\", ino #%u\n", fd->name, fd->ino);
229 fd->name, fd->ino)); 223
230
231 child_ic = jffs2_get_ino_cache(c, fd->ino); 224 child_ic = jffs2_get_ino_cache(c, fd->ino);
232 if (!child_ic) { 225 if (!child_ic) {
233 printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino); 226 dbg_fsbuild("cannot remove child \"%s\", ino #%u, because it doesn't exist\n",
227 fd->name, fd->ino);
234 jffs2_free_full_dirent(fd); 228 jffs2_free_full_dirent(fd);
235 continue; 229 continue;
236 } 230 }
237 231
238 /* Reduce nlink of the child. If it's now zero, stick it on the 232 /* Reduce nlink of the child. If it's now zero, stick it on the
239 dead_fds list to be cleaned up later. Else just free the fd */ 233 dead_fds list to be cleaned up later. Else just free the fd */
240 234
241 child_ic->nlink--; 235 child_ic->nlink--;
242 236
243 if (!child_ic->nlink) { 237 if (!child_ic->nlink) {
244 D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n", 238 dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n",
245 fd->ino, fd->name)); 239 fd->ino, fd->name);
246 fd->next = *dead_fds; 240 fd->next = *dead_fds;
247 *dead_fds = fd; 241 *dead_fds = fd;
248 } else { 242 } else {
249 D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", 243 dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
250 fd->ino, fd->name, child_ic->nlink)); 244 fd->ino, fd->name, child_ic->nlink);
251 jffs2_free_full_dirent(fd); 245 jffs2_free_full_dirent(fd);
252 } 246 }
253 } 247 }
254 } 248 }
255 249
256 /* 250 /*
257 We don't delete the inocache from the hash list and free it yet. 251 We don't delete the inocache from the hash list and free it yet.
258 The erase code will do that, when all the nodes are completely gone. 252 The erase code will do that, when all the nodes are completely gone.
259 */ 253 */
260} 254}
@@ -268,7 +262,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
268 because there's not enough free space... */ 262 because there's not enough free space... */
269 c->resv_blocks_deletion = 2; 263 c->resv_blocks_deletion = 2;
270 264
271 /* Be conservative about how much space we need before we allow writes. 265 /* Be conservative about how much space we need before we allow writes.
272 On top of that which is required for deletia, require an extra 2% 266 On top of that which is required for deletia, require an extra 2%
273 of the medium to be available, for overhead caused by nodes being 267 of the medium to be available, for overhead caused by nodes being
274 split across blocks, etc. */ 268 split across blocks, etc. */
@@ -283,7 +277,7 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
283 277
284 c->resv_blocks_gctrigger = c->resv_blocks_write + 1; 278 c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
285 279
286 /* When do we allow garbage collection to merge nodes to make 280 /* When do we allow garbage collection to merge nodes to make
287 long-term progress at the expense of short-term space exhaustion? */ 281 long-term progress at the expense of short-term space exhaustion? */
288 c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1; 282 c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
289 283
@@ -295,45 +289,45 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
295 trying to GC to make more space. It'll be a fruitless task */ 289 trying to GC to make more space. It'll be a fruitless task */
296 c->nospc_dirty_size = c->sector_size + (c->flash_size / 100); 290 c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
297 291
298 D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n", 292 dbg_fsbuild("JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
299 c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks)); 293 c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks);
300 D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n", 294 dbg_fsbuild("Blocks required to allow deletion: %d (%d KiB)\n",
301 c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024)); 295 c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024);
302 D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n", 296 dbg_fsbuild("Blocks required to allow writes: %d (%d KiB)\n",
303 c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024)); 297 c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024);
304 D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n", 298 dbg_fsbuild("Blocks required to quiesce GC thread: %d (%d KiB)\n",
305 c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024)); 299 c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024);
306 D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n", 300 dbg_fsbuild("Blocks required to allow GC merges: %d (%d KiB)\n",
307 c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024)); 301 c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024);
308 D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n", 302 dbg_fsbuild("Blocks required to GC bad blocks: %d (%d KiB)\n",
309 c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024)); 303 c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
310 D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n", 304 dbg_fsbuild("Amount of dirty space required to GC: %d bytes\n",
311 c->nospc_dirty_size)); 305 c->nospc_dirty_size);
312} 306}
313 307
314int jffs2_do_mount_fs(struct jffs2_sb_info *c) 308int jffs2_do_mount_fs(struct jffs2_sb_info *c)
315{ 309{
310 int ret;
316 int i; 311 int i;
312 int size;
317 313
318 c->free_size = c->flash_size; 314 c->free_size = c->flash_size;
319 c->nr_blocks = c->flash_size / c->sector_size; 315 c->nr_blocks = c->flash_size / c->sector_size;
320 if (c->mtd->flags & MTD_NO_VIRTBLOCKS) 316 size = sizeof(struct jffs2_eraseblock) * c->nr_blocks;
321 c->blocks = vmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks); 317#ifndef __ECOS
318 if (jffs2_blocks_use_vmalloc(c))
319 c->blocks = vmalloc(size);
322 else 320 else
323 c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL); 321#endif
322 c->blocks = kmalloc(size, GFP_KERNEL);
324 if (!c->blocks) 323 if (!c->blocks)
325 return -ENOMEM; 324 return -ENOMEM;
325
326 memset(c->blocks, 0, size);
326 for (i=0; i<c->nr_blocks; i++) { 327 for (i=0; i<c->nr_blocks; i++) {
327 INIT_LIST_HEAD(&c->blocks[i].list); 328 INIT_LIST_HEAD(&c->blocks[i].list);
328 c->blocks[i].offset = i * c->sector_size; 329 c->blocks[i].offset = i * c->sector_size;
329 c->blocks[i].free_size = c->sector_size; 330 c->blocks[i].free_size = c->sector_size;
330 c->blocks[i].dirty_size = 0;
331 c->blocks[i].wasted_size = 0;
332 c->blocks[i].unchecked_size = 0;
333 c->blocks[i].used_size = 0;
334 c->blocks[i].first_node = NULL;
335 c->blocks[i].last_node = NULL;
336 c->blocks[i].bad_count = 0;
337 } 331 }
338 332
339 INIT_LIST_HEAD(&c->clean_list); 333 INIT_LIST_HEAD(&c->clean_list);
@@ -348,16 +342,23 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
348 INIT_LIST_HEAD(&c->bad_list); 342 INIT_LIST_HEAD(&c->bad_list);
349 INIT_LIST_HEAD(&c->bad_used_list); 343 INIT_LIST_HEAD(&c->bad_used_list);
350 c->highest_ino = 1; 344 c->highest_ino = 1;
345 c->summary = NULL;
346
347 ret = jffs2_sum_init(c);
348 if (ret)
349 return ret;
351 350
352 if (jffs2_build_filesystem(c)) { 351 if (jffs2_build_filesystem(c)) {
353 D1(printk(KERN_DEBUG "build_fs failed\n")); 352 dbg_fsbuild("build_fs failed\n");
354 jffs2_free_ino_caches(c); 353 jffs2_free_ino_caches(c);
355 jffs2_free_raw_node_refs(c); 354 jffs2_free_raw_node_refs(c);
356 if (c->mtd->flags & MTD_NO_VIRTBLOCKS) { 355#ifndef __ECOS
356 if (jffs2_blocks_use_vmalloc(c))
357 vfree(c->blocks); 357 vfree(c->blocks);
358 } else { 358 else
359#endif
359 kfree(c->blocks); 360 kfree(c->blocks);
360 } 361
361 return -EIO; 362 return -EIO;
362 } 363 }
363 364