diff options
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r-- | fs/jffs2/summary.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 82a3706c54d8..5dbe87b67ab6 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Zoltan Sogor <weth@inf.u-szeged.hu>, | 5 | * Zoltan Sogor <weth@inf.u-szeged.hu>, |
6 | * Patrik Kluba <pajko@halom.u-szeged.hu>, | 6 | * Patrik Kluba <pajko@halom.u-szeged.hu>, |
7 | * University of Szeged, Hungary | 7 | * University of Szeged, Hungary |
8 | * 2005 KaiGai Kohei <kaigai@ak.jp.nec.com> | ||
8 | * | 9 | * |
9 | * For licensing information, see the file 'LICENCE' in this directory. | 10 | * For licensing information, see the file 'LICENCE' in this directory. |
10 | * | 11 | * |
@@ -81,6 +82,19 @@ static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item) | |||
81 | dbg_summary("dirent (%u) added to summary\n", | 82 | dbg_summary("dirent (%u) added to summary\n", |
82 | je32_to_cpu(item->d.ino)); | 83 | je32_to_cpu(item->d.ino)); |
83 | break; | 84 | break; |
85 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
86 | case JFFS2_NODETYPE_XATTR: | ||
87 | s->sum_size += JFFS2_SUMMARY_XATTR_SIZE; | ||
88 | s->sum_num++; | ||
89 | dbg_summary("xattr (xid=%u, version=%u) added to summary\n", | ||
90 | je32_to_cpu(item->x.xid), je32_to_cpu(item->x.version)); | ||
91 | break; | ||
92 | case JFFS2_NODETYPE_XREF: | ||
93 | s->sum_size += JFFS2_SUMMARY_XREF_SIZE; | ||
94 | s->sum_num++; | ||
95 | dbg_summary("xref added to summary\n"); | ||
96 | break; | ||
97 | #endif | ||
84 | default: | 98 | default: |
85 | JFFS2_WARNING("UNKNOWN node type %u\n", | 99 | JFFS2_WARNING("UNKNOWN node type %u\n", |
86 | je16_to_cpu(item->u.nodetype)); | 100 | je16_to_cpu(item->u.nodetype)); |
@@ -141,6 +155,40 @@ int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *r | |||
141 | return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); | 155 | return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp); |
142 | } | 156 | } |
143 | 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(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL); | ||
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(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL); | ||
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 | ||
144 | /* Cleanup every collected summary information */ | 192 | /* Cleanup every collected summary information */ |
145 | 193 | ||
146 | static void jffs2_sum_clean_collected(struct jffs2_summary *s) | 194 | static void jffs2_sum_clean_collected(struct jffs2_summary *s) |
@@ -259,7 +307,40 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, | |||
259 | 307 | ||
260 | return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); | 308 | return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); |
261 | } | 309 | } |
310 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
311 | case JFFS2_NODETYPE_XATTR: { | ||
312 | struct jffs2_sum_xattr_mem *temp; | ||
313 | if (je32_to_cpu(node->x.version) == 0xffffffff) | ||
314 | return 0; | ||
315 | temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL); | ||
316 | if (!temp) | ||
317 | goto no_mem; | ||
262 | 318 | ||
319 | temp->nodetype = node->x.nodetype; | ||
320 | temp->xid = node->x.xid; | ||
321 | temp->version = node->x.version; | ||
322 | temp->totlen = node->x.totlen; | ||
323 | temp->offset = cpu_to_je32(ofs); | ||
324 | temp->next = NULL; | ||
325 | |||
326 | return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); | ||
327 | } | ||
328 | case JFFS2_NODETYPE_XREF: { | ||
329 | struct jffs2_sum_xref_mem *temp; | ||
330 | |||
331 | if (je32_to_cpu(node->r.ino) == 0xffffffff | ||
332 | && je32_to_cpu(node->r.xid) == 0xffffffff) | ||
333 | return 0; | ||
334 | temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL); | ||
335 | if (!temp) | ||
336 | goto no_mem; | ||
337 | temp->nodetype = node->r.nodetype; | ||
338 | temp->offset = cpu_to_je32(ofs); | ||
339 | temp->next = NULL; | ||
340 | |||
341 | return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp); | ||
342 | } | ||
343 | #endif | ||
263 | case JFFS2_NODETYPE_PADDING: | 344 | case JFFS2_NODETYPE_PADDING: |
264 | dbg_summary("node PADDING\n"); | 345 | dbg_summary("node PADDING\n"); |
265 | c->summary->sum_padded += je32_to_cpu(node->u.totlen); | 346 | c->summary->sum_padded += je32_to_cpu(node->u.totlen); |
@@ -402,8 +483,101 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
402 | 483 | ||
403 | break; | 484 | break; |
404 | } | 485 | } |
486 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
487 | case JFFS2_NODETYPE_XATTR: { | ||
488 | struct jffs2_xattr_datum *xd; | ||
489 | struct jffs2_sum_xattr_flash *spx; | ||
490 | uint32_t ofs; | ||
491 | |||
492 | spx = (struct jffs2_sum_xattr_flash *)sp; | ||
493 | ofs = jeb->offset + je32_to_cpu(spx->offset); | ||
494 | dbg_summary("xattr at %#08x (xid=%u, version=%u)\n", ofs, | ||
495 | je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); | ||
496 | raw = jffs2_alloc_raw_node_ref(); | ||
497 | if (!raw) { | ||
498 | JFFS2_NOTICE("allocation of node reference failed\n"); | ||
499 | kfree(summary); | ||
500 | return -ENOMEM; | ||
501 | } | ||
502 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid), | ||
503 | je32_to_cpu(spx->version)); | ||
504 | if (IS_ERR(xd)) { | ||
505 | jffs2_free_raw_node_ref(raw); | ||
506 | if (PTR_ERR(xd) == -EEXIST) { | ||
507 | /* a newer version of xd exists */ | ||
508 | DIRTY_SPACE(je32_to_cpu(spx->totlen)); | ||
509 | sp += JFFS2_SUMMARY_XATTR_SIZE; | ||
510 | break; | ||
511 | } | ||
512 | JFFS2_NOTICE("allocation of xattr_datum failed\n"); | ||
513 | kfree(summary); | ||
514 | return PTR_ERR(xd); | ||
515 | } | ||
516 | xd->node = raw; | ||
517 | |||
518 | raw->flash_offset = ofs | REF_UNCHECKED; | ||
519 | raw->__totlen = PAD(je32_to_cpu(spx->totlen)); | ||
520 | raw->next_phys = NULL; | ||
521 | raw->next_in_ino = (void *)xd; | ||
522 | if (!jeb->first_node) | ||
523 | jeb->first_node = raw; | ||
524 | if (jeb->last_node) | ||
525 | jeb->last_node->next_phys = raw; | ||
526 | jeb->last_node = raw; | ||
527 | |||
528 | *pseudo_random += je32_to_cpu(spx->xid); | ||
529 | UNCHECKED_SPACE(je32_to_cpu(spx->totlen)); | ||
530 | sp += JFFS2_SUMMARY_XATTR_SIZE; | ||
531 | |||
532 | break; | ||
533 | } | ||
534 | case JFFS2_NODETYPE_XREF: { | ||
535 | struct jffs2_xattr_ref *ref; | ||
536 | struct jffs2_sum_xref_flash *spr; | ||
537 | uint32_t ofs; | ||
538 | |||
539 | spr = (struct jffs2_sum_xref_flash *)sp; | ||
540 | ofs = jeb->offset + je32_to_cpu(spr->offset); | ||
541 | dbg_summary("xref at %#08x (xid=%u, ino=%u)\n", ofs, | ||
542 | je32_to_cpu(spr->xid), je32_to_cpu(spr->ino)); | ||
543 | raw = jffs2_alloc_raw_node_ref(); | ||
544 | if (!raw) { | ||
545 | JFFS2_NOTICE("allocation of node reference failed\n"); | ||
546 | kfree(summary); | ||
547 | return -ENOMEM; | ||
548 | } | ||
549 | ref = jffs2_alloc_xattr_ref(); | ||
550 | if (!ref) { | ||
551 | JFFS2_NOTICE("allocation of xattr_datum failed\n"); | ||
552 | jffs2_free_raw_node_ref(raw); | ||
553 | kfree(summary); | ||
554 | return -ENOMEM; | ||
555 | } | ||
556 | ref->ino = 0xfffffffe; | ||
557 | ref->xid = 0xfffffffd; | ||
558 | ref->node = raw; | ||
559 | ref->next = c->xref_temp; | ||
560 | c->xref_temp = ref; | ||
561 | |||
562 | raw->__totlen = PAD(sizeof(struct jffs2_raw_xref)); | ||
563 | raw->flash_offset = ofs | REF_UNCHECKED; | ||
564 | raw->next_phys = NULL; | ||
565 | raw->next_in_ino = (void *)ref; | ||
566 | if (!jeb->first_node) | ||
567 | jeb->first_node = raw; | ||
568 | if (jeb->last_node) | ||
569 | jeb->last_node->next_phys = raw; | ||
570 | jeb->last_node = raw; | ||
571 | |||
572 | UNCHECKED_SPACE(PAD(sizeof(struct jffs2_raw_xref))); | ||
573 | *pseudo_random += ofs; | ||
574 | sp += JFFS2_SUMMARY_XREF_SIZE; | ||
405 | 575 | ||
576 | break; | ||
577 | } | ||
578 | #endif | ||
406 | default : { | 579 | default : { |
580 | printk("nodetype = %#04x\n",je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)); | ||
407 | JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); | 581 | JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); |
408 | return -EIO; | 582 | return -EIO; |
409 | } | 583 | } |
@@ -593,7 +767,31 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
593 | 767 | ||
594 | break; | 768 | break; |
595 | } | 769 | } |
770 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
771 | case JFFS2_NODETYPE_XATTR: { | ||
772 | struct jffs2_sum_xattr_flash *sxattr_ptr = wpage; | ||
773 | |||
774 | temp = c->summary->sum_list_head; | ||
775 | sxattr_ptr->nodetype = temp->x.nodetype; | ||
776 | sxattr_ptr->xid = temp->x.xid; | ||
777 | sxattr_ptr->version = temp->x.version; | ||
778 | sxattr_ptr->offset = temp->x.offset; | ||
779 | sxattr_ptr->totlen = temp->x.totlen; | ||
780 | |||
781 | wpage += JFFS2_SUMMARY_XATTR_SIZE; | ||
782 | break; | ||
783 | } | ||
784 | case JFFS2_NODETYPE_XREF: { | ||
785 | struct jffs2_sum_xref_flash *sxref_ptr = wpage; | ||
786 | |||
787 | temp = c->summary->sum_list_head; | ||
788 | sxref_ptr->nodetype = temp->r.nodetype; | ||
789 | sxref_ptr->offset = temp->r.offset; | ||
596 | 790 | ||
791 | wpage += JFFS2_SUMMARY_XREF_SIZE; | ||
792 | break; | ||
793 | } | ||
794 | #endif | ||
597 | default : { | 795 | default : { |
598 | BUG(); /* unknown node in summary information */ | 796 | BUG(); /* unknown node in summary information */ |
599 | } | 797 | } |