Commit a4ae3094869f18e26ece25ad175bbe4cd740e60b

Authored by Eric Sandeen
Committed by Jan Kara
1 parent 40a063f669

ext3: speed up file creates by optimizing rec_len functions

The addition of 64k block capability in the rec_len_from_disk
and rec_len_to_disk functions added a bit of math overhead which
slows down file create workloads needlessly when the architecture
cannot even support 64k blocks, thanks to page size limits.

Similar changes already exist in the ext4 codebase.

The directory entry checking can also be optimized a bit
by sprinkling in some unlikely() conditions to move the
error handling out of line.

bonnie++ sequential file creates on a 512MB ramdisk speeds up
from about 77,000/s to about 82,000/s, about a 6% improvement.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Jan Kara <jack@suse.cz>

Showing 2 changed files with 17 additions and 7 deletions Side-by-side Diff

... ... @@ -69,25 +69,26 @@
69 69 const char * error_msg = NULL;
70 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 73 error_msg = "rec_len is smaller than minimal";
74   - else if (rlen % 4 != 0)
  74 + else if (unlikely(rlen % 4 != 0))
75 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 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 79 error_msg = "directory entry across blocks";
80   - else if (le32_to_cpu(de->inode) >
81   - le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count))
  80 + else if (unlikely(le32_to_cpu(de->inode) >
  81 + le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count)))
82 82 error_msg = "inode out of bounds";
83 83  
84   - if (error_msg != NULL)
  84 + if (unlikely(error_msg != NULL))
85 85 ext3_error (dir->i_sb, function,
86 86 "bad entry in directory #%lu: %s - "
87 87 "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
88 88 dir->i_ino, error_msg, offset,
89 89 (unsigned long) le32_to_cpu(de->inode),
90 90 rlen, de->name_len);
  91 +
91 92 return error_msg == NULL ? 1 : 0;
92 93 }
93 94  
include/linux/ext3_fs.h
... ... @@ -724,21 +724,30 @@
724 724 ~EXT3_DIR_ROUND)
725 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 732 static inline unsigned ext3_rec_len_from_disk(__le16 dlen)
728 733 {
729 734 unsigned len = le16_to_cpu(dlen);
730 735  
  736 +#if (PAGE_CACHE_SIZE >= 65536)
731 737 if (len == EXT3_MAX_REC_LEN)
732 738 return 1 << 16;
  739 +#endif
733 740 return len;
734 741 }
735 742  
736 743 static inline __le16 ext3_rec_len_to_disk(unsigned len)
737 744 {
  745 +#if (PAGE_CACHE_SIZE >= 65536)
738 746 if (len == (1 << 16))
739 747 return cpu_to_le16(EXT3_MAX_REC_LEN);
740 748 else if (len > (1 << 16))
741 749 BUG();
  750 +#endif
742 751 return cpu_to_le16(len);
743 752 }
744 753