[JFFS2] Debug code clean up - step 3
[deliverable/linux.git] / fs / jffs2 / readinode.c
CommitLineData
1da177e4
LT
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
e0c8e42f 10 * $Id: readinode.c,v 1.129 2005/07/22 10:32:08 dedekind Exp $
1da177e4
LT
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/fs.h>
17#include <linux/crc32.h>
18#include <linux/pagemap.h>
19#include <linux/mtd/mtd.h>
20#include <linux/compiler.h>
21#include "nodelist.h"
22
23static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
24
1da177e4
LT
25static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
26{
27 if (this->node) {
28 this->node->frags--;
29 if (!this->node->frags) {
30 /* The node has no valid frags left. It's totally obsoleted */
31 D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
32 ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size));
33 jffs2_mark_node_obsolete(c, this->node->raw);
34 jffs2_free_full_dnode(this->node);
35 } else {
36 D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
37 ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size,
38 this->node->frags));
39 mark_ref_normal(this->node->raw);
40 }
41
42 }
43 jffs2_free_node_frag(this);
44}
45
46/* Given an inode, probably with existing list of fragments, add the new node
47 * to the fragment list.
48 */
49int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
50{
51 int ret;
52 struct jffs2_node_frag *newfrag;
53
54 D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
55
336d2ff7
AB
56 if (unlikely(!fn->size))
57 return 0;
58
1da177e4
LT
59 newfrag = jffs2_alloc_node_frag();
60 if (unlikely(!newfrag))
61 return -ENOMEM;
62
63 D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
64 fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));
65
1da177e4
LT
66 newfrag->ofs = fn->ofs;
67 newfrag->size = fn->size;
68 newfrag->node = fn;
69 newfrag->node->frags = 1;
70
71 ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
72 if (ret)
73 return ret;
74
75 /* If we now share a page with other nodes, mark either previous
76 or next node REF_NORMAL, as appropriate. */
77 if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
78 struct jffs2_node_frag *prev = frag_prev(newfrag);
79
80 mark_ref_normal(fn->raw);
81 /* If we don't start at zero there's _always_ a previous */
82 if (prev->node)
83 mark_ref_normal(prev->node->raw);
84 }
85
86 if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
87 struct jffs2_node_frag *next = frag_next(newfrag);
88
89 if (next) {
90 mark_ref_normal(fn->raw);
91 if (next->node)
92 mark_ref_normal(next->node->raw);
93 }
94 }
e0c8e42f
AB
95 jffs2_dbg_fragtree_paranoia_check_nolock(f);
96 jffs2_dbg_dump_fragtree_nolock(f);
1da177e4
LT
97 return 0;
98}
99
100/* Doesn't set inode->i_size */
101static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag)
102{
103 struct jffs2_node_frag *this;
104 uint32_t lastend;
105
106 /* Skip all the nodes which are completed before this one starts */
107 this = jffs2_lookup_node_frag(list, newfrag->node->ofs);
108
109 if (this) {
110 D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
111 this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
112 lastend = this->ofs + this->size;
113 } else {
114 D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n"));
115 lastend = 0;
116 }
117
118 /* See if we ran off the end of the list */
119 if (lastend <= newfrag->ofs) {
120 /* We did */
121
122 /* Check if 'this' node was on the same page as the new node.
123 If so, both 'this' and the new node get marked REF_NORMAL so
124 the GC can take a look.
125 */
126 if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
127 if (this->node)
128 mark_ref_normal(this->node->raw);
129 mark_ref_normal(newfrag->node->raw);
130 }
131
132 if (lastend < newfrag->node->ofs) {
133 /* ... and we need to put a hole in before the new node */
134 struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
135 if (!holefrag) {
136 jffs2_free_node_frag(newfrag);
137 return -ENOMEM;
138 }
139 holefrag->ofs = lastend;
140 holefrag->size = newfrag->node->ofs - lastend;
141 holefrag->node = NULL;
142 if (this) {
143 /* By definition, the 'this' node has no right-hand child,
144 because there are no frags with offset greater than it.
145 So that's where we want to put the hole */
146 D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this));
147 rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
148 } else {
149 D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag));
150 rb_link_node(&holefrag->rb, NULL, &list->rb_node);
151 }
152 rb_insert_color(&holefrag->rb, list);
153 this = holefrag;
154 }
155 if (this) {
156 /* By definition, the 'this' node has no right-hand child,
157 because there are no frags with offset greater than it.
158 So that's where we want to put the hole */
159 D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this));
160 rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
161 } else {
162 D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag));
163 rb_link_node(&newfrag->rb, NULL, &list->rb_node);
164 }
165 rb_insert_color(&newfrag->rb, list);
166 return 0;
167 }
168
169 D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
170 this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
171
172 /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
173 * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
174 */
175 if (newfrag->ofs > this->ofs) {
176 /* This node isn't completely obsoleted. The start of it remains valid */
177
178 /* Mark the new node and the partially covered node REF_NORMAL -- let
179 the GC take a look at them */
180 mark_ref_normal(newfrag->node->raw);
181 if (this->node)
182 mark_ref_normal(this->node->raw);
183
184 if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
185 /* The new node splits 'this' frag into two */
186 struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag();
187 if (!newfrag2) {
188 jffs2_free_node_frag(newfrag);
189 return -ENOMEM;
190 }
191 D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
192 if (this->node)
193 printk("phys 0x%08x\n", ref_offset(this->node->raw));
194 else
195 printk("hole\n");
196 )
197
198 /* New second frag pointing to this's node */
199 newfrag2->ofs = newfrag->ofs + newfrag->size;
200 newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
201 newfrag2->node = this->node;
202 if (this->node)
203 this->node->frags++;
204
205 /* Adjust size of original 'this' */
206 this->size = newfrag->ofs - this->ofs;
207
208 /* Now, we know there's no node with offset
209 greater than this->ofs but smaller than
210 newfrag2->ofs or newfrag->ofs, for obvious
211 reasons. So we can do a tree insert from
212 'this' to insert newfrag, and a tree insert
213 from newfrag to insert newfrag2. */
214 jffs2_fragtree_insert(newfrag, this);
215 rb_insert_color(&newfrag->rb, list);
216
217 jffs2_fragtree_insert(newfrag2, newfrag);
218 rb_insert_color(&newfrag2->rb, list);
219
220 return 0;
221 }
222 /* New node just reduces 'this' frag in size, doesn't split it */
223 this->size = newfrag->ofs - this->ofs;
224
225 /* Again, we know it lives down here in the tree */
226 jffs2_fragtree_insert(newfrag, this);
227 rb_insert_color(&newfrag->rb, list);
228 } else {
229 /* New frag starts at the same point as 'this' used to. Replace
230 it in the tree without doing a delete and insertion */
231 D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
232 newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
233 this, this->ofs, this->ofs+this->size));
234
235 rb_replace_node(&this->rb, &newfrag->rb, list);
236
237 if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
238 D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size));
239 jffs2_obsolete_node_frag(c, this);
240 } else {
241 this->ofs += newfrag->size;
242 this->size -= newfrag->size;
243
244 jffs2_fragtree_insert(this, newfrag);
245 rb_insert_color(&this->rb, list);
246 return 0;
247 }
248 }
249 /* OK, now we have newfrag added in the correct place in the tree, but
250 frag_next(newfrag) may be a fragment which is overlapped by it
251 */
252 while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
253 /* 'this' frag is obsoleted completely. */
254 D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size));
255 rb_erase(&this->rb, list);
256 jffs2_obsolete_node_frag(c, this);
257 }
258 /* Now we're pointing at the first frag which isn't totally obsoleted by
259 the new frag */
260
261 if (!this || newfrag->ofs + newfrag->size == this->ofs) {
262 return 0;
263 }
264 /* Still some overlap but we don't need to move it in the tree */
265 this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
266 this->ofs = newfrag->ofs + newfrag->size;
267
268 /* And mark them REF_NORMAL so the GC takes a look at them */
269 if (this->node)
270 mark_ref_normal(this->node->raw);
271 mark_ref_normal(newfrag->node->raw);
272
273 return 0;
274}
275
276void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
277{
278 struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
279
280 D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
281
282 /* We know frag->ofs <= size. That's what lookup does for us */
283 if (frag && frag->ofs != size) {
284 if (frag->ofs+frag->size >= size) {
285 D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
286 frag->size = size - frag->ofs;
287 }
288 frag = frag_next(frag);
289 }
290 while (frag && frag->ofs >= size) {
291 struct jffs2_node_frag *next = frag_next(frag);
292
293 D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
294 frag_erase(frag, list);
295 jffs2_obsolete_node_frag(c, frag);
296 frag = next;
297 }
298}
299
300/* Scan the list of all nodes present for this ino, build map of versions, etc. */
301
302static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
303 struct jffs2_inode_info *f,
304 struct jffs2_raw_inode *latest_node);
305
306int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
307 uint32_t ino, struct jffs2_raw_inode *latest_node)
308{
309 D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
310
311 retry_inocache:
312 spin_lock(&c->inocache_lock);
313 f->inocache = jffs2_get_ino_cache(c, ino);
314
315 D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache));
316
317 if (f->inocache) {
318 /* Check its state. We may need to wait before we can use it */
319 switch(f->inocache->state) {
320 case INO_STATE_UNCHECKED:
321 case INO_STATE_CHECKEDABSENT:
322 f->inocache->state = INO_STATE_READING;
323 break;
324
325 case INO_STATE_CHECKING:
326 case INO_STATE_GC:
327 /* If it's in either of these states, we need
328 to wait for whoever's got it to finish and
329 put it back. */
330 D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
331 ino, f->inocache->state));
332 sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
333 goto retry_inocache;
334
335 case INO_STATE_READING:
336 case INO_STATE_PRESENT:
337 /* Eep. This should never happen. It can
338 happen if Linux calls read_inode() again
339 before clear_inode() has finished though. */
340 printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
341 /* Fail. That's probably better than allowing it to succeed */
342 f->inocache = NULL;
343 break;
344
345 default:
346 BUG();
347 }
348 }
349 spin_unlock(&c->inocache_lock);
350
351 if (!f->inocache && ino == 1) {
352 /* Special case - no root inode on medium */
353 f->inocache = jffs2_alloc_inode_cache();
354 if (!f->inocache) {
355 printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
356 return -ENOMEM;
357 }
358 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n"));
359 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
360 f->inocache->ino = f->inocache->nlink = 1;
361 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
362 f->inocache->state = INO_STATE_READING;
363 jffs2_add_ino_cache(c, f->inocache);
364 }
365 if (!f->inocache) {
366 printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
367 return -ENOENT;
368 }
369
370 return jffs2_do_read_inode_internal(c, f, latest_node);
371}
372
373int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
374{
375 struct jffs2_raw_inode n;
376 struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
377 int ret;
378
379 if (!f)
380 return -ENOMEM;
381
382 memset(f, 0, sizeof(*f));
383 init_MUTEX_LOCKED(&f->sem);
384 f->inocache = ic;
385
386 ret = jffs2_do_read_inode_internal(c, f, &n);
387 if (!ret) {
388 up(&f->sem);
389 jffs2_do_clear_inode(c, f);
390 }
391 kfree (f);
392 return ret;
393}
394
395static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
396 struct jffs2_inode_info *f,
397 struct jffs2_raw_inode *latest_node)
398{
9dee7503
DW
399 struct jffs2_tmp_dnode_info *tn = NULL;
400 struct rb_root tn_list;
401 struct rb_node *rb, *repl_rb;
1da177e4
LT
402 struct jffs2_full_dirent *fd_list;
403 struct jffs2_full_dnode *fn = NULL;
404 uint32_t crc;
405 uint32_t latest_mctime, mctime_ver;
406 uint32_t mdata_ver = 0;
407 size_t retlen;
408 int ret;
409
410 D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink));
411
412 /* Grab all nodes relevant to this ino */
413 ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
414
415 if (ret) {
416 printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret);
417 if (f->inocache->state == INO_STATE_READING)
418 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
419 return ret;
420 }
421 f->dents = fd_list;
422
9dee7503 423 rb = rb_first(&tn_list);
1da177e4 424
9dee7503
DW
425 while (rb) {
426 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
1da177e4
LT
427 fn = tn->fn;
428
429 if (f->metadata) {
430 if (likely(tn->version >= mdata_ver)) {
431 D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
432 jffs2_mark_node_obsolete(c, f->metadata->raw);
433 jffs2_free_full_dnode(f->metadata);
434 f->metadata = NULL;
435
436 mdata_ver = 0;
437 } else {
438 /* This should never happen. */
439 printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
440 ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
441 jffs2_mark_node_obsolete(c, fn->raw);
442 jffs2_free_full_dnode(fn);
443 /* Fill in latest_node from the metadata, not this one we're about to free... */
444 fn = f->metadata;
445 goto next_tn;
446 }
447 }
448
449 if (fn->size) {
450 jffs2_add_full_dnode_to_inode(c, f, fn);
451 } else {
452 /* Zero-sized node at end of version list. Just a metadata update */
453 D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version));
454 f->metadata = fn;
455 mdata_ver = tn->version;
456 }
457 next_tn:
9dee7503 458 BUG_ON(rb->rb_left);
9dee7503
DW
459 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
460 /* We were then left-hand child of our parent. We need
461 to move our own right-hand child into our place. */
462 repl_rb = rb->rb_right;
463 if (repl_rb)
464 repl_rb->rb_parent = rb->rb_parent;
465 } else
466 repl_rb = NULL;
467
468 rb = rb_next(rb);
469
470 /* Remove the spent tn from the tree; don't bother rebalancing
471 but put our right-hand child in our own place. */
472 if (tn->rb.rb_parent) {
473 if (tn->rb.rb_parent->rb_left == &tn->rb)
474 tn->rb.rb_parent->rb_left = repl_rb;
475 else if (tn->rb.rb_parent->rb_right == &tn->rb)
476 tn->rb.rb_parent->rb_right = repl_rb;
477 else BUG();
478 } else if (tn->rb.rb_right)
479 tn->rb.rb_right->rb_parent = NULL;
480
1da177e4
LT
481 jffs2_free_tmp_dnode_info(tn);
482 }
e0c8e42f 483 jffs2_dbg_fragtree_paranoia_check_nolock(f);
1da177e4
LT
484
485 if (!fn) {
486 /* No data nodes for this inode. */
487 if (f->inocache->ino != 1) {
488 printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino);
489 if (!fd_list) {
490 if (f->inocache->state == INO_STATE_READING)
491 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
492 return -EIO;
493 }
494 printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
495 }
496 latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
497 latest_node->version = cpu_to_je32(0);
498 latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
499 latest_node->isize = cpu_to_je32(0);
500 latest_node->gid = cpu_to_je16(0);
501 latest_node->uid = cpu_to_je16(0);
502 if (f->inocache->state == INO_STATE_READING)
503 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
504 return 0;
505 }
506
507 ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
508 if (ret || retlen != sizeof(*latest_node)) {
509 printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
510 ret, retlen, sizeof(*latest_node));
511 /* FIXME: If this fails, there seems to be a memory leak. Find it. */
512 up(&f->sem);
513 jffs2_do_clear_inode(c, f);
514 return ret?ret:-EIO;
515 }
516
517 crc = crc32(0, latest_node, sizeof(*latest_node)-8);
518 if (crc != je32_to_cpu(latest_node->node_crc)) {
519 printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw));
520 up(&f->sem);
521 jffs2_do_clear_inode(c, f);
522 return -EIO;
523 }
524
525 switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
526 case S_IFDIR:
527 if (mctime_ver > je32_to_cpu(latest_node->version)) {
528 /* The times in the latest_node are actually older than
529 mctime in the latest dirent. Cheat. */
530 latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
531 }
532 break;
533
534
535 case S_IFREG:
536 /* If it was a regular file, truncate it to the latest node's isize */
537 jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize));
538 break;
539
540 case S_IFLNK:
541 /* Hack to work around broken isize in old symlink code.
542 Remove this when dwmw2 comes to his senses and stops
543 symlinks from being an entirely gratuitous special
544 case. */
545 if (!je32_to_cpu(latest_node->isize))
546 latest_node->isize = latest_node->dsize;
32f1a95d
AB
547
548 if (f->inocache->state != INO_STATE_CHECKING) {
549 /* Symlink's inode data is the target path. Read it and
2b79adcc
AB
550 * keep in RAM to facilitate quick follow symlink
551 * operation. */
552 f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
553 if (!f->target) {
32f1a95d
AB
554 printk(KERN_WARNING "Can't allocate %d bytes of memory "
555 "for the symlink target path cache\n",
556 je32_to_cpu(latest_node->csize));
557 up(&f->sem);
558 jffs2_do_clear_inode(c, f);
559 return -ENOMEM;
560 }
561
562 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
2b79adcc 563 je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
32f1a95d
AB
564
565 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
566 if (retlen != je32_to_cpu(latest_node->csize))
567 ret = -EIO;
2b79adcc
AB
568 kfree(f->target);
569 f->target = NULL;
32f1a95d
AB
570 up(&f->sem);
571 jffs2_do_clear_inode(c, f);
572 return -ret;
573 }
574
2b79adcc 575 f->target[je32_to_cpu(latest_node->csize)] = '\0';
32f1a95d 576 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
2b79adcc 577 f->target));
32f1a95d
AB
578 }
579
1da177e4
LT
580 /* fall through... */
581
582 case S_IFBLK:
583 case S_IFCHR:
584 /* Certain inode types should have only one data node, and it's
585 kept as the metadata node */
586 if (f->metadata) {
587 printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n",
588 f->inocache->ino, jemode_to_cpu(latest_node->mode));
589 up(&f->sem);
590 jffs2_do_clear_inode(c, f);
591 return -EIO;
592 }
593 if (!frag_first(&f->fragtree)) {
594 printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n",
595 f->inocache->ino, jemode_to_cpu(latest_node->mode));
596 up(&f->sem);
597 jffs2_do_clear_inode(c, f);
598 return -EIO;
599 }
600 /* ASSERT: f->fraglist != NULL */
601 if (frag_next(frag_first(&f->fragtree))) {
602 printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n",
603 f->inocache->ino, jemode_to_cpu(latest_node->mode));
604 /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
605 up(&f->sem);
606 jffs2_do_clear_inode(c, f);
607 return -EIO;
608 }
609 /* OK. We're happy */
610 f->metadata = frag_first(&f->fragtree)->node;
611 jffs2_free_node_frag(frag_first(&f->fragtree));
612 f->fragtree = RB_ROOT;
613 break;
614 }
615 if (f->inocache->state == INO_STATE_READING)
616 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
617
618 return 0;
619}
620
621void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
622{
623 struct jffs2_full_dirent *fd, *fds;
624 int deleted;
625
626 down(&f->sem);
627 deleted = f->inocache && !f->inocache->nlink;
628
67e345d1
DW
629 if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
630 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
631
1da177e4
LT
632 if (f->metadata) {
633 if (deleted)
634 jffs2_mark_node_obsolete(c, f->metadata->raw);
635 jffs2_free_full_dnode(f->metadata);
636 }
637
638 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
639
2b79adcc
AB
640 if (f->target) {
641 kfree(f->target);
642 f->target = NULL;
643 }
644
645 fds = f->dents;
646 while(fds) {
647 fd = fds;
648 fds = fd->next;
649 jffs2_free_full_dirent(fd);
1da177e4
LT
650 }
651
67e345d1 652 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
1da177e4 653 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
67e345d1
DW
654 if (f->inocache->nodes == (void *)f->inocache)
655 jffs2_del_ino_cache(c, f->inocache);
656 }
1da177e4
LT
657
658 up(&f->sem);
659}
This page took 0.134012 seconds and 5 git commands to generate.