2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright (C) 2001 Red Hat, Inc.
6 * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
8 * The original JFFS, from which the design for JFFS2 was derived,
9 * was designed and implemented by Axis Communications AB.
11 * The contents of this file are subject to the Red Hat eCos Public
12 * License Version 1.1 (the "Licence"); you may not use this file
13 * except in compliance with the Licence. You may obtain a copy of
14 * the Licence at http://www.redhat.com/
16 * Software distributed under the Licence is distributed on an "AS IS"
17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
18 * See the Licence for the specific language governing rights and
19 * limitations under the Licence.
21 * The Original Code is JFFS2 - Journalling Flash File System, version 2
23 * Alternatively, the contents of this file may be used under the
24 * terms of the GNU General Public License version 2 (the "GPL"), in
25 * which case the provisions of the GPL are applicable instead of the
26 * above. If you wish to allow the use of your version of this file
27 * only under the terms of the GPL and not to allow others to use your
28 * version of this file under the RHEPL, indicate your decision by
29 * deleting the provisions above and replace them with the notice and
30 * other provisions required by the GPL. If you do not delete the
31 * provisions above, a recipient may use your version of this file
32 * under either the RHEPL or the GPL.
34 * $Id: readinode.c,v 1.58.2.8 2003/11/02 13:54:20 dwmw2 Exp $
38 /* Given an inode, probably with existing list of fragments, add the new node
39 * to the fragment list.
41 #include <linux/kernel.h>
42 #include <linux/slab.h>
44 #include <linux/mtd/mtd.h>
45 #include <linux/jffs2.h>
47 #include <linux/crc32.h>
50 D1(void jffs2_print_frag_list(struct jffs2_inode_info *f)
52 struct jffs2_node_frag *this = f->fraglist;
56 printk(KERN_DEBUG "frag %04x-%04x: 0x%08x on flash (*%p->%p)\n", this->ofs, this->ofs+this->size, this->node->raw->flash_offset &~3, this, this->next);
58 printk(KERN_DEBUG "frag %04x-%04x: hole (*%p->%p)\n", this->ofs, this->ofs+this->size, this, this->next);
62 printk(KERN_DEBUG "metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3);
67 int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
70 D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
72 ret = jffs2_add_full_dnode_to_fraglist(c, &f->fraglist, fn);
74 D2(jffs2_print_frag_list(f));
78 static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
82 if (!this->node->frags) {
83 /* The node has no valid frags left. It's totally obsoleted */
84 D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
85 this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size));
86 jffs2_mark_node_obsolete(c, this->node->raw);
87 jffs2_free_full_dnode(this->node);
89 D2(printk(KERN_DEBUG "Not marking old node @0x%08x (0x%04x-0x%04x) obsolete. frags is %d\n",
90 this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size,
95 jffs2_free_node_frag(this);
98 /* Doesn't set inode->i_size */
99 int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn)
102 struct jffs2_node_frag *this, **prev, *old;
103 struct jffs2_node_frag *newfrag, *newfrag2;
107 newfrag = jffs2_alloc_node_frag();
113 printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, fn->raw->flash_offset &~3, newfrag);
115 printk(KERN_DEBUG "adding hole node %04x-%04x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, newfrag));
121 jffs2_free_node_frag(newfrag);
125 newfrag->ofs = fn->ofs;
126 newfrag->size = fn->size;
128 newfrag->node->frags = 1;
129 newfrag->next = (void *)0xdeadbeef;
131 /* Skip all the nodes which are completed before this one starts */
132 while(this && fn->ofs >= this->ofs+this->size) {
133 lastend = this->ofs + this->size;
135 D2(printk(KERN_DEBUG "j_a_f_d_t_f: skipping frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n",
136 this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next));
141 /* See if we ran off the end of the list */
144 if (lastend < fn->ofs) {
145 /* ... and we need to put a hole in before the new node */
146 struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
149 holefrag->ofs = lastend;
150 holefrag->size = fn->ofs - lastend;
151 holefrag->next = NULL;
152 holefrag->node = NULL;
154 prev = &holefrag->next;
156 newfrag->next = NULL;
161 D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n",
162 this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next));
164 /* OK. 'this' is pointing at the first frag that fn->ofs at least partially obsoletes,
165 * - i.e. fn->ofs < this->ofs+this->size && fn->ofs >= this->ofs
167 if (fn->ofs > this->ofs) {
168 /* This node isn't completely obsoleted. The start of it remains valid */
169 if (this->ofs + this->size > fn->ofs + fn->size) {
170 /* The new node splits 'this' frag into two */
171 newfrag2 = jffs2_alloc_node_frag();
173 jffs2_free_node_frag(newfrag);
176 D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
178 printk("phys 0x%08x\n", this->node->raw->flash_offset &~3);
182 newfrag2->ofs = fn->ofs + fn->size;
183 newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
184 newfrag2->next = this->next;
185 newfrag2->node = this->node;
188 newfrag->next = newfrag2;
189 this->next = newfrag;
190 this->size = newfrag->ofs - this->ofs;
193 /* New node just reduces 'this' frag in size, doesn't split it */
194 this->size = fn->ofs - this->ofs;
195 newfrag->next = this->next;
196 this->next = newfrag;
197 this = newfrag->next;
199 D2(printk(KERN_DEBUG "Inserting newfrag (*%p) in before 'this' (*%p)\n", newfrag, this));
201 newfrag->next = this;
203 /* OK, now we have newfrag added in the correct place in the list, but
204 newfrag->next points to a fragment which may be overlapping it
206 while (this && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
207 /* 'this' frag is obsoleted. */
210 jffs2_obsolete_node_frag(c, old);
212 /* Now we're pointing at the first frag which isn't totally obsoleted by
214 newfrag->next = this;
216 if (!this || newfrag->ofs + newfrag->size == this->ofs) {
219 /* Still some overlap */
220 this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
221 this->ofs = newfrag->ofs + newfrag->size;
225 void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size)
227 D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
230 if ((*list)->ofs >= size) {
231 struct jffs2_node_frag *this = *list;
233 D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", this->ofs, this->ofs+this->size));
234 jffs2_obsolete_node_frag(c, this);
236 } else if ((*list)->ofs + (*list)->size > size) {
237 D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", (*list)->ofs, (*list)->ofs + (*list)->size));
238 (*list)->size = size - (*list)->ofs;
240 list = &(*list)->next;
244 /* Scan the list of all nodes present for this ino, build map of versions, etc. */
246 void jffs2_read_inode (struct inode *inode)
248 struct jffs2_tmp_dnode_info *tn_list, *tn;
249 struct jffs2_full_dirent *fd_list;
250 struct jffs2_inode_info *f;
251 struct jffs2_full_dnode *fn = NULL;
252 struct jffs2_sb_info *c;
253 struct jffs2_raw_inode latest_node;
254 __u32 latest_mctime, mctime_ver;
259 D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
261 f = JFFS2_INODE_INFO(inode);
262 c = JFFS2_SB_INFO(inode->i_sb);
264 memset(f, 0, sizeof(*f));
265 D2(printk(KERN_DEBUG "getting inocache\n"));
267 f->inocache = jffs2_get_ino_cache(c, inode->i_ino);
268 D2(printk(KERN_DEBUG "jffs2_read_inode(): Got inocache at %p\n", f->inocache));
270 if (!f->inocache && inode->i_ino == 1) {
271 /* Special case - no root inode on medium */
272 f->inocache = jffs2_alloc_inode_cache();
274 printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n");
275 make_bad_inode(inode);
278 D1(printk(KERN_DEBUG "jffs2_read_inode(): Creating inocache for root inode\n"));
279 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
280 f->inocache->ino = f->inocache->nlink = 1;
281 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
282 jffs2_add_ino_cache(c, f->inocache);
285 printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino);
286 make_bad_inode(inode);
289 D1(printk(KERN_DEBUG "jffs2_read_inode(): ino #%lu nlink is %d\n", (unsigned long)inode->i_ino, f->inocache->nlink));
290 inode->i_nlink = f->inocache->nlink;
292 /* Grab all nodes relevant to this ino */
293 ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
296 printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
297 make_bad_inode(inode);
307 if (f->metadata && tn->version > mdata_ver) {
308 D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3));
309 jffs2_mark_node_obsolete(c, f->metadata->raw);
310 jffs2_free_full_dnode(f->metadata);
317 jffs2_add_full_dnode_to_inode(c, f, fn);
319 /* Zero-sized node at end of version list. Just a metadata update */
320 D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", fn->raw->flash_offset &~3, tn->version));
322 mdata_ver = tn->version;
325 jffs2_free_tmp_dnode_info(tn);
328 /* No data nodes for this inode. */
329 if (inode->i_ino != 1) {
330 printk(KERN_WARNING "jffs2_read_inode(): No data nodes found for ino #%lu\n", inode->i_ino);
332 make_bad_inode(inode);
335 printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");
337 inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
338 latest_node.version = 0;
339 inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
340 inode->i_nlink = f->inocache->nlink;
345 ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(latest_node), &retlen, (void *)&latest_node);
346 if (ret || retlen != sizeof(latest_node)) {
347 printk(KERN_NOTICE "MTD read in jffs2_read_inode() failed: Returned %d, %ld of %d bytes read\n",
348 ret, (long)retlen, sizeof(latest_node));
349 jffs2_clear_inode(inode);
350 make_bad_inode(inode);
354 crc = crc32(0, &latest_node, sizeof(latest_node)-8);
355 if (crc != latest_node.node_crc) {
356 printk(KERN_NOTICE "CRC failed for read_inode of inode %ld at physical location 0x%x\n", inode->i_ino, fn->raw->flash_offset & ~3);
357 jffs2_clear_inode(inode);
358 make_bad_inode(inode);
362 inode->i_mode = latest_node.mode;
363 inode->i_uid = latest_node.uid;
364 inode->i_gid = latest_node.gid;
365 inode->i_size = latest_node.isize;
366 if (S_ISREG(inode->i_mode))
367 jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);
368 inode->i_atime = latest_node.atime;
369 inode->i_mtime = latest_node.mtime;
370 inode->i_ctime = latest_node.ctime;
373 /* OK, now the special cases. Certain inode types should
374 have only one data node, and it's kept as the metadata
376 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||
377 S_ISLNK(inode->i_mode)) {
379 printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode);
380 jffs2_clear_inode(inode);
381 make_bad_inode(inode);
385 printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o has no fragments\n", inode->i_ino, inode->i_mode);
386 jffs2_clear_inode(inode);
387 make_bad_inode(inode);
390 /* ASSERT: f->fraglist != NULL */
391 if (f->fraglist->next) {
392 printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode);
393 /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
394 jffs2_clear_inode(inode);
395 make_bad_inode(inode);
398 /* OK. We're happy */
399 f->metadata = f->fraglist->node;
400 jffs2_free_node_frag(f->fraglist);
404 inode->i_blksize = PAGE_SIZE;
405 inode->i_blocks = (inode->i_size + 511) >> 9;
407 switch (inode->i_mode & S_IFMT) {
411 inode->i_op = &jffs2_symlink_inode_operations;
412 /* Hack to work around broken isize in old symlink code.
413 Remove this when dwmw2 comes to his senses and stops
414 symlinks from being an entirely gratuitous special
417 inode->i_size = latest_node.dsize;
421 if (mctime_ver > latest_node.version) {
422 /* The times in the latest_node are actually older than
423 mctime in the latest dirent. Cheat. */
424 inode->i_mtime = inode->i_ctime = inode->i_atime =
427 inode->i_op = &jffs2_dir_inode_operations;
428 inode->i_fop = &jffs2_dir_operations;
432 inode->i_op = &jffs2_file_inode_operations;
433 inode->i_fop = &jffs2_file_operations;
434 inode->i_mapping->a_ops = &jffs2_file_address_operations;
435 inode->i_mapping->nrpages = 0;
440 /* Read the device numbers from the media */
441 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
442 if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
444 printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
445 jffs2_clear_inode(inode);
446 make_bad_inode(inode);
452 inode->i_op = &jffs2_file_inode_operations;
453 init_special_inode(inode, inode->i_mode, kdev_t_to_nr(MKDEV(rdev>>8, rdev&0xff)));
457 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino);
459 D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
462 void jffs2_clear_inode (struct inode *inode)
464 /* We can forget about this inode for now - drop all
465 * the nodelists associated with it, etc.
467 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
468 struct jffs2_node_frag *frag, *frags;
469 struct jffs2_full_dirent *fd, *fds;
470 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
473 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
476 deleted = f->inocache && !f->inocache->nlink;
482 jffs2_mark_node_obsolete(c, f->metadata->raw);
483 jffs2_free_full_dnode(f->metadata);
489 D2(printk(KERN_DEBUG "jffs2_clear_inode: frag at 0x%x-0x%x: node %p, frags %d--\n", frag->ofs, frag->ofs+frag->size, frag->node, frag->node?frag->node->frags:0));
491 if (frag->node && !(--frag->node->frags)) {
492 /* Not a hole, and it's the final remaining frag of this node. Free the node */
494 jffs2_mark_node_obsolete(c, frag->node->raw);
496 jffs2_free_full_dnode(frag->node);
498 jffs2_free_node_frag(frag);
503 jffs2_free_full_dirent(fd);