ocfs2: fix ocfs2 read inode data panic in ocfs2_iget
[sfrench/cifs-2.6.git] / fs / ubifs / tnc_misc.c
index d90ee01076a9ea5559dd8afb26cffc4e61a5cb81..d1815e9590071940059186923bb4dc21e8bb9cce 100644 (file)
@@ -265,9 +265,7 @@ long ubifs_destroy_tnc_subtree(const struct ubifs_info *c,
 /**
  * read_znode - read an indexing node from flash and fill znode.
  * @c: UBIFS file-system description object
- * @lnum: LEB of the indexing node to read
- * @offs: node offset
- * @len: node length
+ * @zzbr: the zbranch describing the node to read
  * @znode: znode to read to
  *
  * This function reads an indexing node from the flash media and fills znode
@@ -276,9 +274,12 @@ long ubifs_destroy_tnc_subtree(const struct ubifs_info *c,
  * is wrong with it, this function prints complaint messages and returns
  * %-EINVAL.
  */
-static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
+static int read_znode(struct ubifs_info *c, struct ubifs_zbranch *zzbr,
                      struct ubifs_znode *znode)
 {
+       int lnum = zzbr->lnum;
+       int offs = zzbr->offs;
+       int len = zzbr->len;
        int i, err, type, cmp;
        struct ubifs_idx_node *idx;
 
@@ -292,6 +293,12 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
                return err;
        }
 
+       err = ubifs_node_check_hash(c, idx, zzbr->hash);
+       if (err) {
+               ubifs_bad_hash(c, idx, zzbr->hash, lnum, offs);
+               return err;
+       }
+
        znode->child_cnt = le16_to_cpu(idx->child_cnt);
        znode->level = le16_to_cpu(idx->level);
 
@@ -308,13 +315,14 @@ static int read_znode(struct ubifs_info *c, int lnum, int offs, int len,
        }
 
        for (i = 0; i < znode->child_cnt; i++) {
-               const struct ubifs_branch *br = ubifs_idx_branch(c, idx, i);
+               struct ubifs_branch *br = ubifs_idx_branch(c, idx, i);
                struct ubifs_zbranch *zbr = &znode->zbranch[i];
 
                key_read(c, &br->key, &zbr->key);
                zbr->lnum = le32_to_cpu(br->lnum);
                zbr->offs = le32_to_cpu(br->offs);
                zbr->len  = le32_to_cpu(br->len);
+               ubifs_copy_hash(c, ubifs_branch_hash(c, br), zbr->hash);
                zbr->znode = NULL;
 
                /* Validate branch */
@@ -425,7 +433,7 @@ struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
        if (!znode)
                return ERR_PTR(-ENOMEM);
 
-       err = read_znode(c, zbr->lnum, zbr->offs, zbr->len, znode);
+       err = read_znode(c, zbr, znode);
        if (err)
                goto out;
 
@@ -496,5 +504,11 @@ int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,
                return -EINVAL;
        }
 
+       err = ubifs_node_check_hash(c, node, zbr->hash);
+       if (err) {
+               ubifs_bad_hash(c, node, zbr->hash, zbr->lnum, zbr->offs);
+               return err;
+       }
+
        return 0;
 }