• Dmitry Monakhov's avatar
    ext4: fix extent_status fragmentation for plain files · 4068664e
    Dmitry Monakhov authored
    Extents are cached in read_extent_tree_block(); as a result, extents
    are not cached for inodes with depth == 0 when we try to find the
    extent using ext4_find_extent().  The result of the lookup is cached
    in ext4_map_blocks() but is only a subset of the extent on disk.  As a
    result, the contents of extents status cache can get very badly
    fragmented for certain workloads, such as a random 4k read workload.
    
    File size of /mnt/test is 33554432 (8192 blocks of 4096 bytes)
     ext:     logical_offset:        physical_offset: length:   expected: flags:
       0:        0..    8191:      40960..     49151:   8192:             last,eof
    
    $ perf record -e 'ext4:ext4_es_*' /root/bin/fio --name=t --direct=0 --rw=randread --bs=4k --filesize=32M --size=32M --filename=/mnt/test
    $ perf script | grep ext4_es_insert_extent | head -n 10
                 fio   131 [000]    13.975421:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [494/1) mapped 41454 status W
                 fio   131 [000]    13.975939:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [6064/1) mapped 47024 status W
                 fio   131 [000]    13.976467:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [6907/1) mapped 47867 status W
                 fio   131 [000]    13.976937:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [3850/1) mapped 44810 status W
                 fio   131 [000]    13.977440:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [3292/1) mapped 44252 status W
                 fio   131 [000]    13.977931:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [6882/1) mapped 47842 status W
                 fio   131 [000]    13.978376:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [3117/1) mapped 44077 status W
                 fio   131 [000]    13.978957:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [2896/1) mapped 43856 status W
                 fio   131 [000]    13.979474:           ext4:ext4_es_insert_extent: dev 253,0 ino 12 es [7479/1) mapped 48439 status W
    
    Fix this by caching the extents for inodes with depth == 0 in
    ext4_find_extent().
    
    [ Renamed ext4_es_cache_extents() to ext4_cache_extents() since this
      newly added function is not in extents_cache.c, and to avoid
      potential visual confusion with ext4_es_cache_extent().  -TYT ]
    Signed-off-by: default avatarDmitry Monakhov <dmonakhov@gmail.com>
    Link: https://lore.kernel.org/r/20191106122502.19986-1-dmonakhov@gmail.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    4068664e
extents.c 163 KB