v2.4.9.9 -> v2.4.9.10
[linux-flexiantxendom0-3.2.10.git] / fs / jffs2 / gc.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: gc.c,v 1.51 2001/05/24 22:24:39 dwmw2 Exp $
35  *
36  */
37
38 #include <linux/kernel.h>
39 #include <linux/mtd/mtd.h>
40 #include <linux/slab.h>
41 #include <linux/jffs2.h>
42 #include <linux/sched.h>
43 #include <linux/interrupt.h>
44 #include <linux/pagemap.h>
45 #include "nodelist.h"
46 #include "crc32.h"
47
48 static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 
49                                         struct inode *inode, struct jffs2_full_dnode *fd);
50 static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 
51                                         struct inode *inode, struct jffs2_full_dirent *fd);
52 static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 
53                                         struct inode *inode, struct jffs2_full_dirent *fd);
54 static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
55                                       struct inode *indeo, struct jffs2_full_dnode *fn,
56                                       __u32 start, __u32 end);
57 static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
58                                        struct inode *inode, struct jffs2_full_dnode *fn,
59                                        __u32 start, __u32 end);
60
61 /* Called with erase_completion_lock held */
62 static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
63 {
64         struct jffs2_eraseblock *ret;
65         struct list_head *nextlist = NULL;
66
67         /* Pick an eraseblock to garbage collect next. This is where we'll
68            put the clever wear-levelling algorithms. Eventually.  */
69         if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > JFFS2_RESERVED_BLOCKS_GCBAD) {
70                 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
71                 nextlist = &c->bad_used_list;
72         } else if (jiffies % 100 && !list_empty(&c->dirty_list)) {
73                 /* Most of the time, pick one off the dirty list */
74                 D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n"));
75                 nextlist = &c->dirty_list;
76         } else if (!list_empty(&c->clean_list)) {
77                 D1(printk(KERN_DEBUG "Picking block from clean_list to GC next\n"));
78                 nextlist = &c->clean_list;
79         } else if (!list_empty(&c->dirty_list)) {
80                 D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n"));
81
82                 nextlist = &c->dirty_list;
83         } else {
84                 /* Eep. Both were empty */
85                 printk(KERN_NOTICE "jffs2: No clean _or_ dirty blocks to GC from! Where are they all?\n");
86                 return NULL;
87         }
88
89         ret = list_entry(nextlist->next, struct jffs2_eraseblock, list);
90         list_del(&ret->list);
91         c->gcblock = ret;
92         ret->gc_node = ret->first_node;
93         if (!ret->gc_node) {
94                 printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);
95                 BUG();
96         }
97         return ret;
98 }
99
100 /* jffs2_garbage_collect_pass
101  * Make a single attempt to progress GC. Move one node, and possibly
102  * start erasing one eraseblock.
103  */
104 int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
105 {
106         struct jffs2_eraseblock *jeb;
107         struct jffs2_inode_info *f;
108         struct jffs2_raw_node_ref *raw;
109         struct jffs2_node_frag *frag;
110         struct jffs2_full_dnode *fn = NULL;
111         struct jffs2_full_dirent *fd;
112         __u32 start = 0, end = 0, nrfrags = 0;
113         __u32 inum;
114         struct inode *inode;
115         int ret = 0;
116
117         if (down_interruptible(&c->alloc_sem))
118                 return -EINTR;
119
120         spin_lock_bh(&c->erase_completion_lock);
121
122         /* First, work out which block we're garbage-collecting */
123         jeb = c->gcblock;
124
125         if (!jeb)
126                 jeb = jffs2_find_gc_block(c);
127
128         if (!jeb) {
129                 printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n");
130                 spin_unlock_bh(&c->erase_completion_lock);
131                 up(&c->alloc_sem);
132                 return -EIO;
133         }
134
135         D1(printk(KERN_DEBUG "garbage collect from block at phys 0x%08x\n", jeb->offset));
136
137         if (!jeb->used_size)
138                 goto eraseit;
139
140         raw = jeb->gc_node;
141                         
142         while(raw->flash_offset & 1) {
143                 D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", raw->flash_offset &~3));
144                 jeb->gc_node = raw = raw->next_phys;
145                 if (!raw) {
146                         printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
147                         printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", 
148                                jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
149                         spin_unlock_bh(&c->erase_completion_lock);
150                         up(&c->alloc_sem);
151                         BUG();
152                 }
153         }
154         D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", raw->flash_offset &~3));
155         if (!raw->next_in_ino) {
156                 /* Inode-less node. Clean marker, snapshot or something like that */
157                 spin_unlock_bh(&c->erase_completion_lock);
158                 jffs2_mark_node_obsolete(c, raw);
159                 goto eraseit_lock;
160         }
161                                                      
162         inum = jffs2_raw_ref_to_inum(raw);
163         D1(printk(KERN_DEBUG "Inode number is #%u\n", inum));
164
165         spin_unlock_bh(&c->erase_completion_lock);
166
167         D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x, ino #%u\n", jeb->offset, raw->flash_offset&~3, inum));
168
169         inode = iget(OFNI_BS_2SFFJ(c), inum);
170         if (is_bad_inode(inode)) {
171                 printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", inum);
172                 /* NB. This will happen again. We need to do something appropriate here. */
173                 iput(inode);
174                 up(&c->alloc_sem);
175                 return -EIO;
176         }
177
178         f = JFFS2_INODE_INFO(inode);
179         down(&f->sem);
180         /* Now we have the lock for this inode. Check that it's still the one at the head
181            of the list. */
182
183         if (raw->flash_offset & 1) {
184                 D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n"));
185                 /* They'll call again */
186                 goto upnout;
187         }
188         /* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */
189         if (f->metadata && f->metadata->raw == raw) {
190                 fn = f->metadata;
191                 ret = jffs2_garbage_collect_metadata(c, jeb, inode, fn);
192                 goto upnout;
193         }
194         
195         for (frag = f->fraglist; frag; frag = frag->next) {
196                 if (frag->node && frag->node->raw == raw) {
197                         fn = frag->node;
198                         end = frag->ofs + frag->size;
199                         if (!nrfrags++)
200                                 start = frag->ofs;
201                         if (nrfrags == frag->node->frags)
202                                 break; /* We've found them all */
203                 }
204         }
205         if (fn) {
206                 /* We found a datanode. Do the GC */
207                 if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) {
208                         /* It crosses a page boundary. Therefore, it must be a hole. */
209                         ret = jffs2_garbage_collect_hole(c, jeb, inode, fn, start, end);
210                 } else {
211                         /* It could still be a hole. But we GC the page this way anyway */
212                         ret = jffs2_garbage_collect_dnode(c, jeb, inode, fn, start, end);
213                 }
214                 goto upnout;
215         }
216         
217         /* Wasn't a dnode. Try dirent */
218         for (fd = f->dents; fd; fd=fd->next) {
219                 if (fd->raw == raw)
220                         break;
221         }
222
223         if (fd && fd->ino) {
224                 ret = jffs2_garbage_collect_dirent(c, jeb, inode, fd);
225         } else if (fd) {
226                 ret = jffs2_garbage_collect_deletion_dirent(c, jeb, inode, fd);
227         } else {
228                 printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%lu\n", raw->flash_offset&~3, inode->i_ino);
229                 if (raw->flash_offset & 1) {
230                         printk(KERN_WARNING "But it's obsolete so we don't mind too much\n");
231                 } else {
232                         ret = -EIO;
233                 }
234         }
235  upnout:
236         up(&f->sem);
237         iput(inode);
238
239  eraseit_lock:
240         /* If we've finished this block, start it erasing */
241         spin_lock_bh(&c->erase_completion_lock);
242
243  eraseit:
244         if (c->gcblock && !c->gcblock->used_size) {
245                 D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset));
246                 /* We're GC'ing an empty block? */
247                 list_add_tail(&c->gcblock->list, &c->erase_pending_list);
248                 c->gcblock = NULL;
249                 c->nr_erasing_blocks++;
250                 jffs2_erase_pending_trigger(c);
251         }
252         spin_unlock_bh(&c->erase_completion_lock);
253         up(&c->alloc_sem);
254
255         return ret;
256 }
257
258 static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 
259                                         struct inode *inode, struct jffs2_full_dnode *fn)
260 {
261         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
262         struct jffs2_full_dnode *new_fn;
263         struct jffs2_raw_inode ri;
264         unsigned short dev;
265         char *mdata = NULL, mdatalen = 0;
266         __u32 alloclen, phys_ofs;
267         int ret;
268
269         if ((inode->i_mode & S_IFMT) == S_IFBLK ||
270             (inode->i_mode & S_IFMT) == S_IFCHR) {
271                 /* For these, we don't actually need to read the old node */
272                 dev =  (MAJOR(to_kdev_t(inode->i_rdev)) << 8) | 
273                         MINOR(to_kdev_t(inode->i_rdev));
274                 mdata = (char *)&dev;
275                 mdatalen = sizeof(dev);
276                 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
277         } else if ((inode->i_mode & S_IFMT) == S_IFLNK) {
278                 mdatalen = fn->size;
279                 mdata = kmalloc(fn->size, GFP_KERNEL);
280                 if (!mdata) {
281                         printk(KERN_WARNING "kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n");
282                         return -ENOMEM;
283                 }
284                 ret = jffs2_read_dnode(c, fn, mdata, 0, mdatalen);
285                 if (ret) {
286                         printk(KERN_WARNING "read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n", ret);
287                         kfree(mdata);
288                         return ret;
289                 }
290                 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen));
291
292         }
293         
294         ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen);
295         if (ret) {
296                 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_metadata failed: %d\n",
297                        sizeof(ri)+ mdatalen, ret);
298                 goto out;
299         }
300         
301         memset(&ri, 0, sizeof(ri));
302         ri.magic = JFFS2_MAGIC_BITMASK;
303         ri.nodetype = JFFS2_NODETYPE_INODE;
304         ri.totlen = sizeof(ri) + mdatalen;
305         ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
306
307         ri.ino = inode->i_ino;
308         ri.version = ++f->highest_version;
309         ri.mode = inode->i_mode;
310         ri.uid = inode->i_uid;
311         ri.gid = inode->i_gid;
312         ri.isize = inode->i_size;
313         ri.atime = inode->i_atime;
314         ri.ctime = inode->i_ctime;
315         ri.mtime = inode->i_mtime;
316         ri.offset = 0;
317         ri.csize = mdatalen;
318         ri.dsize = mdatalen;
319         ri.compr = JFFS2_COMPR_NONE;
320         ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
321         ri.data_crc = crc32(0, mdata, mdatalen);
322
323         new_fn = jffs2_write_dnode(inode, &ri, mdata, mdatalen, phys_ofs, NULL);
324
325         if (IS_ERR(new_fn)) {
326                 printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
327                 ret = PTR_ERR(new_fn);
328                 goto out;
329         }
330         jffs2_mark_node_obsolete(c, fn->raw);
331         jffs2_free_full_dnode(fn);
332         f->metadata = new_fn;
333  out:
334         if ((inode->i_mode & S_IFMT) == S_IFLNK)
335                 kfree(mdata);
336         return ret;
337 }
338
339 static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 
340                                         struct inode *inode, struct jffs2_full_dirent *fd)
341 {
342         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
343         struct jffs2_full_dirent *new_fd;
344         struct jffs2_raw_dirent rd;
345         __u32 alloclen, phys_ofs;
346         int ret;
347
348         rd.magic = JFFS2_MAGIC_BITMASK;
349         rd.nodetype = JFFS2_NODETYPE_DIRENT;
350         rd.nsize = strlen(fd->name);
351         rd.totlen = sizeof(rd) + rd.nsize;
352         rd.hdr_crc = crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4);
353
354         rd.pino = inode->i_ino;
355         rd.version = ++f->highest_version;
356         rd.ino = fd->ino;
357         rd.mctime = max(inode->i_mtime, inode->i_ctime);
358         rd.type = fd->type;
359         rd.node_crc = crc32(0, &rd, sizeof(rd)-8);
360         rd.name_crc = crc32(0, fd->name, rd.nsize);
361         
362         ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen);
363         if (ret) {
364                 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dirent failed: %d\n",
365                        sizeof(rd)+rd.nsize, ret);
366                 return ret;
367         }
368         new_fd = jffs2_write_dirent(inode, &rd, fd->name, rd.nsize, phys_ofs, NULL);
369
370         if (IS_ERR(new_fd)) {
371                 printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd));
372                 return PTR_ERR(new_fd);
373         }
374         jffs2_add_fd_to_list(c, new_fd, &f->dents);
375         return 0;
376 }
377
378 static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 
379                                         struct inode *inode, struct jffs2_full_dirent *fd)
380 {
381         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
382         struct jffs2_full_dirent **fdp = &f->dents;
383         int found = 0;
384
385         /* FIXME: When we run on NAND flash, we need to work out whether
386            this deletion dirent is still needed to actively delete a
387            'real' dirent with the same name that's still somewhere else
388            on the flash. For now, we know that we've actually obliterated
389            all the older dirents when they became obsolete, so we didn't
390            really need to write the deletion to flash in the first place.
391         */
392         while (*fdp) {
393                 if ((*fdp) == fd) {
394                         found = 1;
395                         *fdp = fd->next;
396                         break;
397                 }
398                 fdp = &(*fdp)->next;
399         }
400         if (!found) {
401                 printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%lu\n", fd->name, inode->i_ino);
402         }
403         jffs2_mark_node_obsolete(c, fd->raw);
404         jffs2_free_full_dirent(fd);
405         return 0;
406 }
407
408 static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
409                                       struct inode *inode, struct jffs2_full_dnode *fn,
410                                       __u32 start, __u32 end)
411 {
412         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
413         struct jffs2_raw_inode ri;
414         struct jffs2_node_frag *frag;
415         struct jffs2_full_dnode *new_fn;
416         __u32 alloclen, phys_ofs;
417         int ret;
418
419         D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%lu from offset 0x%x to 0x%x\n",
420                   inode->i_ino, start, end));
421         
422         memset(&ri, 0, sizeof(ri));
423
424         if(fn->frags > 1) {
425                 size_t readlen;
426                 __u32 crc;
427                 /* It's partially obsoleted by a later write. So we have to 
428                    write it out again with the _same_ version as before */
429                 ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(ri), &readlen, (char *)&ri);
430                 if (readlen != sizeof(ri) || ret) {
431                         printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %d. Data will be lost by writing new hold node\n", ret, readlen);
432                         goto fill;
433                 }
434                 if (ri.nodetype != JFFS2_NODETYPE_INODE) {
435                         printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n",
436                                fn->raw->flash_offset & ~3, ri.nodetype, JFFS2_NODETYPE_INODE);
437                         return -EIO;
438                 }
439                 if (ri.totlen != sizeof(ri)) {
440                         printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%x\n",
441                                fn->raw->flash_offset & ~3, ri.totlen, sizeof(ri));
442                         return -EIO;
443                 }
444                 crc = crc32(0, &ri, sizeof(ri)-8);
445                 if (crc != ri.node_crc) {
446                         printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
447                                fn->raw->flash_offset & ~3, ri.node_crc, crc);
448                         /* FIXME: We could possibly deal with this by writing new holes for each frag */
449                         printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n", 
450                                start, end, inode->i_ino);
451                         goto fill;
452                 }
453                 if (ri.compr != JFFS2_COMPR_ZERO) {
454                         printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", fn->raw->flash_offset & ~3);
455                         printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n", 
456                                start, end, inode->i_ino);
457                         goto fill;
458                 }
459         } else {
460         fill:
461                 ri.magic = JFFS2_MAGIC_BITMASK;
462                 ri.nodetype = JFFS2_NODETYPE_INODE;
463                 ri.totlen = sizeof(ri);
464                 ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
465
466                 ri.ino = inode->i_ino;
467                 ri.version = ++f->highest_version;
468                 ri.offset = start;
469                 ri.csize = end - start;
470                 ri.dsize = 0;
471                 ri.compr = JFFS2_COMPR_ZERO;
472         }
473         ri.mode = inode->i_mode;
474         ri.uid = inode->i_uid;
475         ri.gid = inode->i_gid;
476         ri.isize = inode->i_size;
477         ri.atime = inode->i_atime;
478         ri.ctime = inode->i_ctime;
479         ri.mtime = inode->i_mtime;
480         ri.data_crc = 0;
481         ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
482
483         ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen);
484         if (ret) {
485                 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_hole failed: %d\n",
486                        sizeof(ri), ret);
487                 return ret;
488         }
489         new_fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);
490
491         if (IS_ERR(new_fn)) {
492                 printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn));
493                 return PTR_ERR(new_fn);
494         }
495         if (ri.version == f->highest_version) {
496                 jffs2_add_full_dnode_to_inode(c, f, new_fn);
497                 if (f->metadata) {
498                         jffs2_mark_node_obsolete(c, f->metadata->raw);
499                         jffs2_free_full_dnode(f->metadata);
500                         f->metadata = NULL;
501                         return 0;
502                 }
503         }
504         for (frag = f->fraglist; frag; frag = frag->next) {
505                 if (frag->ofs > fn->size + fn->ofs)
506                         break;
507                 if (frag->node == fn) {
508                         frag->node = new_fn;
509                         new_fn->frags++;
510                         fn->frags--;
511                 }
512         }
513         if (fn->frags) {
514                 printk(KERN_WARNING "jffs2_garbage_collect_hole: Old node still has frags!\n");
515                 BUG();
516         }
517         if (!new_fn->frags) {
518                 printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n");
519                 BUG();
520         }
521                 
522         jffs2_mark_node_obsolete(c, fn->raw);
523         jffs2_free_full_dnode(fn);
524         
525         return 0;
526 }
527
528 static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
529                                        struct inode *inode, struct jffs2_full_dnode *fn,
530                                        __u32 start, __u32 end)
531 {
532         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
533         struct jffs2_full_dnode *new_fn;
534         struct jffs2_raw_inode ri;
535         __u32 alloclen, phys_ofs, offset, orig_end;     
536         int ret = 0;
537         unsigned char *comprbuf = NULL, *writebuf;
538         struct page *pg;
539         unsigned char *pg_ptr;
540
541
542         memset(&ri, 0, sizeof(ri));
543
544         D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%lu from offset 0x%x to 0x%x\n",
545                   inode->i_ino, start, end));
546
547         orig_end = end;
548
549
550         /* If we're looking at the last node in the block we're
551            garbage-collecting, we allow ourselves to merge as if the
552            block was already erasing. We're likely to be GC'ing a
553            partial page, and the next block we GC is likely to have
554            the other half of this page right at the beginning, which
555            means we'd expand it _then_, as nr_erasing_blocks would have
556            increased since we checked, and in doing so would obsolete 
557            the partial node which we'd have written here. Meaning that 
558            the GC would churn and churn, and just leave dirty blocks in
559            it's wake.
560         */
561         if(c->nr_free_blocks + c->nr_erasing_blocks > JFFS2_RESERVED_BLOCKS_GCMERGE - (fn->raw->next_phys?0:1)) {
562                 /* Shitloads of space */
563                 /* FIXME: Integrate this properly with GC calculations */
564                 start &= ~(PAGE_CACHE_SIZE-1);
565                 end = min(start + PAGE_CACHE_SIZE, inode->i_size);
566                 D1(printk(KERN_DEBUG "Plenty of free space, so expanding to write from offset 0x%x to 0x%x\n",
567                           start, end));
568                 if (end < orig_end) {
569                         printk(KERN_WARNING "Eep. jffs2_garbage_collect_dnode extended node to write, but it got smaller: start 0x%x, orig_end 0x%x, end 0x%x\n", start, orig_end, end);
570                         end = orig_end;
571                 }
572         }
573         
574         /* First, use readpage() to read the appropriate page into the page cache */
575         /* Q: What happens if we actually try to GC the _same_ page for which commit_write()
576          *    triggered garbage collection in the first place?
577          * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the
578          *    page OK. We'll actually write it out again in commit_write, which is a little
579          *    suboptimal, but at least we're correct.
580          */
581         pg = read_cache_page(inode->i_mapping, start >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode);
582
583         if (IS_ERR(pg)) {
584                 printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg));
585                 return PTR_ERR(pg);
586         }
587         pg_ptr = (char *)kmap(pg);
588         comprbuf = kmalloc(end - start, GFP_KERNEL);
589
590         offset = start;
591         while(offset < orig_end) {
592                 __u32 datalen;
593                 __u32 cdatalen;
594                 char comprtype = JFFS2_COMPR_NONE;
595
596                 ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen);
597
598                 if (ret) {
599                         printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dnode failed: %d\n",
600                                sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret);
601                         break;
602                 }
603                 cdatalen = min(alloclen - sizeof(ri), end - offset);
604                 datalen = end - offset;
605
606                 writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1));
607
608                 if (comprbuf) {
609                         comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen);
610                 }
611                 if (comprtype) {
612                         writebuf = comprbuf;
613                 } else {
614                         datalen = cdatalen;
615                 }
616                 ri.magic = JFFS2_MAGIC_BITMASK;
617                 ri.nodetype = JFFS2_NODETYPE_INODE;
618                 ri.totlen = sizeof(ri) + cdatalen;
619                 ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
620
621                 ri.ino = inode->i_ino;
622                 ri.version = ++f->highest_version;
623                 ri.mode = inode->i_mode;
624                 ri.uid = inode->i_uid;
625                 ri.gid = inode->i_gid;
626                 ri.isize = inode->i_size;
627                 ri.atime = inode->i_atime;
628                 ri.ctime = inode->i_ctime;
629                 ri.mtime = inode->i_mtime;
630                 ri.offset = offset;
631                 ri.csize = cdatalen;
632                 ri.dsize = datalen;
633                 ri.compr = comprtype;
634                 ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
635                 ri.data_crc = crc32(0, writebuf, cdatalen);
636         
637                 new_fn = jffs2_write_dnode(inode, &ri, writebuf, cdatalen, phys_ofs, NULL);
638
639                 if (IS_ERR(new_fn)) {
640                         printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
641                         ret = PTR_ERR(new_fn);
642                         break;
643                 }
644                 ret = jffs2_add_full_dnode_to_inode(c, f, new_fn);
645                 offset += datalen;
646                 if (f->metadata) {
647                         jffs2_mark_node_obsolete(c, f->metadata->raw);
648                         jffs2_free_full_dnode(f->metadata);
649                         f->metadata = NULL;
650                 }
651         }
652         if (comprbuf) kfree(comprbuf);
653
654         kunmap(pg);
655         /* XXX: Does the page get freed automatically? */
656         /* AAA: Judging by the unmount getting stuck in __wait_on_page, nope. */
657         page_cache_release(pg);
658         return ret;
659 }
660