simplify access to ecryptfs inodes in ->readpage() and friends
[safe/jmp/linux-2.6] / fs / ubifs / tnc.c
index f7e36f5..2194915 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include <linux/crc32.h>
+#include <linux/slab.h>
 #include "ubifs.h"
 
 /*
@@ -443,6 +444,11 @@ static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr,
  * This function performs that same function as ubifs_read_node except that
  * it does not require that there is actually a node present and instead
  * the return code indicates if a node was read.
+ *
+ * Note, this function does not check CRC of data nodes if @c->no_chk_data_crc
+ * is true (it is controlled by corresponding mount option). However, if
+ * @c->always_chk_crc is true, @c->no_chk_data_crc is ignored and CRC is always
+ * checked.
  */
 static int try_read_node(const struct ubifs_info *c, void *buf, int type,
                         int len, int lnum, int offs)
@@ -470,9 +476,8 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
        if (node_len != len)
                return 0;
 
-       if (type == UBIFS_DATA_NODE && !c->always_chk_crc)
-               if (c->no_chk_data_crc)
-                       return 0;
+       if (type == UBIFS_DATA_NODE && !c->always_chk_crc && c->no_chk_data_crc)
+               return 1;
 
        crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
        node_crc = le32_to_cpu(ch->crc);
@@ -1155,8 +1160,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
  *   o exact match, i.e. the found zero-level znode contains key @key, then %1
  *     is returned and slot number of the matched branch is stored in @n;
  *   o not exact match, which means that zero-level znode does not contain
- *     @key, then %0 is returned and slot number of the closed branch is stored
- *     in  @n;
+ *     @key, then %0 is returned and slot number of the closest branch is stored
+ *     in @n;
  *   o @key is so small that it is even less than the lowest key of the
  *     leftmost zero-level node, then %0 is returned and %0 is stored in @n.
  *
@@ -1248,7 +1253,7 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
         * splitting in the middle of the colliding sequence. Also, when
         * removing the leftmost key, we would have to correct the key of the
         * parent node, which would introduce additional complications. Namely,
-        * if we changed the the leftmost key of the parent znode, the garbage
+        * if we changed the leftmost key of the parent znode, the garbage
         * collector would be unable to find it (GC is doing this when GC'ing
         * indexing LEBs). Although we already have an additional RB-tree where
         * we save such changed znodes (see 'ins_clr_old_idx_znode()') until
@@ -1429,7 +1434,7 @@ static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1)
  * @lnum: LEB number is returned here
  * @offs: offset is returned here
  *
- * This function look up and reads node with key @key. The caller has to make
+ * This function looks up and reads node with key @key. The caller has to make
  * sure the @node buffer is large enough to fit the node. Returns zero in case
  * of success, %-ENOENT if the node was not found, and a negative error code in
  * case of failure. The node location can be returned in @lnum and @offs.
@@ -1506,7 +1511,7 @@ out:
  *
  * Note, if the bulk-read buffer length (@bu->buf_len) is known, this function
  * makes sure bulk-read nodes fit the buffer. Otherwise, this function prepares
- * maxumum possible amount of nodes for bulk-read.
+ * maximum possible amount of nodes for bulk-read.
  */
 int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu)
 {
@@ -3264,3 +3269,73 @@ out_unlock:
        mutex_unlock(&c->tnc_mutex);
        return err;
 }
+
+#ifdef CONFIG_UBIFS_FS_DEBUG
+
+/**
+ * dbg_check_inode_size - check if inode size is correct.
+ * @c: UBIFS file-system description object
+ * @inum: inode number
+ * @size: inode size
+ *
+ * This function makes sure that the inode size (@size) is correct and it does
+ * not have any pages beyond @size. Returns zero if the inode is OK, %-EINVAL
+ * if it has a data page beyond @size, and other negative error code in case of
+ * other errors.
+ */
+int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
+                        loff_t size)
+{
+       int err, n;
+       union ubifs_key from_key, to_key, *key;
+       struct ubifs_znode *znode;
+       unsigned int block;
+
+       if (!S_ISREG(inode->i_mode))
+               return 0;
+       if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+               return 0;
+
+       block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
+       data_key_init(c, &from_key, inode->i_ino, block);
+       highest_data_key(c, &to_key, inode->i_ino);
+
+       mutex_lock(&c->tnc_mutex);
+       err = ubifs_lookup_level0(c, &from_key, &znode, &n);
+       if (err < 0)
+               goto out_unlock;
+
+       if (err) {
+               err = -EINVAL;
+               key = &from_key;
+               goto out_dump;
+       }
+
+       err = tnc_next(c, &znode, &n);
+       if (err == -ENOENT) {
+               err = 0;
+               goto out_unlock;
+       }
+       if (err < 0)
+               goto out_unlock;
+
+       ubifs_assert(err == 0);
+       key = &znode->zbranch[n].key;
+       if (!key_in_range(c, key, &from_key, &to_key))
+               goto out_unlock;
+
+out_dump:
+       block = key_block(c, key);
+       ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
+                 "(data key %s)", (unsigned long)inode->i_ino, size,
+                 ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
+       dbg_dump_inode(c, inode);
+       dbg_dump_stack();
+       err = -EINVAL;
+
+out_unlock:
+       mutex_unlock(&c->tnc_mutex);
+       return err;
+}
+
+#endif /* CONFIG_UBIFS_FS_DEBUG */