aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/summary.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r--fs/jffs2/summary.c198
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
159int 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
177int 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
146static void jffs2_sum_clean_collected(struct jffs2_summary *s) 194static 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 : {
580printk("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 }