Blame view

fs/jffs2/build.c 12.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   * JFFS2 -- Journalling Flash File System, Version 2.
   *
c00c310ea   David Woodhouse   [JFFS2] Tidy up l...
4
   * Copyright © 2001-2007 Red Hat, Inc.
6088c0587   David Woodhouse   jffs2: Update cop...
5
   * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
   *
   * Created by David Woodhouse <dwmw2@infradead.org>
   *
   * For licensing information, see the file 'LICENCE' in this directory.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
   */
5a528957e   Joe Perches   jffs2: Use pr_fmt...
12
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
  #include <linux/kernel.h>
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/vmalloc.h>
  #include <linux/mtd/mtd.h>
1d5cfdb07   Tetsuo Handa   tree wide: use kv...
18
  #include <linux/mm.h> /* kvfree() */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  #include "nodelist.h"
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
20
21
  static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
  		struct jffs2_inode_cache *, struct jffs2_full_dirent **);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
  
  static inline struct jffs2_inode_cache *
  first_inode_chain(int *i, struct jffs2_sb_info *c)
  {
65e5a0e18   Daniel Drake   jffs2: Dynamicall...
26
  	for (; *i < c->inocache_hashsize; (*i)++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  		if (c->inocache_list[*i])
  			return c->inocache_list[*i];
  	}
  	return NULL;
  }
  
  static inline struct jffs2_inode_cache *
  next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
  {
  	/* More in this chain? */
  	if (ic->next)
  		return ic->next;
  	(*i)++;
  	return first_inode_chain(i, c);
  }
  
  #define for_each_inode(i, c, ic)			\
  	for (i = 0, ic = first_inode_chain(&i, (c));	\
  	     ic;					\
  	     ic = next_inode(&i, ic, (c)))
858119e15   Arjan van de Ven   [PATCH] Unlinline...
47
  static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
be629c62a   David Woodhouse   Fix directory har...
48
49
  				    struct jffs2_inode_cache *ic,
  				    int *dir_hardlinks)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
  {
  	struct jffs2_full_dirent *fd;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
52
53
  	dbg_fsbuild("building directory inode #%u
  ", ic->ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
59
  
  	/* For each child, increase nlink */
  	for(fd = ic->scan_dents; fd; fd = fd->next) {
  		struct jffs2_inode_cache *child_ic;
  		if (!fd->ino)
  			continue;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
60
  		/* we can get high latency here with huge directories */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
  
  		child_ic = jffs2_get_ino_cache(c, fd->ino);
  		if (!child_ic) {
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
64
65
  			dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
  				  fd->name, fd->ino, ic->ino);
  			jffs2_mark_node_obsolete(c, fd->raw);
be629c62a   David Woodhouse   Fix directory har...
68
69
  			/* Clear the ic/raw union so it doesn't cause problems later. */
  			fd->ic = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  			continue;
  		}
be629c62a   David Woodhouse   Fix directory har...
72
73
74
75
76
  		/* From this point, fd->raw is no longer used so we can set fd->ic */
  		fd->ic = child_ic;
  		child_ic->pino_nlink++;
  		/* If we appear (at this stage) to have hard-linked directories,
  		 * set a flag to trigger a scan later */
27c72b040   David Woodhouse   [JFFS2] Track par...
77
  		if (fd->type == DT_DIR) {
be629c62a   David Woodhouse   Fix directory har...
78
79
80
81
  			child_ic->flags |= INO_FLAGS_IS_DIR;
  			if (child_ic->pino_nlink > 1)
  				*dir_hardlinks = 1;
  		}
27c72b040   David Woodhouse   [JFFS2] Track par...
82

733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
83
84
85
  		dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)
  ", fd->name, fd->ino);
  		/* Can't free scan_dents so far. We might need them in pass 2 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
91
92
93
94
95
  	}
  }
  
  /* Scan plan:
   - Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we go
   - Scan directory tree from top down, setting nlink in inocaches
   - Scan inocaches for inodes with nlink==0
  */
  static int jffs2_build_filesystem(struct jffs2_sb_info *c)
  {
be629c62a   David Woodhouse   Fix directory har...
96
  	int ret, i, dir_hardlinks = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
  	struct jffs2_inode_cache *ic;
  	struct jffs2_full_dirent *fd;
  	struct jffs2_full_dirent *dead_fds = NULL;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
100
101
  	dbg_fsbuild("build FS data structures
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
  	/* First, scan the medium and build all the inode caches with
  	   lists of physical nodes */
31fbdf7aa   Artem B. Bityuckiy   [JFFS2] Fix NOR s...
104
  	c->flags |= JFFS2_SB_FLAG_SCANNING;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
  	ret = jffs2_scan_medium(c);
31fbdf7aa   Artem B. Bityuckiy   [JFFS2] Fix NOR s...
106
  	c->flags &= ~JFFS2_SB_FLAG_SCANNING;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
  	if (ret)
  		goto exit;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
109
110
  	dbg_fsbuild("scanned flash completely
  ");
e0c8e42f8   Artem B. Bityutskiy   [JFFS2] Debug cod...
111
  	jffs2_dbg_dump_block_lists_nolock(c);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112

733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
113
114
  	dbg_fsbuild("pass 1 starting
  ");
31fbdf7aa   Artem B. Bityuckiy   [JFFS2] Fix NOR s...
115
  	c->flags |= JFFS2_SB_FLAG_BUILDING;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
  	/* Now scan the directory tree, increasing nlink according to every dirent found. */
  	for_each_inode(i, c, ic) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  		if (ic->scan_dents) {
be629c62a   David Woodhouse   Fix directory har...
119
  			jffs2_build_inode_pass1(c, ic, &dir_hardlinks);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
  			cond_resched();
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123

733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
124
125
  	dbg_fsbuild("pass 1 complete
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
127
128
129
130
131
  
  	/* Next, scan for inodes with nlink == 0 and remove them. If
  	   they were directories, then decrement the nlink of their
  	   children too, and repeat the scan. As that's going to be
  	   a fairly uncommon occurrence, it's not so evil to do it this
  	   way. Recursion bad. */
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
132
133
  	dbg_fsbuild("pass 2 starting
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
  
  	for_each_inode(i, c, ic) {
27c72b040   David Woodhouse   [JFFS2] Track par...
136
  		if (ic->pino_nlink)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
  			continue;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
138

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
  		jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
  		cond_resched();
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
141
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142

733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
143
144
  	dbg_fsbuild("pass 2a starting
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
149
150
  
  	while (dead_fds) {
  		fd = dead_fds;
  		dead_fds = fd->next;
  
  		ic = jffs2_get_ino_cache(c, fd->ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
  
  		if (ic)
  			jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
  		jffs2_free_full_dirent(fd);
  	}
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
156
157
  	dbg_fsbuild("pass 2a complete
  ");
be629c62a   David Woodhouse   Fix directory har...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  
  	if (dir_hardlinks) {
  		/* If we detected directory hardlinks earlier, *hopefully*
  		 * they are gone now because some of the links were from
  		 * dead directories which still had some old dirents lying
  		 * around and not yet garbage-collected, but which have
  		 * been discarded above. So clear the pino_nlink field
  		 * in each directory, so that the final scan below can
  		 * print appropriate warnings. */
  		for_each_inode(i, c, ic) {
  			if (ic->flags & INO_FLAGS_IS_DIR)
  				ic->pino_nlink = 0;
  		}
  	}
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
172
173
  	dbg_fsbuild("freeing temporary data structures
  ");
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
174

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
  	/* Finally, we can scan again and free the dirent structs */
  	for_each_inode(i, c, ic) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
  		while(ic->scan_dents) {
  			fd = ic->scan_dents;
  			ic->scan_dents = fd->next;
be629c62a   David Woodhouse   Fix directory har...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  			/* We do use the pino_nlink field to count nlink of
  			 * directories during fs build, so set it to the
  			 * parent ino# now. Now that there's hopefully only
  			 * one. */
  			if (fd->type == DT_DIR) {
  				if (!fd->ic) {
  					/* We'll have complained about it and marked the coresponding
  					   raw node obsolete already. Just skip it. */
  					continue;
  				}
  
  				/* We *have* to have set this in jffs2_build_inode_pass1() */
  				BUG_ON(!(fd->ic->flags & INO_FLAGS_IS_DIR));
  
  				/* We clear ic->pino_nlink ∀ directories' ic *only* if dir_hardlinks
  				 * is set. Otherwise, we know this should never trigger anyway, so
  				 * we don't do the check. And ic->pino_nlink still contains the nlink
  				 * value (which is 1). */
  				if (dir_hardlinks && fd->ic->pino_nlink) {
  					JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u is also hard linked from dir ino #%u
  ",
  						    fd->name, fd->ino, ic->ino, fd->ic->pino_nlink);
  					/* Should we unlink it from its previous parent? */
  				}
  
  				/* For directories, ic->pino_nlink holds that parent inode # */
  				fd->ic->pino_nlink = ic->ino;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
211
212
  			jffs2_free_full_dirent(fd);
  		}
  		ic->scan_dents = NULL;
  		cond_resched();
  	}
aa98d7cf5   KaiGai Kohei   [JFFS2][XATTR] XA...
213
  	jffs2_build_xattr_subsystem(c);
31fbdf7aa   Artem B. Bityuckiy   [JFFS2] Fix NOR s...
214
  	c->flags &= ~JFFS2_SB_FLAG_BUILDING;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
215

733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
216
217
  	dbg_fsbuild("FS build complete
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  
  	/* Rotate the lists by some number to ensure wear levelling */
  	jffs2_rotate_lists(c);
  
  	ret = 0;
  
  exit:
  	if (ret) {
  		for_each_inode(i, c, ic) {
  			while(ic->scan_dents) {
  				fd = ic->scan_dents;
  				ic->scan_dents = fd->next;
  				jffs2_free_full_dirent(fd);
  			}
  		}
aa98d7cf5   KaiGai Kohei   [JFFS2][XATTR] XA...
233
  		jffs2_clear_xattr_subsystem(c);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
  	}
  
  	return ret;
  }
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
238
239
240
  static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
  					struct jffs2_inode_cache *ic,
  					struct jffs2_full_dirent **dead_fds)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
243
  {
  	struct jffs2_raw_node_ref *raw;
  	struct jffs2_full_dirent *fd;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
244
245
  	dbg_fsbuild("removing ino #%u with nlink == zero.
  ", ic->ino);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
246

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
249
  	raw = ic->nodes;
  	while (raw != (void *)ic) {
  		struct jffs2_raw_node_ref *next = raw->next_in_ino;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
250
251
  		dbg_fsbuild("obsoleting node at 0x%08x
  ", ref_offset(raw));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
257
  		jffs2_mark_node_obsolete(c, raw);
  		raw = next;
  	}
  
  	if (ic->scan_dents) {
  		int whinged = 0;
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
258
259
  		dbg_fsbuild("inode #%u was a directory which may have children...
  ", ic->ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
262
263
264
265
266
267
268
  
  		while(ic->scan_dents) {
  			struct jffs2_inode_cache *child_ic;
  
  			fd = ic->scan_dents;
  			ic->scan_dents = fd->next;
  
  			if (!fd->ino) {
  				/* It's a deletion dirent. Ignore it */
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
269
270
  				dbg_fsbuild("child \"%s\" is a deletion dirent, skipping...
  ", fd->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
273
  				jffs2_free_full_dirent(fd);
  				continue;
  			}
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
274
  			if (!whinged)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  				whinged = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276

733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
277
278
  			dbg_fsbuild("removing child \"%s\", ino #%u
  ", fd->name, fd->ino);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
279

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
  			child_ic = jffs2_get_ino_cache(c, fd->ino);
  			if (!child_ic) {
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
282
283
284
  				dbg_fsbuild("cannot remove child \"%s\", ino #%u, because it doesn't exist
  ",
  						fd->name, fd->ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
  				jffs2_free_full_dirent(fd);
  				continue;
  			}
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
288
  			/* Reduce nlink of the child. If it's now zero, stick it on the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  			   dead_fds list to be cleaned up later. Else just free the fd */
be629c62a   David Woodhouse   Fix directory har...
290
  			child_ic->pino_nlink--;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
291

27c72b040   David Woodhouse   [JFFS2] Track par...
292
293
294
  			if (!child_ic->pino_nlink) {
  				dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.
  ",
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
295
  					  fd->ino, fd->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
  				fd->next = *dead_fds;
  				*dead_fds = fd;
  			} else {
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
299
300
  				dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.
  ",
27c72b040   David Woodhouse   [JFFS2] Track par...
301
  					  fd->ino, fd->name, child_ic->pino_nlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
304
305
306
307
  				jffs2_free_full_dirent(fd);
  			}
  		}
  	}
  
  	/*
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
308
  	   We don't delete the inocache from the hash list and free it yet.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
313
314
315
316
317
318
319
320
  	   The erase code will do that, when all the nodes are completely gone.
  	*/
  }
  
  static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
  {
  	uint32_t size;
  
  	/* Deletion should almost _always_ be allowed. We're fairly
  	   buggered once we stop allowing people to delete stuff
  	   because there's not enough free space... */
  	c->resv_blocks_deletion = 2;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
321
  	/* Be conservative about how much space we need before we allow writes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
326
327
328
329
330
331
332
333
334
  	   On top of that which is required for deletia, require an extra 2%
  	   of the medium to be available, for overhead caused by nodes being
  	   split across blocks, etc. */
  
  	size = c->flash_size / 50; /* 2% of flash size */
  	size += c->nr_blocks * 100; /* And 100 bytes per eraseblock */
  	size += c->sector_size - 1; /* ... and round up */
  
  	c->resv_blocks_write = c->resv_blocks_deletion + (size / c->sector_size);
  
  	/* When do we let the GC thread run in the background */
  
  	c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
335
  	/* When do we allow garbage collection to merge nodes to make
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
338
339
340
341
  	   long-term progress at the expense of short-term space exhaustion? */
  	c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
  
  	/* When do we allow garbage collection to eat from bad blocks rather
  	   than actually making progress? */
  	c->resv_blocks_gcbad = 0;//c->resv_blocks_deletion + 2;
8fb870df5   David Woodhouse   [JFFS2] Trigger g...
342
343
344
345
  	/* What number of 'very dirty' eraseblocks do we allow before we
  	   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. */
85becc535   David Woodhouse   [JFFS2] Relax thr...
346
  	c->vdirty_blocks_gctrigger = c->resv_blocks_gctrigger;
8fb870df5   David Woodhouse   [JFFS2] Trigger g...
347
348
  	if (jffs2_can_mark_obsolete(c))
  		c->vdirty_blocks_gctrigger *= 10;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
  	/* If there's less than this amount of dirty space, don't bother
  	   trying to GC to make more space. It'll be a fruitless task */
  	c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
5a528957e   Joe Perches   jffs2: Use pr_fmt...
352
353
354
  	dbg_fsbuild("trigger levels (size %d KiB, block size %d KiB, %d blocks)
  ",
  		    c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks);
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
  	dbg_fsbuild("Blocks required to allow deletion:    %d (%d KiB)
  ",
  		  c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024);
  	dbg_fsbuild("Blocks required to allow writes:      %d (%d KiB)
  ",
  		  c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024);
  	dbg_fsbuild("Blocks required to quiesce GC thread: %d (%d KiB)
  ",
  		  c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024);
  	dbg_fsbuild("Blocks required to allow GC merges:   %d (%d KiB)
  ",
  		  c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024);
  	dbg_fsbuild("Blocks required to GC bad blocks:     %d (%d KiB)
  ",
  		  c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
  	dbg_fsbuild("Amount of dirty space required to GC: %d bytes
  ",
  		  c->nospc_dirty_size);
8fb870df5   David Woodhouse   [JFFS2] Trigger g...
373
374
375
  	dbg_fsbuild("Very dirty blocks before GC triggered: %d
  ",
  		  c->vdirty_blocks_gctrigger);
182ec4eee   Thomas Gleixner   [JFFS2] Clean up ...
376
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
  
  int jffs2_do_mount_fs(struct jffs2_sb_info *c)
  {
c617e8424   Ferenc Havasi   [JFFS2] Return re...
380
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381
  	int i;
d55849aa4   Artem B. Bityutskiy   [JFFS2] Use memse...
382
  	int size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
385
  
  	c->free_size = c->flash_size;
  	c->nr_blocks = c->flash_size / c->sector_size;
d55849aa4   Artem B. Bityutskiy   [JFFS2] Use memse...
386
  	size = sizeof(struct jffs2_eraseblock) * c->nr_blocks;
737b7661e   Andrew Lunn   [JFFS2] Fix up ne...
387
  #ifndef __ECOS
4ce1f5621   Ferenc Havasi   [JFFS2] Remove su...
388
  	if (jffs2_blocks_use_vmalloc(c))
7ddbead6e   Joe Perches   jffs2: use vzalloc
389
  		c->blocks = vzalloc(size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  	else
737b7661e   Andrew Lunn   [JFFS2] Fix up ne...
391
  #endif
7ddbead6e   Joe Perches   jffs2: use vzalloc
392
  		c->blocks = kzalloc(size, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
  	if (!c->blocks)
  		return -ENOMEM;
d55849aa4   Artem B. Bityutskiy   [JFFS2] Use memse...
395

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
397
398
399
  	for (i=0; i<c->nr_blocks; i++) {
  		INIT_LIST_HEAD(&c->blocks[i].list);
  		c->blocks[i].offset = i * c->sector_size;
  		c->blocks[i].free_size = c->sector_size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
405
  	INIT_LIST_HEAD(&c->clean_list);
  	INIT_LIST_HEAD(&c->very_dirty_list);
  	INIT_LIST_HEAD(&c->dirty_list);
  	INIT_LIST_HEAD(&c->erasable_list);
  	INIT_LIST_HEAD(&c->erasing_list);
e2bc322bf   David Woodhouse   [JFFS2] Add erase...
406
  	INIT_LIST_HEAD(&c->erase_checking_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
409
410
411
412
413
  	INIT_LIST_HEAD(&c->erase_pending_list);
  	INIT_LIST_HEAD(&c->erasable_pending_wbuf_list);
  	INIT_LIST_HEAD(&c->erase_complete_list);
  	INIT_LIST_HEAD(&c->free_list);
  	INIT_LIST_HEAD(&c->bad_list);
  	INIT_LIST_HEAD(&c->bad_used_list);
  	c->highest_ino = 1;
e631ddba5   Ferenc Havasi   [JFFS2] Add erase...
414
  	c->summary = NULL;
c617e8424   Ferenc Havasi   [JFFS2] Return re...
415
416
  	ret = jffs2_sum_init(c);
  	if (ret)
cfa72397c   Dmitry Adamushko   JFFS2: memory lea...
417
  		goto out_free;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
  
  	if (jffs2_build_filesystem(c)) {
733802d97   Artem B. Bityutskiy   [JFFS2] Debug cod...
420
421
  		dbg_fsbuild("build_fs failed
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422
423
  		jffs2_free_ino_caches(c);
  		jffs2_free_raw_node_refs(c);
cfa72397c   Dmitry Adamushko   JFFS2: memory lea...
424
425
  		ret = -EIO;
  		goto out_free;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
428
429
430
  	}
  
  	jffs2_calc_trigger_levels(c);
  
  	return 0;
cfa72397c   Dmitry Adamushko   JFFS2: memory lea...
431
432
  
   out_free:
1d5cfdb07   Tetsuo Handa   tree wide: use kv...
433
  	kvfree(c->blocks);
cfa72397c   Dmitry Adamushko   JFFS2: memory lea...
434
435
  
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  }