1 /* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, 5 * Zoltan Sogor <weth@inf.u-szeged.hu>, 6 * Patrik Kluba <pajko@halom.u-szeged.hu>, 7 * University of Szeged, Hungary 8 * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com> 9 * 10 * For licensing information, see the file 'LICENCE' in this directory. 11 * 12 */ 13 14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 16 #include <linux/kernel.h> 17 #include <linux/slab.h> 18 #include <linux/mtd/mtd.h> 19 #include <linux/pagemap.h> 20 #include <linux/crc32.h> 21 #include <linux/compiler.h> 22 #include <linux/vmalloc.h> 23 #include "nodelist.h" 24 #include "debug.h" 25 26 int jffs2_sum_init(struct jffs2_sb_info *c) 27 { 28 uint32_t sum_size = min_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); 29 30 c->summary = kzalloc_obj(struct jffs2_summary); 31 32 if (!c->summary) { 33 JFFS2_WARNING("Can't allocate memory for summary information!\n"); 34 return -ENOMEM; 35 } 36 37 c->summary->sum_buf = kmalloc(sum_size, GFP_KERNEL); 38 39 if (!c->summary->sum_buf) { 40 JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n"); 41 kfree(c->summary); 42 return -ENOMEM; 43 } 44 45 dbg_summary("returned successfully\n"); 46 47 return 0; 48 } 49 50 void jffs2_sum_exit(struct jffs2_sb_info *c) 51 { 52 dbg_summary("called\n"); 53 54 jffs2_sum_disable_collecting(c->summary); 55 56 kfree(c->summary->sum_buf); 57 c->summary->sum_buf = NULL; 58 59 kfree(c->summary); 60 c->summary = NULL; 61 } 62 63 static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item) 64 { 65 if (!s->sum_list_head) 66 s->sum_list_head = (union jffs2_sum_mem *) item; 67 if (s->sum_list_tail) 68 s->sum_list_tail->u.next = (union jffs2_sum_mem *) item; 69 s->sum_list_tail = (union jffs2_sum_mem *) item; 70 71 switch (je16_to_cpu(item->u.nodetype)) { 72 case JFFS2_NODETYPE_INODE: 73 s->sum_size += JFFS2_SUMMARY_INODE_SIZE; 74 s->sum_num++; 75 dbg_summary("inode (%u) added to summary\n", 76 je32_to_cpu(item->i.inode)); 77 break; 78 case JFFS2_NODETYPE_DIRENT: 79 s->sum_size += JFFS2_SUMMARY_DIRENT_SIZE(item->d.nsize); 80 s->sum_num++; 81 dbg_summary("dirent (%u) added to summary\n", 82 je32_to_cpu(item->d.ino)); 83 break; 84 #ifdef CONFIG_JFFS2_FS_XATTR 85 case JFFS2_NODETYPE_XATTR: 86 s->sum_size += JFFS2_SUMMARY_XATTR_SIZE; 87 s->sum_num++; 88 dbg_summary("xattr (xid=%u, version=%u) added to summary\n", 89 je32_to_cpu(item->x.xid), je32_to_cpu(item->x.version)); 90 break; 91 case JFFS2_NODETYPE_XREF: 92 s->sum_size += JFFS2_SUMMARY_XREF_SIZE; 93 s->sum_num++; 94 dbg_summary("xref added to summary\n"); 95 break; 96 #endif 97 default: 98 JFFS2_WARNING("UNKNOWN node type %u\n", 99 je16_to_cpu(item->u.nodetype)); 100 return 1; 101 } 102 return 0; 103 } 104 105 106 /* The following 3 functions are called from scan.c to collect summary info for not closed jeb */ 107 108 int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size) 109 { 110 dbg_summary("called with %u\n", size); 111 s->sum_padded += size; 112 return 0; 113 } 114 115 int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, 116 uint32_t ofs) 117 { 118 struct jffs2_sum_inode_mem *temp = kmalloc_obj(struct jffs2_sum_inode_mem, 119 GFP_KERNEL); 120 121 if (!temp) 122 return -ENOMEM; 123 124 temp->nodetype = ri->nodetype; 125 temp->inode = ri->ino; 126 temp->version = ri->version; 127 temp->offset = cpu_to_je32(ofs); /* relative offset from the beginning of the jeb */ 128 temp->totlen = ri->totlen; 129 temp->next = NULL; 130 131 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); 132 } 133 134 int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, 135 uint32_t ofs) 136 { 137 struct jffs2_sum_dirent_mem *temp = 138 kmalloc(sizeof(struct jffs2_sum_dirent_mem) + rd->nsize, GFP_KERNEL); 139 140 if (!temp) 141 return -ENOMEM; 142 143 temp->nodetype = rd->nodetype; 144 temp->totlen = rd->totlen; 145 temp->offset = cpu_to_je32(ofs); /* relative from the beginning of the jeb */ 146 temp->pino = rd->pino; 147 temp->version = rd->version; 148 temp->ino = rd->ino; 149 temp->nsize = rd->nsize; 150 temp->type = rd->type; 151 temp->next = NULL; 152 153 memcpy(temp->name, rd->name, rd->nsize); 154 155 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); 156 } 157 158 #ifdef CONFIG_JFFS2_FS_XATTR 159 int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, uint32_t ofs) 160 { 161 struct jffs2_sum_xattr_mem *temp; 162 163 temp = kmalloc_obj(struct jffs2_sum_xattr_mem); 164 if (!temp) 165 return -ENOMEM; 166 167 temp->nodetype = rx->nodetype; 168 temp->xid = rx->xid; 169 temp->version = rx->version; 170 temp->offset = cpu_to_je32(ofs); 171 temp->totlen = rx->totlen; 172 temp->next = NULL; 173 174 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); 175 } 176 177 int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, uint32_t ofs) 178 { 179 struct jffs2_sum_xref_mem *temp; 180 181 temp = kmalloc_obj(struct jffs2_sum_xref_mem); 182 if (!temp) 183 return -ENOMEM; 184 185 temp->nodetype = rr->nodetype; 186 temp->offset = cpu_to_je32(ofs); 187 temp->next = NULL; 188 189 return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); 190 } 191 #endif 192 /* Cleanup every collected summary information */ 193 194 static void jffs2_sum_clean_collected(struct jffs2_summary *s) 195 { 196 union jffs2_sum_mem *temp; 197 198 if (!s->sum_list_head) { 199 dbg_summary("already empty\n"); 200 } 201 while (s->sum_list_head) { 202 temp = s->sum_list_head; 203 s->sum_list_head = s->sum_list_head->u.next; 204 kfree(temp); 205 } 206 s->sum_list_tail = NULL; 207 s->sum_padded = 0; 208 s->sum_num = 0; 209 } 210 211 void jffs2_sum_reset_collected(struct jffs2_summary *s) 212 { 213 dbg_summary("called\n"); 214 jffs2_sum_clean_collected(s); 215 s->sum_size = 0; 216 } 217 218 void jffs2_sum_disable_collecting(struct jffs2_summary *s) 219 { 220 dbg_summary("called\n"); 221 jffs2_sum_clean_collected(s); 222 s->sum_size = JFFS2_SUMMARY_NOSUM_SIZE; 223 } 224 225 int jffs2_sum_is_disabled(struct jffs2_summary *s) 226 { 227 return (s->sum_size == JFFS2_SUMMARY_NOSUM_SIZE); 228 } 229 230 /* Move the collected summary information into sb (called from scan.c) */ 231 232 void jffs2_sum_move_collected(struct jffs2_sb_info *c, struct jffs2_summary *s) 233 { 234 dbg_summary("oldsize=0x%x oldnum=%u => newsize=0x%x newnum=%u\n", 235 c->summary->sum_size, c->summary->sum_num, 236 s->sum_size, s->sum_num); 237 238 c->summary->sum_size = s->sum_size; 239 c->summary->sum_num = s->sum_num; 240 c->summary->sum_padded = s->sum_padded; 241 c->summary->sum_list_head = s->sum_list_head; 242 c->summary->sum_list_tail = s->sum_list_tail; 243 244 s->sum_list_head = s->sum_list_tail = NULL; 245 } 246 247 /* Called from wbuf.c to collect writed node info */ 248 249 int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, 250 unsigned long count, uint32_t ofs) 251 { 252 union jffs2_node_union *node; 253 struct jffs2_eraseblock *jeb; 254 255 if (c->summary->sum_size == JFFS2_SUMMARY_NOSUM_SIZE) { 256 dbg_summary("Summary is disabled for this jeb! Skipping summary info!\n"); 257 return 0; 258 } 259 260 node = invecs[0].iov_base; 261 jeb = &c->blocks[ofs / c->sector_size]; 262 ofs -= jeb->offset; 263 264 switch (je16_to_cpu(node->u.nodetype)) { 265 case JFFS2_NODETYPE_INODE: { 266 struct jffs2_sum_inode_mem *temp = 267 kmalloc_obj(struct jffs2_sum_inode_mem, 268 GFP_KERNEL); 269 270 if (!temp) 271 goto no_mem; 272 273 temp->nodetype = node->i.nodetype; 274 temp->inode = node->i.ino; 275 temp->version = node->i.version; 276 temp->offset = cpu_to_je32(ofs); 277 temp->totlen = node->i.totlen; 278 temp->next = NULL; 279 280 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); 281 } 282 283 case JFFS2_NODETYPE_DIRENT: { 284 struct jffs2_sum_dirent_mem *temp = 285 kmalloc(sizeof(struct jffs2_sum_dirent_mem) + node->d.nsize, GFP_KERNEL); 286 287 if (!temp) 288 goto no_mem; 289 290 temp->nodetype = node->d.nodetype; 291 temp->totlen = node->d.totlen; 292 temp->offset = cpu_to_je32(ofs); 293 temp->pino = node->d.pino; 294 temp->version = node->d.version; 295 temp->ino = node->d.ino; 296 temp->nsize = node->d.nsize; 297 temp->type = node->d.type; 298 temp->next = NULL; 299 300 switch (count) { 301 case 1: 302 memcpy(temp->name,node->d.name,node->d.nsize); 303 break; 304 305 case 2: 306 memcpy(temp->name,invecs[1].iov_base,node->d.nsize); 307 break; 308 309 default: 310 BUG(); /* impossible count value */ 311 break; 312 } 313 314 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); 315 } 316 #ifdef CONFIG_JFFS2_FS_XATTR 317 case JFFS2_NODETYPE_XATTR: { 318 struct jffs2_sum_xattr_mem *temp; 319 temp = kmalloc_obj(struct jffs2_sum_xattr_mem, 320 GFP_KERNEL); 321 if (!temp) 322 goto no_mem; 323 324 temp->nodetype = node->x.nodetype; 325 temp->xid = node->x.xid; 326 temp->version = node->x.version; 327 temp->totlen = node->x.totlen; 328 temp->offset = cpu_to_je32(ofs); 329 temp->next = NULL; 330 331 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); 332 } 333 case JFFS2_NODETYPE_XREF: { 334 struct jffs2_sum_xref_mem *temp; 335 temp = kmalloc_obj(struct jffs2_sum_xref_mem, 336 GFP_KERNEL); 337 if (!temp) 338 goto no_mem; 339 temp->nodetype = node->r.nodetype; 340 temp->offset = cpu_to_je32(ofs); 341 temp->next = NULL; 342 343 return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); 344 } 345 #endif 346 case JFFS2_NODETYPE_PADDING: 347 dbg_summary("node PADDING\n"); 348 c->summary->sum_padded += je32_to_cpu(node->u.totlen); 349 break; 350 351 case JFFS2_NODETYPE_CLEANMARKER: 352 dbg_summary("node CLEANMARKER\n"); 353 break; 354 355 case JFFS2_NODETYPE_SUMMARY: 356 dbg_summary("node SUMMARY\n"); 357 break; 358 359 default: 360 /* If you implement a new node type you should also implement 361 summary support for it or disable summary. 362 */ 363 BUG(); 364 break; 365 } 366 367 return 0; 368 369 no_mem: 370 JFFS2_WARNING("MEMORY ALLOCATION ERROR!"); 371 return -ENOMEM; 372 } 373 374 static struct jffs2_raw_node_ref *sum_link_node_ref(struct jffs2_sb_info *c, 375 struct jffs2_eraseblock *jeb, 376 uint32_t ofs, uint32_t len, 377 struct jffs2_inode_cache *ic) 378 { 379 /* If there was a gap, mark it dirty */ 380 if ((ofs & ~3) > c->sector_size - jeb->free_size) { 381 /* Ew. Summary doesn't actually tell us explicitly about dirty space */ 382 jffs2_scan_dirty_space(c, jeb, (ofs & ~3) - (c->sector_size - jeb->free_size)); 383 } 384 385 return jffs2_link_node_ref(c, jeb, jeb->offset + ofs, len, ic); 386 } 387 388 /* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */ 389 390 static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 391 struct jffs2_raw_summary *summary, uint32_t *pseudo_random) 392 { 393 struct jffs2_inode_cache *ic; 394 struct jffs2_full_dirent *fd; 395 void *sp; 396 int i, ino; 397 int err; 398 399 sp = summary->sum; 400 401 for (i=0; i<je32_to_cpu(summary->sum_num); i++) { 402 dbg_summary("processing summary index %d\n", i); 403 404 cond_resched(); 405 406 /* Make sure there's a spare ref for dirty space */ 407 err = jffs2_prealloc_raw_node_refs(c, jeb, 2); 408 if (err) 409 return err; 410 411 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) { 412 case JFFS2_NODETYPE_INODE: { 413 struct jffs2_sum_inode_flash *spi; 414 spi = sp; 415 416 ino = je32_to_cpu(spi->inode); 417 418 dbg_summary("Inode at 0x%08x-0x%08x\n", 419 jeb->offset + je32_to_cpu(spi->offset), 420 jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spi->totlen)); 421 422 ic = jffs2_scan_make_ino_cache(c, ino); 423 if (!ic) { 424 JFFS2_NOTICE("scan_make_ino_cache failed\n"); 425 return -ENOMEM; 426 } 427 428 sum_link_node_ref(c, jeb, je32_to_cpu(spi->offset) | REF_UNCHECKED, 429 PAD(je32_to_cpu(spi->totlen)), ic); 430 431 *pseudo_random += je32_to_cpu(spi->version); 432 433 sp += JFFS2_SUMMARY_INODE_SIZE; 434 435 break; 436 } 437 438 case JFFS2_NODETYPE_DIRENT: { 439 struct jffs2_sum_dirent_flash *spd; 440 int checkedlen; 441 spd = sp; 442 443 dbg_summary("Dirent at 0x%08x-0x%08x\n", 444 jeb->offset + je32_to_cpu(spd->offset), 445 jeb->offset + je32_to_cpu(spd->offset) + je32_to_cpu(spd->totlen)); 446 447 448 /* This should never happen, but https://dev.laptop.org/ticket/4184 */ 449 checkedlen = strnlen(spd->name, spd->nsize); 450 if (!checkedlen) { 451 pr_err("Dirent at %08x has zero at start of name. Aborting mount.\n", 452 jeb->offset + 453 je32_to_cpu(spd->offset)); 454 return -EIO; 455 } 456 if (checkedlen < spd->nsize) { 457 pr_err("Dirent at %08x has zeroes in name. Truncating to %d chars\n", 458 jeb->offset + 459 je32_to_cpu(spd->offset), 460 checkedlen); 461 } 462 463 464 fd = jffs2_alloc_full_dirent(checkedlen+1); 465 if (!fd) 466 return -ENOMEM; 467 468 memcpy(&fd->name, spd->name, checkedlen); 469 fd->name[checkedlen] = 0; 470 471 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino)); 472 if (!ic) { 473 jffs2_free_full_dirent(fd); 474 return -ENOMEM; 475 } 476 477 fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_UNCHECKED, 478 PAD(je32_to_cpu(spd->totlen)), ic); 479 480 fd->next = NULL; 481 fd->version = je32_to_cpu(spd->version); 482 fd->ino = je32_to_cpu(spd->ino); 483 fd->nhash = full_name_hash(NULL, fd->name, checkedlen); 484 fd->type = spd->type; 485 486 jffs2_add_fd_to_list(c, fd, &ic->scan_dents); 487 488 *pseudo_random += je32_to_cpu(spd->version); 489 490 sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize); 491 492 break; 493 } 494 #ifdef CONFIG_JFFS2_FS_XATTR 495 case JFFS2_NODETYPE_XATTR: { 496 struct jffs2_xattr_datum *xd; 497 struct jffs2_sum_xattr_flash *spx; 498 499 spx = (struct jffs2_sum_xattr_flash *)sp; 500 dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n", 501 jeb->offset + je32_to_cpu(spx->offset), 502 jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen), 503 je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); 504 505 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid), 506 je32_to_cpu(spx->version)); 507 if (IS_ERR(xd)) 508 return PTR_ERR(xd); 509 if (xd->version > je32_to_cpu(spx->version)) { 510 /* node is not the newest one */ 511 struct jffs2_raw_node_ref *raw 512 = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED, 513 PAD(je32_to_cpu(spx->totlen)), NULL); 514 raw->next_in_ino = xd->node->next_in_ino; 515 xd->node->next_in_ino = raw; 516 } else { 517 xd->version = je32_to_cpu(spx->version); 518 sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED, 519 PAD(je32_to_cpu(spx->totlen)), (void *)xd); 520 } 521 *pseudo_random += je32_to_cpu(spx->xid); 522 sp += JFFS2_SUMMARY_XATTR_SIZE; 523 524 break; 525 } 526 case JFFS2_NODETYPE_XREF: { 527 struct jffs2_xattr_ref *ref; 528 struct jffs2_sum_xref_flash *spr; 529 530 spr = (struct jffs2_sum_xref_flash *)sp; 531 dbg_summary("xref at %#08x-%#08x\n", 532 jeb->offset + je32_to_cpu(spr->offset), 533 jeb->offset + je32_to_cpu(spr->offset) + 534 (uint32_t)PAD(sizeof(struct jffs2_raw_xref))); 535 536 ref = jffs2_alloc_xattr_ref(); 537 if (!ref) { 538 JFFS2_NOTICE("allocation of xattr_datum failed\n"); 539 return -ENOMEM; 540 } 541 ref->next = c->xref_temp; 542 c->xref_temp = ref; 543 544 sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED, 545 PAD(sizeof(struct jffs2_raw_xref)), (void *)ref); 546 547 *pseudo_random += ref->node->flash_offset; 548 sp += JFFS2_SUMMARY_XREF_SIZE; 549 550 break; 551 } 552 #endif 553 default : { 554 uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype); 555 JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype); 556 if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT) 557 return -EIO; 558 559 /* For compatible node types, just fall back to the full scan */ 560 c->wasted_size -= jeb->wasted_size; 561 c->free_size += c->sector_size - jeb->free_size; 562 c->used_size -= jeb->used_size; 563 c->dirty_size -= jeb->dirty_size; 564 jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0; 565 jeb->free_size = c->sector_size; 566 567 jffs2_free_jeb_node_refs(c, jeb); 568 return -ENOTRECOVERABLE; 569 } 570 } 571 } 572 return 0; 573 } 574 575 /* Process the summary node - called from jffs2_scan_eraseblock() */ 576 int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 577 struct jffs2_raw_summary *summary, uint32_t sumsize, 578 uint32_t *pseudo_random) 579 { 580 struct jffs2_unknown_node crcnode; 581 int ret, ofs; 582 uint32_t crc; 583 584 ofs = c->sector_size - sumsize; 585 586 dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", 587 jeb->offset, jeb->offset + ofs, sumsize); 588 589 /* OK, now check for node validity and CRC */ 590 crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 591 crcnode.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY); 592 crcnode.totlen = summary->totlen; 593 crc = crc32(0, &crcnode, sizeof(crcnode)-4); 594 595 if (je32_to_cpu(summary->hdr_crc) != crc) { 596 dbg_summary("Summary node header is corrupt (bad CRC or " 597 "no summary at all)\n"); 598 goto crc_err; 599 } 600 601 if (je32_to_cpu(summary->totlen) != sumsize) { 602 dbg_summary("Summary node is corrupt (wrong erasesize?)\n"); 603 goto crc_err; 604 } 605 606 crc = crc32(0, summary, sizeof(struct jffs2_raw_summary)-8); 607 608 if (je32_to_cpu(summary->node_crc) != crc) { 609 dbg_summary("Summary node is corrupt (bad CRC)\n"); 610 goto crc_err; 611 } 612 613 crc = crc32(0, summary->sum, sumsize - sizeof(struct jffs2_raw_summary)); 614 615 if (je32_to_cpu(summary->sum_crc) != crc) { 616 dbg_summary("Summary node data is corrupt (bad CRC)\n"); 617 goto crc_err; 618 } 619 620 if ( je32_to_cpu(summary->cln_mkr) ) { 621 622 dbg_summary("Summary : CLEANMARKER node \n"); 623 624 ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); 625 if (ret) 626 return ret; 627 628 if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) { 629 dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n", 630 je32_to_cpu(summary->cln_mkr), c->cleanmarker_size); 631 if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr))))) 632 return ret; 633 } else if (jeb->first_node) { 634 dbg_summary("CLEANMARKER node not first node in block " 635 "(0x%08x)\n", jeb->offset); 636 if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr))))) 637 return ret; 638 } else { 639 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, 640 je32_to_cpu(summary->cln_mkr), NULL); 641 } 642 } 643 644 ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random); 645 /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full 646 scan of this eraseblock. So return zero */ 647 if (ret == -ENOTRECOVERABLE) 648 return 0; 649 if (ret) 650 return ret; /* real error */ 651 652 /* for PARANOIA_CHECK */ 653 ret = jffs2_prealloc_raw_node_refs(c, jeb, 2); 654 if (ret) 655 return ret; 656 657 sum_link_node_ref(c, jeb, ofs | REF_NORMAL, sumsize, NULL); 658 659 if (unlikely(jeb->free_size)) { 660 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n", 661 jeb->free_size, jeb->offset); 662 jeb->wasted_size += jeb->free_size; 663 c->wasted_size += jeb->free_size; 664 c->free_size -= jeb->free_size; 665 jeb->free_size = 0; 666 } 667 668 return jffs2_scan_classify_jeb(c, jeb); 669 670 crc_err: 671 JFFS2_WARNING("Summary node crc error, skipping summary information.\n"); 672 673 return 0; 674 } 675 676 /* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */ 677 678 static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 679 uint32_t infosize, uint32_t datasize, int padsize) 680 { 681 struct jffs2_raw_summary isum; 682 union jffs2_sum_mem *temp; 683 struct jffs2_sum_marker *sm; 684 struct kvec vecs[2]; 685 uint32_t sum_ofs; 686 void *wpage; 687 int ret; 688 size_t retlen; 689 690 if (padsize + datasize > MAX_SUMMARY_SIZE) { 691 /* It won't fit in the buffer. Abort summary for this jeb */ 692 jffs2_sum_disable_collecting(c->summary); 693 694 JFFS2_WARNING("Summary too big (%d data, %d pad) in eraseblock at %08x\n", 695 datasize, padsize, jeb->offset); 696 /* Non-fatal */ 697 return 0; 698 } 699 /* Is there enough space for summary? */ 700 if (padsize < 0) { 701 /* don't try to write out summary for this jeb */ 702 jffs2_sum_disable_collecting(c->summary); 703 704 JFFS2_WARNING("Not enough space for summary, padsize = %d\n", 705 padsize); 706 /* Non-fatal */ 707 return 0; 708 } 709 710 memset(c->summary->sum_buf, 0xff, datasize); 711 memset(&isum, 0, sizeof(isum)); 712 713 isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 714 isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY); 715 isum.totlen = cpu_to_je32(infosize); 716 isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4)); 717 isum.padded = cpu_to_je32(c->summary->sum_padded); 718 isum.cln_mkr = cpu_to_je32(c->cleanmarker_size); 719 isum.sum_num = cpu_to_je32(c->summary->sum_num); 720 wpage = c->summary->sum_buf; 721 722 while (c->summary->sum_num) { 723 temp = c->summary->sum_list_head; 724 725 switch (je16_to_cpu(temp->u.nodetype)) { 726 case JFFS2_NODETYPE_INODE: { 727 struct jffs2_sum_inode_flash *sino_ptr = wpage; 728 729 sino_ptr->nodetype = temp->i.nodetype; 730 sino_ptr->inode = temp->i.inode; 731 sino_ptr->version = temp->i.version; 732 sino_ptr->offset = temp->i.offset; 733 sino_ptr->totlen = temp->i.totlen; 734 735 wpage += JFFS2_SUMMARY_INODE_SIZE; 736 737 break; 738 } 739 740 case JFFS2_NODETYPE_DIRENT: { 741 struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage; 742 743 sdrnt_ptr->nodetype = temp->d.nodetype; 744 sdrnt_ptr->totlen = temp->d.totlen; 745 sdrnt_ptr->offset = temp->d.offset; 746 sdrnt_ptr->pino = temp->d.pino; 747 sdrnt_ptr->version = temp->d.version; 748 sdrnt_ptr->ino = temp->d.ino; 749 sdrnt_ptr->nsize = temp->d.nsize; 750 sdrnt_ptr->type = temp->d.type; 751 752 memcpy(sdrnt_ptr->name, temp->d.name, 753 temp->d.nsize); 754 755 wpage += JFFS2_SUMMARY_DIRENT_SIZE(temp->d.nsize); 756 757 break; 758 } 759 #ifdef CONFIG_JFFS2_FS_XATTR 760 case JFFS2_NODETYPE_XATTR: { 761 struct jffs2_sum_xattr_flash *sxattr_ptr = wpage; 762 763 temp = c->summary->sum_list_head; 764 sxattr_ptr->nodetype = temp->x.nodetype; 765 sxattr_ptr->xid = temp->x.xid; 766 sxattr_ptr->version = temp->x.version; 767 sxattr_ptr->offset = temp->x.offset; 768 sxattr_ptr->totlen = temp->x.totlen; 769 770 wpage += JFFS2_SUMMARY_XATTR_SIZE; 771 break; 772 } 773 case JFFS2_NODETYPE_XREF: { 774 struct jffs2_sum_xref_flash *sxref_ptr = wpage; 775 776 temp = c->summary->sum_list_head; 777 sxref_ptr->nodetype = temp->r.nodetype; 778 sxref_ptr->offset = temp->r.offset; 779 780 wpage += JFFS2_SUMMARY_XREF_SIZE; 781 break; 782 } 783 #endif 784 default : { 785 if ((je16_to_cpu(temp->u.nodetype) & JFFS2_COMPAT_MASK) 786 == JFFS2_FEATURE_RWCOMPAT_COPY) { 787 dbg_summary("Writing unknown RWCOMPAT_COPY node type %x\n", 788 je16_to_cpu(temp->u.nodetype)); 789 jffs2_sum_disable_collecting(c->summary); 790 /* The above call removes the list, nothing more to do */ 791 goto bail_rwcompat; 792 } else { 793 BUG(); /* unknown node in summary information */ 794 } 795 } 796 } 797 798 c->summary->sum_list_head = temp->u.next; 799 kfree(temp); 800 801 c->summary->sum_num--; 802 } 803 bail_rwcompat: 804 805 jffs2_sum_reset_collected(c->summary); 806 807 wpage += padsize; 808 809 sm = wpage; 810 sm->offset = cpu_to_je32(c->sector_size - jeb->free_size); 811 sm->magic = cpu_to_je32(JFFS2_SUM_MAGIC); 812 813 isum.sum_crc = cpu_to_je32(crc32(0, c->summary->sum_buf, datasize)); 814 isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8)); 815 816 vecs[0].iov_base = &isum; 817 vecs[0].iov_len = sizeof(isum); 818 vecs[1].iov_base = c->summary->sum_buf; 819 vecs[1].iov_len = datasize; 820 821 sum_ofs = jeb->offset + c->sector_size - jeb->free_size; 822 823 dbg_summary("writing out data to flash to pos : 0x%08x\n", sum_ofs); 824 825 ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0); 826 827 if (ret || (retlen != infosize)) { 828 829 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n", 830 infosize, sum_ofs, ret, retlen); 831 832 if (retlen) { 833 /* Waste remaining space */ 834 spin_lock(&c->erase_completion_lock); 835 jffs2_link_node_ref(c, jeb, sum_ofs | REF_OBSOLETE, infosize, NULL); 836 spin_unlock(&c->erase_completion_lock); 837 } 838 839 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE; 840 841 return 0; 842 } 843 844 spin_lock(&c->erase_completion_lock); 845 jffs2_link_node_ref(c, jeb, sum_ofs | REF_NORMAL, infosize, NULL); 846 spin_unlock(&c->erase_completion_lock); 847 848 return 0; 849 } 850 851 /* Write out summary information - called from jffs2_do_reserve_space */ 852 853 int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) 854 __must_hold(&c->erase_completion_block) 855 { 856 int datasize, infosize, padsize; 857 struct jffs2_eraseblock *jeb; 858 int ret = 0; 859 860 dbg_summary("called\n"); 861 862 spin_unlock(&c->erase_completion_lock); 863 864 jeb = c->nextblock; 865 ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); 866 867 if (ret) 868 goto out; 869 870 if (!c->summary->sum_num || !c->summary->sum_list_head) { 871 JFFS2_WARNING("Empty summary info!!!\n"); 872 BUG(); 873 } 874 875 datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker); 876 infosize = sizeof(struct jffs2_raw_summary) + datasize; 877 padsize = jeb->free_size - infosize; 878 infosize += padsize; 879 datasize += padsize; 880 881 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); 882 883 out: 884 spin_lock(&c->erase_completion_lock); 885 return ret; 886 } 887