2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright (C) 2001-2003 Red Hat, Inc.
6 * Created by David Woodhouse <dwmw2@infradead.org>
8 * For licensing information, see the file 'LICENCE' in this directory.
10 * $Id: readinode.c,v 1.117 2004/11/20 18:06:54 dwmw2 Exp $
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
17 #include <linux/crc32.h>
18 #include <linux/pagemap.h>
19 #include <linux/mtd/mtd.h>
20 #include <linux/compiler.h>
23 static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info
*c
, struct rb_root
*list
, struct jffs2_node_frag
*newfrag
);
25 #if CONFIG_JFFS2_FS_DEBUG >= 2
26 static void jffs2_print_fragtree(struct rb_root
*list
, int permitbug
)
28 struct jffs2_node_frag
*this = frag_first(list
);
34 printk(KERN_DEBUG
"frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n",
35 this->ofs
, this->ofs
+this->size
, ref_offset(this->node
->raw
), ref_flags(this->node
->raw
),
36 this, frag_left(this), frag_right(this), frag_parent(this));
38 printk(KERN_DEBUG
"frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs
,
39 this->ofs
+this->size
, this, frag_left(this), frag_right(this), frag_parent(this));
40 if (this->ofs
!= lastofs
)
42 lastofs
= this->ofs
+this->size
;
43 this = frag_next(this);
45 if (buggy
&& !permitbug
) {
46 printk(KERN_CRIT
"Frag tree got a hole in it\n");
51 void jffs2_print_frag_list(struct jffs2_inode_info
*f
)
53 jffs2_print_fragtree(&f
->fragtree
, 0);
56 printk(KERN_DEBUG
"metadata at 0x%08x\n", ref_offset(f
->metadata
->raw
));
61 #if CONFIG_JFFS2_FS_DEBUG >= 1
62 static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info
*f
)
64 struct jffs2_node_frag
*frag
;
67 for (frag
= frag_first(&f
->fragtree
); frag
; frag
= frag_next(frag
)) {
69 struct jffs2_full_dnode
*fn
= frag
->node
;
73 if (ref_flags(fn
->raw
) == REF_PRISTINE
) {
76 printk(KERN_WARNING
"REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn
->raw
), fn
->frags
);
79 /* A hole node which isn't multi-page should be garbage-collected
80 and merged anyway, so we just check for the frag size here,
81 rather than mucking around with actually reading the node
82 and checking the compression type, which is the real way
83 to tell a hole node. */
84 if (frag
->ofs
& (PAGE_CACHE_SIZE
-1) && frag_prev(frag
) && frag_prev(frag
)->size
< PAGE_CACHE_SIZE
&& frag_prev(frag
)->node
) {
85 printk(KERN_WARNING
"REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n",
90 if ((frag
->ofs
+frag
->size
) & (PAGE_CACHE_SIZE
-1) && frag_next(frag
) && frag_next(frag
)->size
< PAGE_CACHE_SIZE
&& frag_next(frag
)->node
) {
91 printk(KERN_WARNING
"REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n",
92 ref_offset(fn
->raw
), frag
->ofs
, frag
->ofs
+frag
->size
);
99 struct jffs2_node_frag
*thisfrag
;
101 printk(KERN_WARNING
"Inode is #%u\n", f
->inocache
->ino
);
102 thisfrag
= frag_first(&f
->fragtree
);
104 if (!thisfrag
->node
) {
105 printk("Frag @0x%x-0x%x; node-less hole\n",
106 thisfrag
->ofs
, thisfrag
->size
+ thisfrag
->ofs
);
107 } else if (!thisfrag
->node
->raw
) {
108 printk("Frag @0x%x-0x%x; raw-less hole\n",
109 thisfrag
->ofs
, thisfrag
->size
+ thisfrag
->ofs
);
111 printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n",
112 thisfrag
->ofs
, thisfrag
->size
+ thisfrag
->ofs
,
113 ref_offset(thisfrag
->node
->raw
), ref_flags(thisfrag
->node
->raw
),
114 thisfrag
->node
->ofs
, thisfrag
->node
->ofs
+thisfrag
->node
->size
);
116 thisfrag
= frag_next(thisfrag
);
123 static void jffs2_obsolete_node_frag(struct jffs2_sb_info
*c
, struct jffs2_node_frag
*this)
127 if (!this->node
->frags
) {
128 /* The node has no valid frags left. It's totally obsoleted */
129 D2(printk(KERN_DEBUG
"Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
130 ref_offset(this->node
->raw
), this->node
->ofs
, this->node
->ofs
+this->node
->size
));
131 jffs2_mark_node_obsolete(c
, this->node
->raw
);
132 jffs2_free_full_dnode(this->node
);
134 D2(printk(KERN_DEBUG
"Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
135 ref_offset(this->node
->raw
), this->node
->ofs
, this->node
->ofs
+this->node
->size
,
137 mark_ref_normal(this->node
->raw
);
141 jffs2_free_node_frag(this);
144 /* Given an inode, probably with existing list of fragments, add the new node
145 * to the fragment list.
147 int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
, struct jffs2_full_dnode
*fn
)
150 struct jffs2_node_frag
*newfrag
;
152 D1(printk(KERN_DEBUG
"jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f
->inocache
->ino
, f
, fn
));
154 newfrag
= jffs2_alloc_node_frag();
155 if (unlikely(!newfrag
))
158 D2(printk(KERN_DEBUG
"adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
159 fn
->ofs
, fn
->ofs
+fn
->size
, ref_offset(fn
->raw
), newfrag
));
161 if (unlikely(!fn
->size
)) {
162 jffs2_free_node_frag(newfrag
);
166 newfrag
->ofs
= fn
->ofs
;
167 newfrag
->size
= fn
->size
;
169 newfrag
->node
->frags
= 1;
171 ret
= jffs2_add_frag_to_fragtree(c
, &f
->fragtree
, newfrag
);
175 /* If we now share a page with other nodes, mark either previous
176 or next node REF_NORMAL, as appropriate. */
177 if (newfrag
->ofs
& (PAGE_CACHE_SIZE
-1)) {
178 struct jffs2_node_frag
*prev
= frag_prev(newfrag
);
180 mark_ref_normal(fn
->raw
);
181 /* If we don't start at zero there's _always_ a previous */
183 mark_ref_normal(prev
->node
->raw
);
186 if ((newfrag
->ofs
+newfrag
->size
) & (PAGE_CACHE_SIZE
-1)) {
187 struct jffs2_node_frag
*next
= frag_next(newfrag
);
190 mark_ref_normal(fn
->raw
);
192 mark_ref_normal(next
->node
->raw
);
195 D2(if (jffs2_sanitycheck_fragtree(f
)) {
196 printk(KERN_WARNING
"Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n",
197 fn
->ofs
, fn
->ofs
+fn
->size
, ref_offset(fn
->raw
), newfrag
);
200 D2(jffs2_print_frag_list(f
));
204 /* Doesn't set inode->i_size */
205 static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info
*c
, struct rb_root
*list
, struct jffs2_node_frag
*newfrag
)
207 struct jffs2_node_frag
*this;
210 /* Skip all the nodes which are completed before this one starts */
211 this = jffs2_lookup_node_frag(list
, newfrag
->node
->ofs
);
214 D2(printk(KERN_DEBUG
"j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
215 this->ofs
, this->ofs
+this->size
, this->node
?(ref_offset(this->node
->raw
)):0xffffffff, this));
216 lastend
= this->ofs
+ this->size
;
218 D2(printk(KERN_DEBUG
"j_a_f_d_t_f: Lookup gave no frag\n"));
222 /* See if we ran off the end of the list */
223 if (lastend
<= newfrag
->ofs
) {
226 /* Check if 'this' node was on the same page as the new node.
227 If so, both 'this' and the new node get marked REF_NORMAL so
228 the GC can take a look.
230 if (lastend
&& (lastend
-1) >> PAGE_CACHE_SHIFT
== newfrag
->ofs
>> PAGE_CACHE_SHIFT
) {
232 mark_ref_normal(this->node
->raw
);
233 mark_ref_normal(newfrag
->node
->raw
);
236 if (lastend
< newfrag
->node
->ofs
) {
237 /* ... and we need to put a hole in before the new node */
238 struct jffs2_node_frag
*holefrag
= jffs2_alloc_node_frag();
240 jffs2_free_node_frag(newfrag
);
243 holefrag
->ofs
= lastend
;
244 holefrag
->size
= newfrag
->node
->ofs
- lastend
;
245 holefrag
->node
= NULL
;
247 /* By definition, the 'this' node has no right-hand child,
248 because there are no frags with offset greater than it.
249 So that's where we want to put the hole */
250 D2(printk(KERN_DEBUG
"Adding hole frag (%p) on right of node at (%p)\n", holefrag
, this));
251 rb_link_node(&holefrag
->rb
, &this->rb
, &this->rb
.rb_right
);
253 D2(printk(KERN_DEBUG
"Adding hole frag (%p) at root of tree\n", holefrag
));
254 rb_link_node(&holefrag
->rb
, NULL
, &list
->rb_node
);
256 rb_insert_color(&holefrag
->rb
, list
);
260 /* By definition, the 'this' node has no right-hand child,
261 because there are no frags with offset greater than it.
262 So that's where we want to put the hole */
263 D2(printk(KERN_DEBUG
"Adding new frag (%p) on right of node at (%p)\n", newfrag
, this));
264 rb_link_node(&newfrag
->rb
, &this->rb
, &this->rb
.rb_right
);
266 D2(printk(KERN_DEBUG
"Adding new frag (%p) at root of tree\n", newfrag
));
267 rb_link_node(&newfrag
->rb
, NULL
, &list
->rb_node
);
269 rb_insert_color(&newfrag
->rb
, list
);
273 D2(printk(KERN_DEBUG
"j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
274 this->ofs
, this->ofs
+this->size
, this->node
?(ref_offset(this->node
->raw
)):0xffffffff, this));
276 /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
277 * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
279 if (newfrag
->ofs
> this->ofs
) {
280 /* This node isn't completely obsoleted. The start of it remains valid */
282 /* Mark the new node and the partially covered node REF_NORMAL -- let
283 the GC take a look at them */
284 mark_ref_normal(newfrag
->node
->raw
);
286 mark_ref_normal(this->node
->raw
);
288 if (this->ofs
+ this->size
> newfrag
->ofs
+ newfrag
->size
) {
289 /* The new node splits 'this' frag into two */
290 struct jffs2_node_frag
*newfrag2
= jffs2_alloc_node_frag();
292 jffs2_free_node_frag(newfrag
);
295 D2(printk(KERN_DEBUG
"split old frag 0x%04x-0x%04x -->", this->ofs
, this->ofs
+this->size
);
297 printk("phys 0x%08x\n", ref_offset(this->node
->raw
));
302 /* New second frag pointing to this's node */
303 newfrag2
->ofs
= newfrag
->ofs
+ newfrag
->size
;
304 newfrag2
->size
= (this->ofs
+this->size
) - newfrag2
->ofs
;
305 newfrag2
->node
= this->node
;
309 /* Adjust size of original 'this' */
310 this->size
= newfrag
->ofs
- this->ofs
;
312 /* Now, we know there's no node with offset
313 greater than this->ofs but smaller than
314 newfrag2->ofs or newfrag->ofs, for obvious
315 reasons. So we can do a tree insert from
316 'this' to insert newfrag, and a tree insert
317 from newfrag to insert newfrag2. */
318 jffs2_fragtree_insert(newfrag
, this);
319 rb_insert_color(&newfrag
->rb
, list
);
321 jffs2_fragtree_insert(newfrag2
, newfrag
);
322 rb_insert_color(&newfrag2
->rb
, list
);
326 /* New node just reduces 'this' frag in size, doesn't split it */
327 this->size
= newfrag
->ofs
- this->ofs
;
329 /* Again, we know it lives down here in the tree */
330 jffs2_fragtree_insert(newfrag
, this);
331 rb_insert_color(&newfrag
->rb
, list
);
333 /* New frag starts at the same point as 'this' used to. Replace
334 it in the tree without doing a delete and insertion */
335 D2(printk(KERN_DEBUG
"Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
336 newfrag
, newfrag
->ofs
, newfrag
->ofs
+newfrag
->size
,
337 this, this->ofs
, this->ofs
+this->size
));
339 rb_replace_node(&this->rb
, &newfrag
->rb
, list
);
341 if (newfrag
->ofs
+ newfrag
->size
>= this->ofs
+this->size
) {
342 D2(printk(KERN_DEBUG
"Obsoleting node frag %p (%x-%x)\n", this, this->ofs
, this->ofs
+this->size
));
343 jffs2_obsolete_node_frag(c
, this);
345 this->ofs
+= newfrag
->size
;
346 this->size
-= newfrag
->size
;
348 jffs2_fragtree_insert(this, newfrag
);
349 rb_insert_color(&this->rb
, list
);
353 /* OK, now we have newfrag added in the correct place in the tree, but
354 frag_next(newfrag) may be a fragment which is overlapped by it
356 while ((this = frag_next(newfrag
)) && newfrag
->ofs
+ newfrag
->size
>= this->ofs
+ this->size
) {
357 /* 'this' frag is obsoleted completely. */
358 D2(printk(KERN_DEBUG
"Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs
, this->ofs
+this->size
));
359 rb_erase(&this->rb
, list
);
360 jffs2_obsolete_node_frag(c
, this);
362 /* Now we're pointing at the first frag which isn't totally obsoleted by
365 if (!this || newfrag
->ofs
+ newfrag
->size
== this->ofs
) {
368 /* Still some overlap but we don't need to move it in the tree */
369 this->size
= (this->ofs
+ this->size
) - (newfrag
->ofs
+ newfrag
->size
);
370 this->ofs
= newfrag
->ofs
+ newfrag
->size
;
372 /* And mark them REF_NORMAL so the GC takes a look at them */
374 mark_ref_normal(this->node
->raw
);
375 mark_ref_normal(newfrag
->node
->raw
);
380 void jffs2_truncate_fraglist (struct jffs2_sb_info
*c
, struct rb_root
*list
, uint32_t size
)
382 struct jffs2_node_frag
*frag
= jffs2_lookup_node_frag(list
, size
);
384 D1(printk(KERN_DEBUG
"Truncating fraglist to 0x%08x bytes\n", size
));
386 /* We know frag->ofs <= size. That's what lookup does for us */
387 if (frag
&& frag
->ofs
!= size
) {
388 if (frag
->ofs
+frag
->size
>= size
) {
389 D1(printk(KERN_DEBUG
"Truncating frag 0x%08x-0x%08x\n", frag
->ofs
, frag
->ofs
+frag
->size
));
390 frag
->size
= size
- frag
->ofs
;
392 frag
= frag_next(frag
);
394 while (frag
&& frag
->ofs
>= size
) {
395 struct jffs2_node_frag
*next
= frag_next(frag
);
397 D1(printk(KERN_DEBUG
"Removing frag 0x%08x-0x%08x\n", frag
->ofs
, frag
->ofs
+frag
->size
));
398 frag_erase(frag
, list
);
399 jffs2_obsolete_node_frag(c
, frag
);
404 /* Scan the list of all nodes present for this ino, build map of versions, etc. */
406 static int jffs2_do_read_inode_internal(struct jffs2_sb_info
*c
,
407 struct jffs2_inode_info
*f
,
408 struct jffs2_raw_inode
*latest_node
);
410 int jffs2_do_read_inode(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
,
411 uint32_t ino
, struct jffs2_raw_inode
*latest_node
)
413 D2(printk(KERN_DEBUG
"jffs2_do_read_inode(): getting inocache\n"));
416 spin_lock(&c
->inocache_lock
);
417 f
->inocache
= jffs2_get_ino_cache(c
, ino
);
419 D2(printk(KERN_DEBUG
"jffs2_do_read_inode(): Got inocache at %p\n", f
->inocache
));
422 /* Check its state. We may need to wait before we can use it */
423 switch(f
->inocache
->state
) {
424 case INO_STATE_UNCHECKED
:
425 case INO_STATE_CHECKEDABSENT
:
426 f
->inocache
->state
= INO_STATE_READING
;
429 case INO_STATE_CHECKING
:
431 /* If it's in either of these states, we need
432 to wait for whoever's got it to finish and
434 D1(printk(KERN_DEBUG
"jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
435 ino
, f
->inocache
->state
));
436 sleep_on_spinunlock(&c
->inocache_wq
, &c
->inocache_lock
);
439 case INO_STATE_READING
:
440 case INO_STATE_PRESENT
:
441 /* Eep. This should never happen. It can
442 happen if Linux calls read_inode() again
443 before clear_inode() has finished though. */
444 printk(KERN_WARNING
"Eep. Trying to read_inode #%u when it's already in state %d!\n", ino
, f
->inocache
->state
);
445 /* Fail. That's probably better than allowing it to succeed */
453 spin_unlock(&c
->inocache_lock
);
455 if (!f
->inocache
&& ino
== 1) {
456 /* Special case - no root inode on medium */
457 f
->inocache
= jffs2_alloc_inode_cache();
459 printk(KERN_CRIT
"jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
462 D1(printk(KERN_DEBUG
"jffs2_do_read_inode(): Creating inocache for root inode\n"));
463 memset(f
->inocache
, 0, sizeof(struct jffs2_inode_cache
));
464 f
->inocache
->ino
= f
->inocache
->nlink
= 1;
465 f
->inocache
->nodes
= (struct jffs2_raw_node_ref
*)f
->inocache
;
466 f
->inocache
->state
= INO_STATE_READING
;
467 jffs2_add_ino_cache(c
, f
->inocache
);
470 printk(KERN_WARNING
"jffs2_do_read_inode() on nonexistent ino %u\n", ino
);
474 return jffs2_do_read_inode_internal(c
, f
, latest_node
);
477 int jffs2_do_crccheck_inode(struct jffs2_sb_info
*c
, struct jffs2_inode_cache
*ic
)
479 struct jffs2_raw_inode n
;
480 struct jffs2_inode_info
*f
= kmalloc(sizeof(*f
), GFP_KERNEL
);
486 memset(f
, 0, sizeof(*f
));
487 init_MUTEX_LOCKED(&f
->sem
);
490 ret
= jffs2_do_read_inode_internal(c
, f
, &n
);
493 jffs2_do_clear_inode(c
, f
);
499 static int jffs2_do_read_inode_internal(struct jffs2_sb_info
*c
,
500 struct jffs2_inode_info
*f
,
501 struct jffs2_raw_inode
*latest_node
)
503 struct jffs2_tmp_dnode_info
*tn_list
, *tn
;
504 struct jffs2_full_dirent
*fd_list
;
505 struct jffs2_full_dnode
*fn
= NULL
;
507 uint32_t latest_mctime
, mctime_ver
;
508 uint32_t mdata_ver
= 0;
512 D1(printk(KERN_DEBUG
"jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f
->inocache
->ino
, f
->inocache
->nlink
));
514 /* Grab all nodes relevant to this ino */
515 ret
= jffs2_get_inode_nodes(c
, f
, &tn_list
, &fd_list
, &f
->highest_version
, &latest_mctime
, &mctime_ver
);
518 printk(KERN_CRIT
"jffs2_get_inode_nodes() for ino %u returned %d\n", f
->inocache
->ino
, ret
);
519 if (f
->inocache
->state
== INO_STATE_READING
)
520 jffs2_set_inocache_state(c
, f
->inocache
, INO_STATE_CHECKEDABSENT
);
531 if (likely(tn
->version
>= mdata_ver
)) {
532 D1(printk(KERN_DEBUG
"Obsoleting old metadata at 0x%08x\n", ref_offset(f
->metadata
->raw
)));
533 jffs2_mark_node_obsolete(c
, f
->metadata
->raw
);
534 jffs2_free_full_dnode(f
->metadata
);
539 /* This should never happen. */
540 printk(KERN_WARNING
"Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
541 ref_offset(fn
->raw
), tn
->version
, mdata_ver
, ref_offset(f
->metadata
->raw
));
542 jffs2_mark_node_obsolete(c
, fn
->raw
);
543 jffs2_free_full_dnode(fn
);
544 /* Fill in latest_node from the metadata, not this one we're about to free... */
551 jffs2_add_full_dnode_to_inode(c
, f
, fn
);
553 /* Zero-sized node at end of version list. Just a metadata update */
554 D1(printk(KERN_DEBUG
"metadata @%08x: ver %d\n", ref_offset(fn
->raw
), tn
->version
));
556 mdata_ver
= tn
->version
;
560 jffs2_free_tmp_dnode_info(tn
);
562 D1(jffs2_sanitycheck_fragtree(f
));
565 /* No data nodes for this inode. */
566 if (f
->inocache
->ino
!= 1) {
567 printk(KERN_WARNING
"jffs2_do_read_inode(): No data nodes found for ino #%u\n", f
->inocache
->ino
);
569 if (f
->inocache
->state
== INO_STATE_READING
)
570 jffs2_set_inocache_state(c
, f
->inocache
, INO_STATE_CHECKEDABSENT
);
573 printk(KERN_WARNING
"jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
575 latest_node
->mode
= cpu_to_jemode(S_IFDIR
|S_IRUGO
|S_IWUSR
|S_IXUGO
);
576 latest_node
->version
= cpu_to_je32(0);
577 latest_node
->atime
= latest_node
->ctime
= latest_node
->mtime
= cpu_to_je32(0);
578 latest_node
->isize
= cpu_to_je32(0);
579 latest_node
->gid
= cpu_to_je16(0);
580 latest_node
->uid
= cpu_to_je16(0);
581 if (f
->inocache
->state
== INO_STATE_READING
)
582 jffs2_set_inocache_state(c
, f
->inocache
, INO_STATE_PRESENT
);
586 ret
= jffs2_flash_read(c
, ref_offset(fn
->raw
), sizeof(*latest_node
), &retlen
, (void *)latest_node
);
587 if (ret
|| retlen
!= sizeof(*latest_node
)) {
588 printk(KERN_NOTICE
"MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
589 ret
, retlen
, sizeof(*latest_node
));
590 /* FIXME: If this fails, there seems to be a memory leak. Find it. */
592 jffs2_do_clear_inode(c
, f
);
596 crc
= crc32(0, latest_node
, sizeof(*latest_node
)-8);
597 if (crc
!= je32_to_cpu(latest_node
->node_crc
)) {
598 printk(KERN_NOTICE
"CRC failed for read_inode of inode %u at physical location 0x%x\n", f
->inocache
->ino
, ref_offset(fn
->raw
));
600 jffs2_do_clear_inode(c
, f
);
604 switch(jemode_to_cpu(latest_node
->mode
) & S_IFMT
) {
606 if (mctime_ver
> je32_to_cpu(latest_node
->version
)) {
607 /* The times in the latest_node are actually older than
608 mctime in the latest dirent. Cheat. */
609 latest_node
->ctime
= latest_node
->mtime
= cpu_to_je32(latest_mctime
);
615 /* If it was a regular file, truncate it to the latest node's isize */
616 jffs2_truncate_fraglist(c
, &f
->fragtree
, je32_to_cpu(latest_node
->isize
));
620 /* Hack to work around broken isize in old symlink code.
621 Remove this when dwmw2 comes to his senses and stops
622 symlinks from being an entirely gratuitous special
624 if (!je32_to_cpu(latest_node
->isize
))
625 latest_node
->isize
= latest_node
->dsize
;
626 /* fall through... */
630 /* Certain inode types should have only one data node, and it's
631 kept as the metadata node */
633 printk(KERN_WARNING
"Argh. Special inode #%u with mode 0%o had metadata node\n",
634 f
->inocache
->ino
, jemode_to_cpu(latest_node
->mode
));
636 jffs2_do_clear_inode(c
, f
);
639 if (!frag_first(&f
->fragtree
)) {
640 printk(KERN_WARNING
"Argh. Special inode #%u with mode 0%o has no fragments\n",
641 f
->inocache
->ino
, jemode_to_cpu(latest_node
->mode
));
643 jffs2_do_clear_inode(c
, f
);
646 /* ASSERT: f->fraglist != NULL */
647 if (frag_next(frag_first(&f
->fragtree
))) {
648 printk(KERN_WARNING
"Argh. Special inode #%u with mode 0x%x had more than one node\n",
649 f
->inocache
->ino
, jemode_to_cpu(latest_node
->mode
));
650 /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
652 jffs2_do_clear_inode(c
, f
);
655 /* OK. We're happy */
656 f
->metadata
= frag_first(&f
->fragtree
)->node
;
657 jffs2_free_node_frag(frag_first(&f
->fragtree
));
658 f
->fragtree
= RB_ROOT
;
661 if (f
->inocache
->state
== INO_STATE_READING
)
662 jffs2_set_inocache_state(c
, f
->inocache
, INO_STATE_PRESENT
);
667 void jffs2_do_clear_inode(struct jffs2_sb_info
*c
, struct jffs2_inode_info
*f
)
669 struct jffs2_full_dirent
*fd
, *fds
;
673 deleted
= f
->inocache
&& !f
->inocache
->nlink
;
677 jffs2_mark_node_obsolete(c
, f
->metadata
->raw
);
678 jffs2_free_full_dnode(f
->metadata
);
681 jffs2_kill_fragtree(&f
->fragtree
, deleted
?c
:NULL
);
688 jffs2_free_full_dirent(fd
);
691 if (f
->inocache
&& f
->inocache
->state
!= INO_STATE_CHECKING
)
692 jffs2_set_inocache_state(c
, f
->inocache
, INO_STATE_CHECKEDABSENT
);