Merge git://git.infradead.org/jffs2-xattr-2.6
authorDavid Woodhouse <dwmw2@infradead.org>
Sat, 20 May 2006 16:27:32 +0000 (17:27 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Sat, 20 May 2006 16:27:32 +0000 (17:27 +0100)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
1  2 
fs/jffs2/dir.c
fs/jffs2/fs.c
fs/jffs2/gc.c
fs/jffs2/nodelist.h
fs/jffs2/os-linux.h
fs/jffs2/scan.c
fs/jffs2/summary.c
fs/jffs2/summary.h
include/linux/jffs2.h

diff --cc fs/jffs2/dir.c
Simple merge
diff --cc fs/jffs2/fs.c
Simple merge
diff --cc fs/jffs2/gc.c
Simple merge
Simple merge
Simple merge
diff --cc fs/jffs2/scan.c
@@@ -306,12 -306,142 +306,143 @@@ int jffs2_scan_classify_jeb(struct jffs
                return BLK_STATE_ALLDIRTY;
  }
  
+ #ifdef CONFIG_JFFS2_FS_XATTR
+ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+                                struct jffs2_raw_xattr *rx, uint32_t ofs,
+                                struct jffs2_summary *s)
+ {
+       struct jffs2_xattr_datum *xd;
+       struct jffs2_raw_node_ref *raw;
+       uint32_t totlen, crc;
+       crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4);
+       if (crc != je32_to_cpu(rx->node_crc)) {
+               if (je32_to_cpu(rx->node_crc) != 0xffffffff)
+                       JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
+                                     ofs, je32_to_cpu(rx->node_crc), crc);
+               DIRTY_SPACE(je32_to_cpu(rx->totlen));
+               return 0;
+       }
+       totlen = PAD(sizeof(*rx) + rx->name_len + 1 + je16_to_cpu(rx->value_len));
+       if (totlen != je32_to_cpu(rx->totlen)) {
+               JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
+                             ofs, je32_to_cpu(rx->totlen), totlen);
+               DIRTY_SPACE(je32_to_cpu(rx->totlen));
+               return 0;
+       }
+       raw =  jffs2_alloc_raw_node_ref();
+       if (!raw)
+               return -ENOMEM;
+       xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version));
+       if (IS_ERR(xd)) {
+               jffs2_free_raw_node_ref(raw);
+               if (PTR_ERR(xd) == -EEXIST) {
+                       DIRTY_SPACE(PAD(je32_to_cpu(rx->totlen)));
+                       return 0;
+               }
+               return PTR_ERR(xd);
+       }
+       xd->xprefix = rx->xprefix;
+       xd->name_len = rx->name_len;
+       xd->value_len = je16_to_cpu(rx->value_len);
+       xd->data_crc = je32_to_cpu(rx->data_crc);
+       xd->node = raw;
+       raw->__totlen = totlen;
+       raw->flash_offset = ofs | REF_PRISTINE;
+       raw->next_phys = NULL;
+       raw->next_in_ino = (void *)xd;
+       if (!jeb->first_node)
+               jeb->first_node = raw;
+       if (jeb->last_node)
+               jeb->last_node->next_phys = raw;
+       jeb->last_node = raw;
+       USED_SPACE(PAD(je32_to_cpu(rx->totlen)));
+       if (jffs2_sum_active())
+               jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset);
+       dbg_xattr("scaning xdatum at %#08x (xid=%u, version=%u)\n",
+                 ofs, xd->xid, xd->version);
+       return 0;
+ }
+ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+                               struct jffs2_raw_xref *rr, uint32_t ofs,
+                               struct jffs2_summary *s)
+ {
+       struct jffs2_xattr_ref *ref;
+       struct jffs2_raw_node_ref *raw;
+       uint32_t crc;
+       crc = crc32(0, rr, sizeof(*rr) - 4);
+       if (crc != je32_to_cpu(rr->node_crc)) {
+               if (je32_to_cpu(rr->node_crc) != 0xffffffff)
+                       JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
+                                     ofs, je32_to_cpu(rr->node_crc), crc);
+               DIRTY_SPACE(PAD(je32_to_cpu(rr->totlen)));
+               return 0;
+       }
+       if (PAD(sizeof(struct jffs2_raw_xref)) != je32_to_cpu(rr->totlen)) {
+               JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
+                             ofs, je32_to_cpu(rr->totlen),
+                             PAD(sizeof(struct jffs2_raw_xref)));
+               DIRTY_SPACE(je32_to_cpu(rr->totlen));
+               return 0;
+       }
+       ref = jffs2_alloc_xattr_ref();
+       if (!ref)
+               return -ENOMEM;
+       raw =  jffs2_alloc_raw_node_ref();
+       if (!raw) {
+               jffs2_free_xattr_ref(ref);
+               return -ENOMEM;
+       }
+       /* BEFORE jffs2_build_xattr_subsystem() called, 
+        * ref->xid is used to store 32bit xid, xd is not used
+        * ref->ino is used to store 32bit inode-number, ic is not used
+        * Thoes variables are declared as union, thus using those
+        * are exclusive. In a similar way, ref->next is temporarily
+        * used to chain all xattr_ref object. It's re-chained to
+        * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly.
+        */
+       ref->node = raw;
+       ref->ino = je32_to_cpu(rr->ino);
+       ref->xid = je32_to_cpu(rr->xid);
+       ref->next = c->xref_temp;
+       c->xref_temp = ref;
+       raw->__totlen = PAD(je32_to_cpu(rr->totlen));
+       raw->flash_offset = ofs | REF_PRISTINE;
+       raw->next_phys = NULL;
+       raw->next_in_ino = (void *)ref;
+       if (!jeb->first_node)
+               jeb->first_node = raw;
+       if (jeb->last_node)
+               jeb->last_node->next_phys = raw;
+       jeb->last_node = raw;
+       USED_SPACE(PAD(je32_to_cpu(rr->totlen)));       
+       if (jffs2_sum_active())
+               jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);
+       dbg_xattr("scan xref at %#08x (xid=%u, ino=%u)\n",
+                 ofs, ref->xid, ref->ino);
+       return 0;
+ }
+ #endif
 +/* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into
 +   the flash, XIP-style */
  static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
 -                              unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
 +                                unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {
        struct jffs2_unknown_node *node;
        struct jffs2_unknown_node crcnode;
 -      struct jffs2_sum_marker *sm;
        uint32_t ofs, prevofs;
        uint32_t hdr_crc, buf_ofs, buf_len;
        int err;
@@@ -402,9 -489,103 +483,102 @@@ static int jffs2_sum_process_sum_data(s
  
                                break;
                        }
+ #ifdef CONFIG_JFFS2_FS_XATTR
+                       case JFFS2_NODETYPE_XATTR: {
+                               struct jffs2_xattr_datum *xd;
+                               struct jffs2_sum_xattr_flash *spx;
+                               uint32_t ofs;
+                               spx = (struct jffs2_sum_xattr_flash *)sp;
+                               ofs = jeb->offset + je32_to_cpu(spx->offset);
+                               dbg_summary("xattr at %#08x (xid=%u, version=%u)\n", ofs,
+                                           je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
+                               raw = jffs2_alloc_raw_node_ref();
+                               if (!raw) {
+                                       JFFS2_NOTICE("allocation of node reference failed\n");
+                                       kfree(summary);
+                                       return -ENOMEM;
+                               }
+                               xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
+                                                               je32_to_cpu(spx->version));
+                               if (IS_ERR(xd)) {
+                                       jffs2_free_raw_node_ref(raw);
+                                       if (PTR_ERR(xd) == -EEXIST) {
+                                               /* a newer version of xd exists */
+                                               DIRTY_SPACE(je32_to_cpu(spx->totlen));
+                                               sp += JFFS2_SUMMARY_XATTR_SIZE;
+                                               break;
+                                       }
+                                       JFFS2_NOTICE("allocation of xattr_datum failed\n");
+                                       kfree(summary);
+                                       return PTR_ERR(xd);
+                               }
+                               xd->node = raw;
+                               raw->flash_offset = ofs | REF_UNCHECKED;
+                               raw->__totlen = PAD(je32_to_cpu(spx->totlen));
+                               raw->next_phys = NULL;
+                               raw->next_in_ino = (void *)xd;
+                               if (!jeb->first_node)
+                                       jeb->first_node = raw;
+                               if (jeb->last_node)
+                                       jeb->last_node->next_phys = raw;
+                               jeb->last_node = raw;
+                               *pseudo_random += je32_to_cpu(spx->xid);
+                               UNCHECKED_SPACE(je32_to_cpu(spx->totlen));
+                               sp += JFFS2_SUMMARY_XATTR_SIZE;
+                               break;
+                       }
+                       case JFFS2_NODETYPE_XREF: {
+                               struct jffs2_xattr_ref *ref;
+                               struct jffs2_sum_xref_flash *spr;
+                               uint32_t ofs;
+                               spr = (struct jffs2_sum_xref_flash *)sp;
+                               ofs = jeb->offset + je32_to_cpu(spr->offset);
+                               dbg_summary("xref at %#08x (xid=%u, ino=%u)\n", ofs,
+                                           je32_to_cpu(spr->xid), je32_to_cpu(spr->ino));
+                               raw = jffs2_alloc_raw_node_ref();
+                               if (!raw) {
+                                       JFFS2_NOTICE("allocation of node reference failed\n");
+                                       kfree(summary);
+                                       return -ENOMEM;
+                               }
+                               ref = jffs2_alloc_xattr_ref();
+                               if (!ref) {
+                                       JFFS2_NOTICE("allocation of xattr_datum failed\n");
+                                       jffs2_free_raw_node_ref(raw);
+                                       kfree(summary);
+                                       return -ENOMEM;
+                               }
+                               ref->ino = 0xfffffffe;
+                               ref->xid = 0xfffffffd;
+                               ref->node = raw;
+                               ref->next = c->xref_temp;
+                               c->xref_temp = ref;
+                               raw->__totlen = PAD(sizeof(struct jffs2_raw_xref));
+                               raw->flash_offset = ofs | REF_UNCHECKED;
+                               raw->next_phys = NULL;
+                               raw->next_in_ino = (void *)ref;
+                               if (!jeb->first_node)
+                                       jeb->first_node = raw;
+                               if (jeb->last_node)
+                                       jeb->last_node->next_phys = raw;
+                               jeb->last_node = raw;
+                               UNCHECKED_SPACE(PAD(sizeof(struct jffs2_raw_xref)));
+                               *pseudo_random += ofs;
+                               sp += JFFS2_SUMMARY_XREF_SIZE;
  
+                               break;
+                       }
+ #endif
                        default : {
+ printk("nodetype = %#04x\n",je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype));
                                JFFS2_WARNING("Unsupported node type found in summary! Exiting...");
 -                              kfree(summary);
                                return -EIO;
                        }
                }
@@@ -159,9 -197,10 +197,11 @@@ int jffs2_sum_write_sumnode(struct jffs
  int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size);
  int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs);
  int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, uint32_t ofs);
+ int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, uint32_t ofs);
+ int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, uint32_t ofs);
  int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
 -                      uint32_t ofs, uint32_t *pseudo_random);
 +                         struct jffs2_raw_summary *summary, uint32_t sumlen,
 +                         uint32_t *pseudo_random);
  
  #else                         /* SUMMARY DISABLED */
  
Simple merge