1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001 Red Hat, Inc.
5  *
6  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
7  *
8  * The original JFFS, from which the design for JFFS2 was derived,
9  * was designed and implemented by Axis Communications AB.
10  *
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/
15  *
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.
20  *
21  * The Original Code is JFFS2 - Journalling Flash File System, version 2
22  *
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.
33  *
34  * $Id: readinode.c,v 1.58.2.8 2003/11/02 13:54:20 dwmw2 Exp $
35  *
36  */
37 
38 /* Given an inode, probably with existing list of fragments, add the new node
39  * to the fragment list.
40  */
41 #include <linux/kernel.h>
42 #include <linux/slab.h>
43 #include <linux/fs.h>
44 #include <linux/mtd/mtd.h>
45 #include <linux/jffs2.h>
46 #include "nodelist.h"
47 #include <linux/crc32.h>
48 
49 
D1(void jffs2_print_frag_list (struct jffs2_inode_info * f){ struct jffs2_node_frag *this = f->fraglist; while(this) { if (this->node) 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); else printk(KERN_DEBUG "frag %04x-%04x: hole (*%p->%p)\\n", this->ofs, this->ofs+this->size, this, this->next); this = this->next; } if (f->metadata) { printk(KERN_DEBUG "metadata at 0x%08x\\n", f->metadata->raw->flash_offset &~3); } })50 D1(void jffs2_print_frag_list(struct jffs2_inode_info *f)
51 {
52 	struct jffs2_node_frag *this = f->fraglist;
53 
54 	while(this) {
55 		if (this->node)
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);
57 		else
58 			printk(KERN_DEBUG "frag %04x-%04x: hole (*%p->%p)\n", this->ofs, this->ofs+this->size, this, this->next);
59 		this = this->next;
60 	}
61 	if (f->metadata) {
62 		printk(KERN_DEBUG "metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3);
63 	}
64 })
65 
66 
67 int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
68 {
69 	int ret;
70 	D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
71 
72 	ret = jffs2_add_full_dnode_to_fraglist(c, &f->fraglist, fn);
73 
74 	D2(jffs2_print_frag_list(f));
75 	return ret;
76 }
77 
jffs2_obsolete_node_frag(struct jffs2_sb_info * c,struct jffs2_node_frag * this)78 static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
79 {
80 	if (this->node) {
81 		this->node->frags--;
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);
88 		} else {
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,
91 				  this->node->frags));
92 		}
93 
94 	}
95 	jffs2_free_node_frag(this);
96 }
97 
98 /* Doesn't set inode->i_size */
jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info * c,struct jffs2_node_frag ** list,struct jffs2_full_dnode * fn)99 int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn)
100 {
101 
102 	struct jffs2_node_frag *this, **prev, *old;
103 	struct jffs2_node_frag *newfrag, *newfrag2;
104 	__u32 lastend = 0;
105 
106 
107 	newfrag = jffs2_alloc_node_frag();
108 	if (!newfrag) {
109 		return -ENOMEM;
110 	}
111 
112 	D2(if (fn->raw)
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);
114 	else
115 		printk(KERN_DEBUG "adding hole node %04x-%04x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, newfrag));
116 
117 	prev = list;
118 	this = *list;
119 
120 	if (!fn->size) {
121 		jffs2_free_node_frag(newfrag);
122 		return 0;
123 	}
124 
125 	newfrag->ofs = fn->ofs;
126 	newfrag->size = fn->size;
127 	newfrag->node = fn;
128 	newfrag->node->frags = 1;
129 	newfrag->next = (void *)0xdeadbeef;
130 
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;
134 
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));
137 		prev = &this->next;
138 		this = this->next;
139 	}
140 
141 	/* See if we ran off the end of the list */
142 	if (!this) {
143 		/* We did */
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();
147 			if (!holefrag)
148 				return -ENOMEM;
149 			holefrag->ofs = lastend;
150 			holefrag->size = fn->ofs - lastend;
151 			holefrag->next = NULL;
152 			holefrag->node = NULL;
153 			*prev = holefrag;
154 			prev = &holefrag->next;
155 		}
156 		newfrag->next = NULL;
157 		*prev = newfrag;
158 		return 0;
159 	}
160 
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));
163 
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
166 	 */
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();
172 			if (!newfrag2) {
173 				jffs2_free_node_frag(newfrag);
174 				return -ENOMEM;
175 			}
176 			D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
177 			if (this->node)
178 				printk("phys 0x%08x\n", this->node->raw->flash_offset &~3);
179 			else
180 				printk("hole\n");
181 			   )
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;
186 			if (this->node)
187 				this->node->frags++;
188 			newfrag->next = newfrag2;
189 			this->next = newfrag;
190 			this->size = newfrag->ofs - this->ofs;
191 			return 0;
192 		}
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;
198 	} else {
199 		D2(printk(KERN_DEBUG "Inserting newfrag (*%p) in before 'this' (*%p)\n", newfrag, this));
200 		*prev = newfrag;
201 	        newfrag->next = this;
202 	}
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
205 	*/
206 	while (this && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
207 		/* 'this' frag is obsoleted. */
208 		old = this;
209 		this = old->next;
210 		jffs2_obsolete_node_frag(c, old);
211 	}
212 	/* Now we're pointing at the first frag which isn't totally obsoleted by
213 	   the new frag */
214 	newfrag->next = this;
215 
216 	if (!this || newfrag->ofs + newfrag->size == this->ofs) {
217 		return 0;
218 	}
219 	/* Still some overlap */
220 	this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
221 	this->ofs = newfrag->ofs + newfrag->size;
222 	return 0;
223 }
224 
jffs2_truncate_fraglist(struct jffs2_sb_info * c,struct jffs2_node_frag ** list,__u32 size)225 void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size)
226 {
227 	D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
228 
229 	while (*list) {
230 		if ((*list)->ofs >= size) {
231 			struct jffs2_node_frag *this = *list;
232 			*list = this->next;
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);
235 			continue;
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;
239 		}
240 		list = &(*list)->next;
241 	}
242 }
243 
244 /* Scan the list of all nodes present for this ino, build map of versions, etc. */
245 
jffs2_read_inode(struct inode * inode)246 void jffs2_read_inode (struct inode *inode)
247 {
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;
255 	__u32 mdata_ver = 0;
256 	int ret;
257 	ssize_t retlen;
258 
259 	D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
260 
261 	f = JFFS2_INODE_INFO(inode);
262 	c = JFFS2_SB_INFO(inode->i_sb);
263 
264 	memset(f, 0, sizeof(*f));
265 	D2(printk(KERN_DEBUG "getting inocache\n"));
266 	init_MUTEX(&f->sem);
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));
269 
270 	if (!f->inocache && inode->i_ino == 1) {
271 		/* Special case - no root inode on medium */
272 		f->inocache = jffs2_alloc_inode_cache();
273 		if (!f->inocache) {
274 			printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n");
275 			make_bad_inode(inode);
276 			return;
277 		}
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);
283 	}
284 	if (!f->inocache) {
285 		printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino);
286 		make_bad_inode(inode);
287 		return;
288 	}
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;
291 
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);
294 
295 	if (ret) {
296 		printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
297 		make_bad_inode(inode);
298 		return;
299 	}
300 	f->dents = fd_list;
301 
302 	while (tn_list) {
303 		tn = tn_list;
304 
305 		fn = tn->fn;
306 
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);
311 			f->metadata = NULL;
312 
313 			mdata_ver = 0;
314 		}
315 
316 		if (fn->size) {
317 			jffs2_add_full_dnode_to_inode(c, f, fn);
318 		} else {
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));
321 			f->metadata = fn;
322 			mdata_ver = tn->version;
323 		}
324 		tn_list = tn->next;
325 		jffs2_free_tmp_dnode_info(tn);
326 	}
327 	if (!fn) {
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);
331 			if (!fd_list) {
332 				make_bad_inode(inode);
333 				return;
334 			}
335 			printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");
336 		}
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;
341 		inode->i_size = 0;
342 	} else {
343 		__u32 crc;
344 
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);
351 			return;
352 		}
353 
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);
359 			return;
360 		}
361 
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;
371 	}
372 
373 	/* OK, now the special cases. Certain inode types should
374 	   have only one data node, and it's kept as the metadata
375 	   node */
376 	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||
377 	    S_ISLNK(inode->i_mode)) {
378 		if (f->metadata) {
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);
382 			return;
383 		}
384 		if (!f->fraglist) {
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);
388 			return;
389 		}
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);
396 			return;
397 		}
398 		/* OK. We're happy */
399 		f->metadata = f->fraglist->node;
400 		jffs2_free_node_frag(f->fraglist);
401 		f->fraglist = NULL;
402 	}
403 
404 	inode->i_blksize = PAGE_SIZE;
405 	inode->i_blocks = (inode->i_size + 511) >> 9;
406 
407 	switch (inode->i_mode & S_IFMT) {
408 		unsigned short rdev;
409 
410 	case S_IFLNK:
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
415 		   case. */
416 		if (!inode->i_size)
417 			inode->i_size = latest_node.dsize;
418 		break;
419 
420 	case S_IFDIR:
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 =
425 				latest_mctime;
426 		}
427 		inode->i_op = &jffs2_dir_inode_operations;
428 		inode->i_fop = &jffs2_dir_operations;
429 		break;
430 
431 	case S_IFREG:
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;
436 		break;
437 
438 	case S_IFBLK:
439 	case S_IFCHR:
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) {
443 			/* Eep */
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);
447 			return;
448 		}
449 
450 	case S_IFSOCK:
451 	case S_IFIFO:
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)));
454 		break;
455 
456 	default:
457 		printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino);
458 	}
459 	D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
460 }
461 
jffs2_clear_inode(struct inode * inode)462 void jffs2_clear_inode (struct inode *inode)
463 {
464 	/* We can forget about this inode for now - drop all
465 	 *  the nodelists associated with it, etc.
466 	 */
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);
471         int deleted;
472 
473 	D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
474 
475 	down(&f->sem);
476 	deleted = f->inocache && !f->inocache->nlink;
477 
478 	frags = f->fraglist;
479 	fds = f->dents;
480 	if (f->metadata) {
481 		if (deleted)
482 			jffs2_mark_node_obsolete(c, f->metadata->raw);
483 		jffs2_free_full_dnode(f->metadata);
484 	}
485 
486 	while (frags) {
487 		frag = frags;
488 		frags = frag->next;
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));
490 
491 		if (frag->node && !(--frag->node->frags)) {
492 			/* Not a hole, and it's the final remaining frag of this node. Free the node */
493 			if (deleted)
494 				jffs2_mark_node_obsolete(c, frag->node->raw);
495 
496 			jffs2_free_full_dnode(frag->node);
497 		}
498 		jffs2_free_node_frag(frag);
499 	}
500 	while(fds) {
501 		fd = fds;
502 		fds = fd->next;
503 		jffs2_free_full_dirent(fd);
504 	}
505 
506 	up(&f->sem);
507 };
508 
509