]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/jffs2/readinode.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc
[linux-2.6-omap-h63xx.git] / fs / jffs2 / readinode.c
index 5351b34d5419785c1b9f746c441bc394a1b5957a..266423b2709d04be8709164b0dacdbbebc4f22b8 100644 (file)
@@ -66,7 +66,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
                        jffs2_free_full_dnode(tn->fn);
                        jffs2_free_tmp_dnode_info(tn);
 
-                       this = this->rb_parent;
+                       this = rb_parent(this);
                        if (!this)
                                break;
 
@@ -116,19 +116,42 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
                                uint32_t *latest_mctime, uint32_t *mctime_ver)
 {
        struct jffs2_full_dirent *fd;
+       uint32_t crc;
 
-       /* The direntry nodes are checked during the flash scanning */
-       BUG_ON(ref_flags(ref) == REF_UNCHECKED);
        /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
        BUG_ON(ref_obsolete(ref));
 
-       /* Sanity check */
-       if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
-               JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
-                      ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
+       crc = crc32(0, rd, sizeof(*rd) - 8);
+       if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
+               JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n",
+                            ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
                return 1;
        }
 
+       /* If we've never checked the CRCs on this node, check them now */
+       if (ref_flags(ref) == REF_UNCHECKED) {
+               struct jffs2_eraseblock *jeb;
+               int len;
+
+               /* Sanity check */
+               if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
+                       JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
+                                   ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
+                       return 1;
+               }
+
+               jeb = &c->blocks[ref->flash_offset / c->sector_size];
+               len = ref_totlen(c, jeb, ref);
+
+               spin_lock(&c->erase_completion_lock);
+               jeb->used_size += len;
+               jeb->unchecked_size -= len;
+               c->used_size += len;
+               c->unchecked_size -= len;
+               ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
+               spin_unlock(&c->erase_completion_lock);
+       }
+
        fd = jffs2_alloc_full_dirent(rd->nsize + 1);
        if (unlikely(!fd))
                return -ENOMEM;
@@ -198,10 +221,18 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
        struct jffs2_tmp_dnode_info *tn;
        uint32_t len, csize;
        int ret = 1;
+       uint32_t crc;
 
        /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
        BUG_ON(ref_obsolete(ref));
 
+       crc = crc32(0, rd, sizeof(*rd) - 8);
+       if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
+               JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n",
+                            ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
+               return 1;
+       }
+
        tn = jffs2_alloc_tmp_dnode_info();
        if (!tn) {
                JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn));
@@ -213,14 +244,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
 
        /* If we've never checked the CRCs on this node, check them now */
        if (ref_flags(ref) == REF_UNCHECKED) {
-               uint32_t crc;
-
-               crc = crc32(0, rd, sizeof(*rd) - 8);
-               if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
-                       JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
-                                       ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
-                       goto free_out;
-               }
 
                /* Sanity checks */
                if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
@@ -685,12 +708,12 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
                        jffs2_mark_node_obsolete(c, fn->raw);
 
                BUG_ON(rb->rb_left);
-               if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
+               if (rb_parent(rb) && rb_parent(rb)->rb_left == rb) {
                        /* We were then left-hand child of our parent. We need
                         * to move our own right-hand child into our place. */
                        repl_rb = rb->rb_right;
                        if (repl_rb)
-                               repl_rb->rb_parent = rb->rb_parent;
+                               rb_set_parent(repl_rb, rb_parent(rb));
                } else
                        repl_rb = NULL;
 
@@ -698,14 +721,14 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
 
                /* Remove the spent tn from the tree; don't bother rebalancing
                 * but put our right-hand child in our own place. */
-               if (tn->rb.rb_parent) {
-                       if (tn->rb.rb_parent->rb_left == &tn->rb)
-                               tn->rb.rb_parent->rb_left = repl_rb;
-                       else if (tn->rb.rb_parent->rb_right == &tn->rb)
-                               tn->rb.rb_parent->rb_right = repl_rb;
+               if (rb_parent(&tn->rb)) {
+                       if (rb_parent(&tn->rb)->rb_left == &tn->rb)
+                               rb_parent(&tn->rb)->rb_left = repl_rb;
+                       else if (rb_parent(&tn->rb)->rb_right == &tn->rb)
+                               rb_parent(&tn->rb)->rb_right = repl_rb;
                        else BUG();
                } else if (tn->rb.rb_right)
-                       tn->rb.rb_right->rb_parent = NULL;
+                       rb_set_parent(tn->rb.rb_right, NULL);
 
                jffs2_free_tmp_dnode_info(tn);
                if (ret) {
@@ -945,6 +968,8 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
        struct jffs2_full_dirent *fd, *fds;
        int deleted;
 
+       jffs2_clear_acl(f);
+       jffs2_xattr_delete_inode(c, f->inocache);
        down(&f->sem);
        deleted = f->inocache && !f->inocache->nlink;