v2.4.9.9 -> v2.4.9.10
[opensuse:kernel.git] / fs / jffs2 / readinode.c
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.56 2001/07/26 20:32:39 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 "crc32.h"
48
49
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
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 */
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                         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
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
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         int ret;
255         ssize_t retlen;
256
257         D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
258
259         f = JFFS2_INODE_INFO(inode);
260         c = JFFS2_SB_INFO(inode->i_sb);
261
262         memset(f, 0, sizeof(*f));
263         D2(printk(KERN_DEBUG "getting inocache\n"));
264         init_MUTEX(&f->sem);
265         f->inocache = jffs2_get_ino_cache(c, inode->i_ino);
266         D2(printk(KERN_DEBUG "jffs2_read_inode(): Got inocache at %p\n", f->inocache));
267
268         if (!f->inocache && inode->i_ino == 1) {
269                 /* Special case - no root inode on medium */
270                 f->inocache = jffs2_alloc_inode_cache();
271                 if (!f->inocache) {
272                         printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n");
273                         make_bad_inode(inode);
274                         return;
275                 }
276                 D1(printk(KERN_DEBUG "jffs2_read_inode(): Creating inocache for root inode\n"));
277                 memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
278                 f->inocache->ino = f->inocache->nlink = 1;
279                 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
280                 jffs2_add_ino_cache(c, f->inocache);
281         }
282         if (!f->inocache) {
283                 printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino);
284                 make_bad_inode(inode);
285                 return;
286         }
287         D1(printk(KERN_DEBUG "jffs2_read_inode(): ino #%lu nlink is %d\n", (unsigned long)inode->i_ino, f->inocache->nlink));
288         inode->i_nlink = f->inocache->nlink;
289
290         /* Grab all nodes relevant to this ino */
291         ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version);
292
293         if (ret) {
294                 printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
295                 make_bad_inode(inode);
296                 return;
297         }
298         f->dents = fd_list;
299
300         while (tn_list) {
301                 static __u32 mdata_ver = 0;
302
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                 inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
339                 inode->i_nlink = f->inocache->nlink;
340                 inode->i_size = 0;
341         } else {
342                 __u32 crc;
343
344                 ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(latest_node), &retlen, (void *)&latest_node);
345                 if (ret || retlen != sizeof(latest_node)) {
346                         printk(KERN_NOTICE "MTD read in jffs2_read_inode() failed: Returned %d, %ld of %d bytes read\n",
347                                ret, (long)retlen, sizeof(latest_node));
348                         jffs2_clear_inode(inode);
349                         make_bad_inode(inode);
350                         return;
351                 }
352
353                 crc = crc32(0, &latest_node, sizeof(latest_node)-8);
354                 if (crc != latest_node.node_crc) {
355                         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);
356                         jffs2_clear_inode(inode);
357                         make_bad_inode(inode);
358                         return;
359                 }
360
361                 inode->i_mode = latest_node.mode;
362                 inode->i_uid = latest_node.uid;
363                 inode->i_gid = latest_node.gid;
364                 inode->i_size = latest_node.isize;
365                 if ((inode->i_mode & S_IFMT) == S_IFREG)
366                         jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);
367                 inode->i_atime = latest_node.atime;
368                 inode->i_mtime = latest_node.mtime;
369                 inode->i_ctime = latest_node.ctime;
370         }
371
372         /* OK, now the special cases. Certain inode types should
373            have only one data node, and it's kept as the metadata
374            node */
375         if ((inode->i_mode & S_IFMT) == S_IFBLK ||
376             (inode->i_mode & S_IFMT) == S_IFCHR ||
377             (inode->i_mode & S_IFMT) == S_IFLNK) {
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 had more than one node\n", inode->i_ino);
393                         jffs2_clear_inode(inode);
394                         make_bad_inode(inode);
395                         return;
396                 }
397                 /* OK. We're happy */
398                 f->metadata = f->fraglist->node;
399                 jffs2_free_node_frag(f->fraglist);
400                 f->fraglist = NULL;
401         }                       
402             
403         inode->i_blksize = PAGE_SIZE;
404         inode->i_blocks = (inode->i_size + 511) >> 9;
405         
406         switch (inode->i_mode & S_IFMT) {
407                 unsigned short rdev;
408
409         case S_IFLNK:
410                 inode->i_op = &jffs2_symlink_inode_operations;
411                 break;
412                 
413         case S_IFDIR:
414                 inode->i_op = &jffs2_dir_inode_operations;
415                 inode->i_fop = &jffs2_dir_operations;
416                 break;
417
418         case S_IFREG:
419                 inode->i_op = &jffs2_file_inode_operations;
420                 inode->i_fop = &jffs2_file_operations;
421                 inode->i_mapping->a_ops = &jffs2_file_address_operations;
422                 inode->i_mapping->nrpages = 0;
423                 break;
424
425         case S_IFBLK:
426         case S_IFCHR:
427                 /* Read the device numbers from the media */
428                 D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
429                 if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
430                         /* Eep */
431                         printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
432                         jffs2_clear_inode(inode);
433                         make_bad_inode(inode);
434                         return;
435                 }                       
436
437         case S_IFSOCK:
438         case S_IFIFO:
439                 inode->i_op = &jffs2_file_inode_operations;
440                 init_special_inode(inode, inode->i_mode, kdev_t_to_nr(MKDEV(rdev>>8, rdev&0xff)));
441                 break;
442
443         default:
444                 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino);
445         }
446         D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
447 }
448
449 void jffs2_clear_inode (struct inode *inode)
450 {
451         /* We can forget about this inode for now - drop all 
452          *  the nodelists associated with it, etc.
453          */
454         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
455         struct jffs2_node_frag *frag, *frags;
456         struct jffs2_full_dirent *fd, *fds;
457         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
458
459         D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
460
461         frags = f->fraglist;
462         fds = f->dents;
463         if (f->metadata) {
464                 if (!f->inocache->nlink)
465                         jffs2_mark_node_obsolete(c, f->metadata->raw);
466                 jffs2_free_full_dnode(f->metadata);
467         }
468
469         while (frags) {
470                 frag = frags;
471                 frags = frag->next;
472                 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));
473
474                 if (frag->node && !(--frag->node->frags)) {
475                         /* Not a hole, and it's the final remaining frag of this node. Free the node */
476                         if (!f->inocache->nlink)
477                                 jffs2_mark_node_obsolete(c, frag->node->raw);
478
479                         jffs2_free_full_dnode(frag->node);
480                 }
481                 jffs2_free_node_frag(frag);
482         }
483         while(fds) {
484                 fd = fds;
485                 fds = fd->next;
486                 jffs2_free_full_dirent(fd);
487         }
488         //      if (!f->inocache->nlink) {
489                 //              D1(printk(KERN_DEBUG "jffs2_clear_inode() deleting inode #%lu\n", inode->i_ino));
490                 //              jffs2_del_ino_cache(JFFS2_SB_INFO(inode->i_sb), f->inocache);
491                 //              jffs2_free_inode_cache(f->inocache);
492         //      }
493 };
494