diff options
-rw-r--r-- | fs/ext3/dir.c | 15 | ||||
-rw-r--r-- | include/linux/ext3_fs.h | 9 |
2 files changed, 17 insertions, 7 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index e2e72c367cf6..34f0a072b935 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -69,25 +69,26 @@ int ext3_check_dir_entry (const char * function, struct inode * dir, | |||
69 | const char * error_msg = NULL; | 69 | const char * error_msg = NULL; |
70 | const int rlen = ext3_rec_len_from_disk(de->rec_len); | 70 | const int rlen = ext3_rec_len_from_disk(de->rec_len); |
71 | 71 | ||
72 | if (rlen < EXT3_DIR_REC_LEN(1)) | 72 | if (unlikely(rlen < EXT3_DIR_REC_LEN(1))) |
73 | error_msg = "rec_len is smaller than minimal"; | 73 | error_msg = "rec_len is smaller than minimal"; |
74 | else if (rlen % 4 != 0) | 74 | else if (unlikely(rlen % 4 != 0)) |
75 | error_msg = "rec_len % 4 != 0"; | 75 | error_msg = "rec_len % 4 != 0"; |
76 | else if (rlen < EXT3_DIR_REC_LEN(de->name_len)) | 76 | else if (unlikely(rlen < EXT3_DIR_REC_LEN(de->name_len))) |
77 | error_msg = "rec_len is too small for name_len"; | 77 | error_msg = "rec_len is too small for name_len"; |
78 | else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) | 78 | else if (unlikely((((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize))) |
79 | error_msg = "directory entry across blocks"; | 79 | error_msg = "directory entry across blocks"; |
80 | else if (le32_to_cpu(de->inode) > | 80 | else if (unlikely(le32_to_cpu(de->inode) > |
81 | le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count)) | 81 | le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))) |
82 | error_msg = "inode out of bounds"; | 82 | error_msg = "inode out of bounds"; |
83 | 83 | ||
84 | if (error_msg != NULL) | 84 | if (unlikely(error_msg != NULL)) |
85 | ext3_error (dir->i_sb, function, | 85 | ext3_error (dir->i_sb, function, |
86 | "bad entry in directory #%lu: %s - " | 86 | "bad entry in directory #%lu: %s - " |
87 | "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", | 87 | "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", |
88 | dir->i_ino, error_msg, offset, | 88 | dir->i_ino, error_msg, offset, |
89 | (unsigned long) le32_to_cpu(de->inode), | 89 | (unsigned long) le32_to_cpu(de->inode), |
90 | rlen, de->name_len); | 90 | rlen, de->name_len); |
91 | |||
91 | return error_msg == NULL ? 1 : 0; | 92 | return error_msg == NULL ? 1 : 0; |
92 | } | 93 | } |
93 | 94 | ||
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index a443965946bb..65990ef612f5 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -724,21 +724,30 @@ struct ext3_dir_entry_2 { | |||
724 | ~EXT3_DIR_ROUND) | 724 | ~EXT3_DIR_ROUND) |
725 | #define EXT3_MAX_REC_LEN ((1<<16)-1) | 725 | #define EXT3_MAX_REC_LEN ((1<<16)-1) |
726 | 726 | ||
727 | /* | ||
728 | * Tests against MAX_REC_LEN etc were put in place for 64k block | ||
729 | * sizes; if that is not possible on this arch, we can skip | ||
730 | * those tests and speed things up. | ||
731 | */ | ||
727 | static inline unsigned ext3_rec_len_from_disk(__le16 dlen) | 732 | static inline unsigned ext3_rec_len_from_disk(__le16 dlen) |
728 | { | 733 | { |
729 | unsigned len = le16_to_cpu(dlen); | 734 | unsigned len = le16_to_cpu(dlen); |
730 | 735 | ||
736 | #if (PAGE_CACHE_SIZE >= 65536) | ||
731 | if (len == EXT3_MAX_REC_LEN) | 737 | if (len == EXT3_MAX_REC_LEN) |
732 | return 1 << 16; | 738 | return 1 << 16; |
739 | #endif | ||
733 | return len; | 740 | return len; |
734 | } | 741 | } |
735 | 742 | ||
736 | static inline __le16 ext3_rec_len_to_disk(unsigned len) | 743 | static inline __le16 ext3_rec_len_to_disk(unsigned len) |
737 | { | 744 | { |
745 | #if (PAGE_CACHE_SIZE >= 65536) | ||
738 | if (len == (1 << 16)) | 746 | if (len == (1 << 16)) |
739 | return cpu_to_le16(EXT3_MAX_REC_LEN); | 747 | return cpu_to_le16(EXT3_MAX_REC_LEN); |
740 | else if (len > (1 << 16)) | 748 | else if (len > (1 << 16)) |
741 | BUG(); | 749 | BUG(); |
750 | #endif | ||
742 | return cpu_to_le16(len); | 751 | return cpu_to_le16(len); |
743 | } | 752 | } |
744 | 753 | ||