diff options
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r-- | fs/jffs2/summary.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 7b0ed77a4c35..5d9ec8e36528 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); |
@@ -408,8 +489,94 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras | |||
408 | 489 | ||
409 | break; | 490 | break; |
410 | } | 491 | } |
492 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
493 | case JFFS2_NODETYPE_XATTR: { | ||
494 | struct jffs2_xattr_datum *xd; | ||
495 | struct jffs2_sum_xattr_flash *spx; | ||
496 | uint32_t ofs; | ||
497 | |||
498 | spx = (struct jffs2_sum_xattr_flash *)sp; | ||
499 | ofs = jeb->offset + je32_to_cpu(spx->offset); | ||
500 | dbg_summary("xattr at %#08x (xid=%u, version=%u)\n", ofs, | ||
501 | je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); | ||
502 | raw = jffs2_alloc_raw_node_ref(); | ||
503 | if (!raw) { | ||
504 | JFFS2_NOTICE("allocation of node reference failed\n"); | ||
505 | kfree(summary); | ||
506 | return -ENOMEM; | ||
507 | } | ||
508 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid), | ||
509 | je32_to_cpu(spx->version)); | ||
510 | if (IS_ERR(xd)) { | ||
511 | JFFS2_NOTICE("allocation of xattr_datum failed\n"); | ||
512 | jffs2_free_raw_node_ref(raw); | ||
513 | kfree(summary); | ||
514 | return PTR_ERR(xd); | ||
515 | } | ||
516 | xd->node = raw; | ||
411 | 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 | list_add_tail(&ref->ilist, &c->xattr_temp); | ||
560 | |||
561 | raw->__totlen = PAD(sizeof(struct jffs2_raw_xref)); | ||
562 | raw->flash_offset = ofs | REF_UNCHECKED; | ||
563 | raw->next_phys = NULL; | ||
564 | raw->next_in_ino = (void *)ref; | ||
565 | if (!jeb->first_node) | ||
566 | jeb->first_node = raw; | ||
567 | if (jeb->last_node) | ||
568 | jeb->last_node->next_phys = raw; | ||
569 | jeb->last_node = raw; | ||
570 | |||
571 | UNCHECKED_SPACE(PAD(sizeof(struct jffs2_raw_xref))); | ||
572 | *pseudo_random += ofs; | ||
573 | sp += JFFS2_SUMMARY_XREF_SIZE; | ||
574 | |||
575 | break; | ||
576 | } | ||
577 | #endif | ||
412 | default : { | 578 | default : { |
579 | printk("nodetype = %#04x\n",je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)); | ||
413 | JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); | 580 | JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); |
414 | kfree(summary); | 581 | kfree(summary); |
415 | return -EIO; | 582 | return -EIO; |
@@ -617,7 +784,31 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
617 | 784 | ||
618 | break; | 785 | break; |
619 | } | 786 | } |
787 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
788 | case JFFS2_NODETYPE_XATTR: { | ||
789 | struct jffs2_sum_xattr_flash *sxattr_ptr = wpage; | ||
790 | |||
791 | temp = c->summary->sum_list_head; | ||
792 | sxattr_ptr->nodetype = temp->x.nodetype; | ||
793 | sxattr_ptr->xid = temp->x.xid; | ||
794 | sxattr_ptr->version = temp->x.version; | ||
795 | sxattr_ptr->offset = temp->x.offset; | ||
796 | sxattr_ptr->totlen = temp->x.totlen; | ||
797 | |||
798 | wpage += JFFS2_SUMMARY_XATTR_SIZE; | ||
799 | break; | ||
800 | } | ||
801 | case JFFS2_NODETYPE_XREF: { | ||
802 | struct jffs2_sum_xref_flash *sxref_ptr = wpage; | ||
803 | |||
804 | temp = c->summary->sum_list_head; | ||
805 | sxref_ptr->nodetype = temp->r.nodetype; | ||
806 | sxref_ptr->offset = temp->r.offset; | ||
620 | 807 | ||
808 | wpage += JFFS2_SUMMARY_XREF_SIZE; | ||
809 | break; | ||
810 | } | ||
811 | #endif | ||
621 | default : { | 812 | default : { |
622 | BUG(); /* unknown node in summary information */ | 813 | BUG(); /* unknown node in summary information */ |
623 | } | 814 | } |