1. 25 1月, 2020 5 次提交
  2. 24 1月, 2020 1 次提交
    • D
      ext4: fix extent_status fragmentation for plain files · 4068664e
      Dmitry Monakhov 提交于
      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: NDmitry Monakhov <dmonakhov@gmail.com>
      Link: https://lore.kernel.org/r/20191106122502.19986-1-dmonakhov@gmail.comSigned-off-by: NTheodore Ts'o <tytso@mit.edu>
      4068664e
  3. 18 1月, 2020 27 次提交
  4. 27 12月, 2019 4 次提交
  5. 26 12月, 2019 1 次提交
  6. 23 12月, 2019 2 次提交
    • R
      ext4: Move to shared i_rwsem even without dioread_nolock mount opt · bc6385da
      Ritesh Harjani 提交于
      We were using shared locking only in case of dioread_nolock mount option in case
      of DIO overwrites. This mount condition is not needed anymore with current code,
      since:-
      
      1. No race between buffered writes & DIO overwrites. Since buffIO writes takes
      exclusive lock & DIO overwrites will take shared locking. Also DIO path will
      make sure to flush and wait for any dirty page cache data.
      
      2. No race between buffered reads & DIO overwrites, since there is no block
      allocation that is possible with DIO overwrites. So no stale data exposure
      should happen. Same is the case between DIO reads & DIO overwrites.
      
      3. Also other paths like truncate is protected, since we wait there for any DIO
      in flight to be over.
      Reviewed-by: NJan Kara <jack@suse.cz>
      Tested-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
      Signed-off-by: NRitesh Harjani <riteshh@linux.ibm.com>
      Link: https://lore.kernel.org/r/20191212055557.11151-4-riteshh@linux.ibm.comSigned-off-by: NTheodore Ts'o <tytso@mit.edu>
      bc6385da
    • R
      ext4: Start with shared i_rwsem in case of DIO instead of exclusive · aa9714d0
      Ritesh Harjani 提交于
      Earlier there was no shared lock in DIO read path. But this patch
      (16c54688: ext4: Allow parallel DIO reads)
      simplified some of the locking mechanism while still allowing for parallel DIO
      reads by adding shared lock in inode DIO read path.
      
      But this created problem with mixed read/write workload. It is due to the fact
      that in DIO path, we first start with exclusive lock and only when we determine
      that it is a ovewrite IO, we downgrade the lock. This causes the problem, since
      we still have shared locking in DIO reads.
      
      So, this patch tries to fix this issue by starting with shared lock and then
      switching to exclusive lock only when required based on ext4_dio_write_checks().
      
      Other than that, it also simplifies below cases:-
      
      1. Simplified ext4_unaligned_aio API to ext4_unaligned_io. Previous API was
      abused in the sense that it was not really checking for AIO anywhere also it
      used to check for extending writes. So this API was renamed and simplified to
      ext4_unaligned_io() which actully only checks if the IO is really unaligned.
      
      Now, in case of unaligned direct IO, iomap_dio_rw needs to do zeroing of partial
      block and that will require serialization against other direct IOs in the same
      block. So we take a exclusive inode lock for any unaligned DIO. In case of AIO
      we also need to wait for any outstanding IOs to complete so that conversion from
      unwritten to written is completed before anyone try to map the overlapping block.
      Hence we take exclusive inode lock and also wait for inode_dio_wait() for
      unaligned DIO case. Please note since we are anyway taking an exclusive lock in
      unaligned IO, inode_dio_wait() becomes a no-op in case of non-AIO DIO.
      
      2. Added ext4_extending_io(). This checks if the IO is extending the file.
      
      3. Added ext4_dio_write_checks(). In this we start with shared inode lock and
      only switch to exclusive lock if required. So in most cases with aligned,
      non-extending, dioread_nolock & overwrites, it tries to write with a shared
      lock. If not, then we restart the operation in ext4_dio_write_checks(), after
      acquiring exclusive lock.
      Reviewed-by: NJan Kara <jack@suse.cz>
      Tested-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
      Signed-off-by: NRitesh Harjani <riteshh@linux.ibm.com>
      Link: https://lore.kernel.org/r/20191212055557.11151-3-riteshh@linux.ibm.comSigned-off-by: NTheodore Ts'o <tytso@mit.edu>
      aa9714d0