ext4: don't verify checksums of dx non-leaf nodes during fallback scan
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 13 Nov 2012 04:51:02 +0000 (23:51 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 13 Nov 2012 04:51:02 +0000 (23:51 -0500)
During a directory entry lookup of a hashed directory, if the
hash-based lookup functions fail and we fall back to a linear scan,
don't try to verify the dirent checksum on the internal nodes of the
hash tree because they don't store a checksum in a hidden dirent like
the leaf nodes do.

Reported-by: George Spelvin <linux@horizon.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/namei.c

index 580af3dfc0ebdbe807e56248c9f965fbd7c77f40..88e9a2c7e328e74d3518c2e9b698353f46080f3b 100644 (file)
@@ -1146,6 +1146,21 @@ static inline int search_dirblock(struct buffer_head *bh,
        return 0;
 }
 
+static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block,
+                              struct ext4_dir_entry *de)
+{
+       struct super_block *sb = dir->i_sb;
+
+       if (!is_dx(dir))
+               return 0;
+       if (block == 0)
+               return 1;
+       if (de->inode == 0 &&
+           ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize) ==
+                       sb->s_blocksize)
+               return 1;
+       return 0;
+}
 
 /*
  *     ext4_find_entry()
@@ -1246,6 +1261,8 @@ restart:
                        goto next;
                }
                if (!buffer_verified(bh) &&
+                   !is_dx_internal_node(dir, block,
+                                        (struct ext4_dir_entry *)bh->b_data) &&
                    !ext4_dirent_csum_verify(dir,
                                (struct ext4_dir_entry *)bh->b_data)) {
                        EXT4_ERROR_INODE(dir, "checksumming directory "