aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/dir.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2010-12-19 22:07:02 -0500
committerTheodore Ts'o <tytso@mit.edu>2010-12-19 22:07:02 -0500
commitcad3f00763dcf9dfc62cbddf4bd714ab5a71a0eb (patch)
tree02ec7c4959f5506f0b2fe128b1318e257ee6f0e4 /fs/ext4/dir.c
parentb17b35ec13adfeb0346d4b329110b14adc509327 (diff)
ext4: optimize ext4_check_dir_entry() with unlikely() annotations
This function gets called a lot for large directories, and the answer is almost always "no, no, there's no problem". This means using unlikely() is a good thing. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/dir.c')
-rw-r--r--fs/ext4/dir.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index ece76fb6a40c..bd5d74d06399 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -60,7 +60,11 @@ static unsigned char get_dtype(struct super_block *sb, int filetype)
60 return (ext4_filetype_table[filetype]); 60 return (ext4_filetype_table[filetype]);
61} 61}
62 62
63 63/*
64 * Return 0 if the directory entry is OK, and 1 if there is a problem
65 *
66 * Note: this is the opposite of what ext2 and ext3 historically returned...
67 */
64int __ext4_check_dir_entry(const char *function, unsigned int line, 68int __ext4_check_dir_entry(const char *function, unsigned int line,
65 struct inode *dir, 69 struct inode *dir,
66 struct ext4_dir_entry_2 *de, 70 struct ext4_dir_entry_2 *de,
@@ -71,26 +75,28 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
71 const int rlen = ext4_rec_len_from_disk(de->rec_len, 75 const int rlen = ext4_rec_len_from_disk(de->rec_len,
72 dir->i_sb->s_blocksize); 76 dir->i_sb->s_blocksize);
73 77
74 if (rlen < EXT4_DIR_REC_LEN(1)) 78 if (unlikely(rlen < EXT4_DIR_REC_LEN(1)))
75 error_msg = "rec_len is smaller than minimal"; 79 error_msg = "rec_len is smaller than minimal";
76 else if (rlen % 4 != 0) 80 else if (unlikely(rlen % 4 != 0))
77 error_msg = "rec_len % 4 != 0"; 81 error_msg = "rec_len % 4 != 0";
78 else if (rlen < EXT4_DIR_REC_LEN(de->name_len)) 82 else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
79 error_msg = "rec_len is too small for name_len"; 83 error_msg = "rec_len is too small for name_len";
80 else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) 84 else if (unlikely(((char *) de - bh->b_data) + rlen >
85 dir->i_sb->s_blocksize))
81 error_msg = "directory entry across blocks"; 86 error_msg = "directory entry across blocks";
82 else if (le32_to_cpu(de->inode) > 87 else if (unlikely(le32_to_cpu(de->inode) >
83 le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)) 88 le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
84 error_msg = "inode out of bounds"; 89 error_msg = "inode out of bounds";
90 else
91 return 0;
85 92
86 if (error_msg != NULL) 93 ext4_error_inode(dir, function, line, bh->b_blocknr,
87 ext4_error_inode(dir, function, line, bh->b_blocknr, 94 "bad entry in directory: %s - "
88 "bad entry in directory: %s - " 95 "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d",
89 "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d", 96 error_msg, (unsigned) (offset%bh->b_size), offset,
90 error_msg, (unsigned) (offset%bh->b_size), offset, 97 le32_to_cpu(de->inode),
91 le32_to_cpu(de->inode), 98 rlen, de->name_len);
92 rlen, de->name_len); 99 return 1;
93 return error_msg == NULL ? 1 : 0;
94} 100}
95 101
96static int ext4_readdir(struct file *filp, 102static int ext4_readdir(struct file *filp,
@@ -194,8 +200,8 @@ revalidate:
194 while (!error && filp->f_pos < inode->i_size 200 while (!error && filp->f_pos < inode->i_size
195 && offset < sb->s_blocksize) { 201 && offset < sb->s_blocksize) {
196 de = (struct ext4_dir_entry_2 *) (bh->b_data + offset); 202 de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
197 if (!ext4_check_dir_entry(inode, de, 203 if (ext4_check_dir_entry(inode, de,
198 bh, offset)) { 204 bh, offset)) {
199 /* 205 /*
200 * On error, skip the f_pos to the next block 206 * On error, skip the f_pos to the next block
201 */ 207 */