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.1.1.1 2008/10/15 03:27:07 james26_jang 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 48static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 49 struct inode *inode, struct jffs2_full_dnode *fd); 50static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 51 struct inode *inode, struct jffs2_full_dirent *fd); 52static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 53 struct inode *inode, struct jffs2_full_dirent *fd); 54static 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); 57static 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 */ 62static 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 */ 104int 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 up(&c->alloc_sem); 139 goto eraseit; 140 } 141 142 raw = jeb->gc_node; 143 144 while(raw->flash_offset & 1) { 145 D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", raw->flash_offset &~3)); 146 jeb->gc_node = raw = raw->next_phys; 147 if (!raw) { 148 printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); 149 printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", 150 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); 151 spin_unlock_bh(&c->erase_completion_lock); 152 up(&c->alloc_sem); 153 BUG(); 154 } 155 } 156 D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", raw->flash_offset &~3)); 157 if (!raw->next_in_ino) { 158 /* Inode-less node. Clean marker, snapshot or something like that */ 159 spin_unlock_bh(&c->erase_completion_lock); 160 jffs2_mark_node_obsolete(c, raw); 161 up(&c->alloc_sem); 162 goto eraseit_lock; 163 } 164 165 inum = jffs2_raw_ref_to_inum(raw); 166 D1(printk(KERN_DEBUG "Inode number is #%u\n", inum)); 167 168 spin_unlock_bh(&c->erase_completion_lock); 169 170 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)); 171 172 inode = iget(OFNI_BS_2SFFJ(c), inum); 173 if (is_bad_inode(inode)) { 174 printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", inum); 175 /* NB. This will happen again. We need to do something appropriate here. */ 176 up(&c->alloc_sem); 177 iput(inode); 178 return -EIO; 179 } 180 181 f = JFFS2_INODE_INFO(inode); 182 down(&f->sem); 183 /* Now we have the lock for this inode. Check that it's still the one at the head 184 of the list. */ 185 186 if (raw->flash_offset & 1) { 187 D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n")); 188 /* They'll call again */ 189 goto upnout; 190 } 191 /* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */ 192 if (f->metadata && f->metadata->raw == raw) { 193 fn = f->metadata; 194 ret = jffs2_garbage_collect_metadata(c, jeb, inode, fn); 195 goto upnout; 196 } 197 198 for (frag = f->fraglist; frag; frag = frag->next) { 199 if (frag->node && frag->node->raw == raw) { 200 fn = frag->node; 201 end = frag->ofs + frag->size; 202 if (!nrfrags++) 203 start = frag->ofs; 204 if (nrfrags == frag->node->frags) 205 break; /* We've found them all */ 206 } 207 } 208 if (fn) { 209 /* We found a datanode. Do the GC */ 210 if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) { 211 /* It crosses a page boundary. Therefore, it must be a hole. */ 212 ret = jffs2_garbage_collect_hole(c, jeb, inode, fn, start, end); 213 } else { 214 /* It could still be a hole. But we GC the page this way anyway */ 215 ret = jffs2_garbage_collect_dnode(c, jeb, inode, fn, start, end); 216 } 217 goto upnout; 218 } 219 220 /* Wasn't a dnode. Try dirent */ 221 for (fd = f->dents; fd; fd=fd->next) { 222 if (fd->raw == raw) 223 break; 224 } 225 226 if (fd && fd->ino) { 227 ret = jffs2_garbage_collect_dirent(c, jeb, inode, fd); 228 } else if (fd) { 229 ret = jffs2_garbage_collect_deletion_dirent(c, jeb, inode, fd); 230 } else { 231 printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%lu\n", raw->flash_offset&~3, inode->i_ino); 232 if (raw->flash_offset & 1) { 233 printk(KERN_WARNING "But it's obsolete so we don't mind too much\n"); 234 } else { 235 ret = -EIO; 236 } 237 } 238 upnout: 239 up(&f->sem); 240 up(&c->alloc_sem); 241 iput(inode); 242 243 eraseit_lock: 244 /* If we've finished this block, start it erasing */ 245 spin_lock_bh(&c->erase_completion_lock); 246 247 eraseit: 248 if (c->gcblock && !c->gcblock->used_size) { 249 D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset)); 250 /* We're GC'ing an empty block? */ 251 list_add_tail(&c->gcblock->list, &c->erase_pending_list); 252 c->gcblock = NULL; 253 c->nr_erasing_blocks++; 254 jffs2_erase_pending_trigger(c); 255 } 256 spin_unlock_bh(&c->erase_completion_lock); 257 258 return ret; 259} 260 261static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 262 struct inode *inode, struct jffs2_full_dnode *fn) 263{ 264 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 265 struct jffs2_full_dnode *new_fn; 266 struct jffs2_raw_inode ri; 267 unsigned short dev; 268 char *mdata = NULL, mdatalen = 0; 269 __u32 alloclen, phys_ofs; 270 int ret; 271 272 if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { 273 /* For these, we don't actually need to read the old node */ 274 dev = (MAJOR(to_kdev_t(inode->i_rdev)) << 8) | 275 MINOR(to_kdev_t(inode->i_rdev)); 276 mdata = (char *)&dev; 277 mdatalen = sizeof(dev); 278 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen)); 279 } else if (S_ISLNK(inode->i_mode)) { 280 mdatalen = fn->size; 281 mdata = kmalloc(fn->size, GFP_KERNEL); 282 if (!mdata) { 283 printk(KERN_WARNING "kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n"); 284 return -ENOMEM; 285 } 286 ret = jffs2_read_dnode(c, fn, mdata, 0, mdatalen); 287 if (ret) { 288 printk(KERN_WARNING "read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n", ret); 289 kfree(mdata); 290 return ret; 291 } 292 D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen)); 293 294 } 295 296 ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen); 297 if (ret) { 298 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_metadata failed: %d\n", 299 sizeof(ri)+ mdatalen, ret); 300 goto out; 301 } 302 303 memset(&ri, 0, sizeof(ri)); 304 ri.magic = JFFS2_MAGIC_BITMASK; 305 ri.nodetype = JFFS2_NODETYPE_INODE; 306 ri.totlen = sizeof(ri) + mdatalen; 307 ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); 308 309 ri.ino = inode->i_ino; 310 ri.version = ++f->highest_version; 311 ri.mode = inode->i_mode; 312 ri.uid = inode->i_uid; 313 ri.gid = inode->i_gid; 314 ri.isize = inode->i_size; 315 ri.atime = inode->i_atime; 316 ri.ctime = inode->i_ctime; 317 ri.mtime = inode->i_mtime; 318 ri.offset = 0; 319 ri.csize = mdatalen; 320 ri.dsize = mdatalen; 321 ri.compr = JFFS2_COMPR_NONE; 322 ri.node_crc = crc32(0, &ri, sizeof(ri)-8); 323 ri.data_crc = crc32(0, mdata, mdatalen); 324 325 new_fn = jffs2_write_dnode(inode, &ri, mdata, mdatalen, phys_ofs, NULL); 326 327 if (IS_ERR(new_fn)) { 328 printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); 329 ret = PTR_ERR(new_fn); 330 goto out; 331 } 332 jffs2_mark_node_obsolete(c, fn->raw); 333 jffs2_free_full_dnode(fn); 334 f->metadata = new_fn; 335 out: 336 if (S_ISLNK(inode->i_mode)) 337 kfree(mdata); 338 return ret; 339} 340 341static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 342 struct inode *inode, struct jffs2_full_dirent *fd) 343{ 344 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 345 struct jffs2_full_dirent *new_fd; 346 struct jffs2_raw_dirent rd; 347 __u32 alloclen, phys_ofs; 348 int ret; 349 350 rd.magic = JFFS2_MAGIC_BITMASK; 351 rd.nodetype = JFFS2_NODETYPE_DIRENT; 352 rd.nsize = strlen(fd->name); 353 rd.totlen = sizeof(rd) + rd.nsize; 354 rd.hdr_crc = crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4); 355 356 rd.pino = inode->i_ino; 357 rd.version = ++f->highest_version; 358 rd.ino = fd->ino; 359 rd.mctime = max(inode->i_mtime, inode->i_ctime); 360 rd.type = fd->type; 361 rd.node_crc = crc32(0, &rd, sizeof(rd)-8); 362 rd.name_crc = crc32(0, fd->name, rd.nsize); 363 364 ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen); 365 if (ret) { 366 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dirent failed: %d\n", 367 sizeof(rd)+rd.nsize, ret); 368 return ret; 369 } 370 new_fd = jffs2_write_dirent(inode, &rd, fd->name, rd.nsize, phys_ofs, NULL); 371 372 if (IS_ERR(new_fd)) { 373 printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd)); 374 return PTR_ERR(new_fd); 375 } 376 jffs2_add_fd_to_list(c, new_fd, &f->dents); 377 return 0; 378} 379 380static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 381 struct inode *inode, struct jffs2_full_dirent *fd) 382{ 383 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 384 struct jffs2_full_dirent **fdp = &f->dents; 385 int found = 0; 386 387 while (*fdp) { 388 if ((*fdp) == fd) { 389 found = 1; 390 *fdp = fd->next; 391 break; 392 } 393 fdp = &(*fdp)->next; 394 } 395 if (!found) { 396 printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%lu\n", fd->name, inode->i_ino); 397 } 398 jffs2_mark_node_obsolete(c, fd->raw); 399 jffs2_free_full_dirent(fd); 400 return 0; 401} 402 403static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 404 struct inode *inode, struct jffs2_full_dnode *fn, 405 __u32 start, __u32 end) 406{ 407 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 408 struct jffs2_raw_inode ri; 409 struct jffs2_node_frag *frag; 410 struct jffs2_full_dnode *new_fn; 411 __u32 alloclen, phys_ofs; 412 int ret; 413 414 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%lu from offset 0x%x to 0x%x\n", 415 inode->i_ino, start, end)); 416 417 memset(&ri, 0, sizeof(ri)); 418 419 if(fn->frags > 1) { 420 size_t readlen; 421 __u32 crc; 422 /* It's partially obsoleted by a later write. So we have to 423 write it out again with the _same_ version as before */ 424 ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(ri), &readlen, (char *)&ri); 425 if (readlen != sizeof(ri) || ret) { 426 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); 427 goto fill; 428 } 429 if (ri.nodetype != JFFS2_NODETYPE_INODE) { 430 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n", 431 fn->raw->flash_offset & ~3, ri.nodetype, JFFS2_NODETYPE_INODE); 432 return -EIO; 433 } 434 if (ri.totlen != sizeof(ri)) { 435 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%x\n", 436 fn->raw->flash_offset & ~3, ri.totlen, sizeof(ri)); 437 return -EIO; 438 } 439 crc = crc32(0, &ri, sizeof(ri)-8); 440 if (crc != ri.node_crc) { 441 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", 442 fn->raw->flash_offset & ~3, ri.node_crc, crc); 443 printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n", 444 start, end, inode->i_ino); 445 goto fill; 446 } 447 if (ri.compr != JFFS2_COMPR_ZERO) { 448 printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", fn->raw->flash_offset & ~3); 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 } else { 454 fill: 455 ri.magic = JFFS2_MAGIC_BITMASK; 456 ri.nodetype = JFFS2_NODETYPE_INODE; 457 ri.totlen = sizeof(ri); 458 ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); 459 460 ri.ino = inode->i_ino; 461 ri.version = ++f->highest_version; 462 ri.offset = start; 463 ri.dsize = end - start; 464 ri.csize = 0; 465 ri.compr = JFFS2_COMPR_ZERO; 466 } 467 ri.mode = inode->i_mode; 468 ri.uid = inode->i_uid; 469 ri.gid = inode->i_gid; 470 ri.isize = inode->i_size; 471 ri.atime = inode->i_atime; 472 ri.ctime = inode->i_ctime; 473 ri.mtime = inode->i_mtime; 474 ri.data_crc = 0; 475 ri.node_crc = crc32(0, &ri, sizeof(ri)-8); 476 477 ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen); 478 if (ret) { 479 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_hole failed: %d\n", 480 sizeof(ri), ret); 481 return ret; 482 } 483 new_fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL); 484 485 if (IS_ERR(new_fn)) { 486 printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn)); 487 return PTR_ERR(new_fn); 488 } 489 if (ri.version == f->highest_version) { 490 jffs2_add_full_dnode_to_inode(c, f, new_fn); 491 if (f->metadata) { 492 jffs2_mark_node_obsolete(c, f->metadata->raw); 493 jffs2_free_full_dnode(f->metadata); 494 f->metadata = NULL; 495 } 496 return 0; 497 } 498 499 /* 500 * We should only get here in the case where the node we are 501 * replacing had more than one frag, so we kept the same version 502 * number as before. (Except in case of error -- see 'goto fill;' 503 * above.) 504 */ 505 D1(if(fn->frags <= 1) { 506 printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n", 507 fn->frags, ri.version, f->highest_version, ri.ino); 508 }); 509 510 for (frag = f->fraglist; frag; frag = frag->next) { 511 if (frag->ofs > fn->size + fn->ofs) 512 break; 513 if (frag->node == fn) { 514 frag->node = new_fn; 515 new_fn->frags++; 516 fn->frags--; 517 } 518 } 519 if (fn->frags) { 520 printk(KERN_WARNING "jffs2_garbage_collect_hole: Old node still has frags!\n"); 521 BUG(); 522 } 523 if (!new_fn->frags) { 524 printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n"); 525 BUG(); 526 } 527 528 jffs2_mark_node_obsolete(c, fn->raw); 529 jffs2_free_full_dnode(fn); 530 531 return 0; 532} 533 534static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 535 struct inode *inode, struct jffs2_full_dnode *fn, 536 __u32 start, __u32 end) 537{ 538 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 539 struct jffs2_full_dnode *new_fn; 540 struct jffs2_raw_inode ri; 541 __u32 alloclen, phys_ofs, offset, orig_end; 542 int ret = 0; 543 unsigned char *comprbuf = NULL, *writebuf; 544 struct page *pg; 545 unsigned char *pg_ptr; 546 547 548 memset(&ri, 0, sizeof(ri)); 549 550 D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%lu from offset 0x%x to 0x%x\n", 551 inode->i_ino, start, end)); 552 553 orig_end = end; 554 555 556 /* If we're looking at the last node in the block we're 557 garbage-collecting, we allow ourselves to merge as if the 558 block was already erasing. We're likely to be GC'ing a 559 partial page, and the next block we GC is likely to have 560 the other half of this page right at the beginning, which 561 means we'd expand it _then_, as nr_erasing_blocks would have 562 increased since we checked, and in doing so would obsolete 563 the partial node which we'd have written here. Meaning that 564 the GC would churn and churn, and just leave dirty blocks in 565 it's wake. 566 */ 567 if(c->nr_free_blocks + c->nr_erasing_blocks > JFFS2_RESERVED_BLOCKS_GCMERGE - (fn->raw->next_phys?0:1)) { 568 /* Shitloads of space */ 569 start &= ~(PAGE_CACHE_SIZE-1); 570 end = min_t(__u32, start + PAGE_CACHE_SIZE, inode->i_size); 571 D1(printk(KERN_DEBUG "Plenty of free space, so expanding to write from offset 0x%x to 0x%x\n", 572 start, end)); 573 if (end < orig_end) { 574 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); 575 end = orig_end; 576 } 577 } 578 579 /* First, use readpage() to read the appropriate page into the page cache */ 580 /* Q: What happens if we actually try to GC the _same_ page for which commit_write() 581 * triggered garbage collection in the first place? 582 * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the 583 * page OK. We'll actually write it out again in commit_write, which is a little 584 * suboptimal, but at least we're correct. 585 */ 586 pg = read_cache_page(inode->i_mapping, start >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode); 587 588 if (IS_ERR(pg)) { 589 printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg)); 590 return PTR_ERR(pg); 591 } 592 pg_ptr = (char *)kmap(pg); 593 comprbuf = kmalloc(end - start, GFP_KERNEL); 594 595 offset = start; 596 while(offset < orig_end) { 597 __u32 datalen; 598 __u32 cdatalen; 599 char comprtype = JFFS2_COMPR_NONE; 600 601 ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen); 602 603 if (ret) { 604 printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dnode failed: %d\n", 605 sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret); 606 break; 607 } 608 cdatalen = min(alloclen - sizeof(ri), end - offset); 609 datalen = end - offset; 610 611 writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1)); 612 613 if (comprbuf) { 614 comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen); 615 } 616 if (comprtype) { 617 writebuf = comprbuf; 618 } else { 619 datalen = cdatalen; 620 } 621 ri.magic = JFFS2_MAGIC_BITMASK; 622 ri.nodetype = JFFS2_NODETYPE_INODE; 623 ri.totlen = sizeof(ri) + cdatalen; 624 ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); 625 626 ri.ino = inode->i_ino; 627 ri.version = ++f->highest_version; 628 ri.mode = inode->i_mode; 629 ri.uid = inode->i_uid; 630 ri.gid = inode->i_gid; 631 ri.isize = inode->i_size; 632 ri.atime = inode->i_atime; 633 ri.ctime = inode->i_ctime; 634 ri.mtime = inode->i_mtime; 635 ri.offset = offset; 636 ri.csize = cdatalen; 637 ri.dsize = datalen; 638 ri.compr = comprtype; 639 ri.node_crc = crc32(0, &ri, sizeof(ri)-8); 640 ri.data_crc = crc32(0, writebuf, cdatalen); 641 642 new_fn = jffs2_write_dnode(inode, &ri, writebuf, cdatalen, phys_ofs, NULL); 643 644 if (IS_ERR(new_fn)) { 645 printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); 646 ret = PTR_ERR(new_fn); 647 break; 648 } 649 ret = jffs2_add_full_dnode_to_inode(c, f, new_fn); 650 offset += datalen; 651 if (f->metadata) { 652 jffs2_mark_node_obsolete(c, f->metadata->raw); 653 jffs2_free_full_dnode(f->metadata); 654 f->metadata = NULL; 655 } 656 } 657 if (comprbuf) kfree(comprbuf); 658 659 kunmap(pg); 660 /* AAA: Judging by the unmount getting stuck in __wait_on_page, nope. */ 661 page_cache_release(pg); 662 return ret; 663} 664 665