tweak reserved blocks
[linux-2.4.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.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
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                         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
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         __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
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