1. 03 Apr, 2020 4 commits
  2. 31 Mar, 2020 19 commits
    • Chao Yu's avatar
      f2fs: compress: add .{init,destroy}_decompress_ctx callback · 23b1faaa
      Chao Yu authored
      Add below two callback interfaces in struct f2fs_compress_ops:
      
      	int (*init_decompress_ctx)(struct decompress_io_ctx *dic);
      	void (*destroy_decompress_ctx)(struct decompress_io_ctx *dic);
      
      Which will be used by zstd compress algorithm later.
      
      In addition, this patch adds callback function pointer check, so that
      specified algorithm can avoid defining unneeded functions.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      23b1faaa
    • Chao Yu's avatar
      f2fs: compress: fix to call missing destroy_compress_ctx() · 09ff4801
      Chao Yu authored
      Otherwise, it will cause memory leak.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      09ff4801
    • Chao Yu's avatar
      f2fs: change default compression algorithm · 91faa534
      Chao Yu authored
      Use LZ4 as default compression algorithm, as compared to LZO, it shows
      almost the same compression ratio and much better decompression speed.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      91faa534
    • Chao Yu's avatar
      f2fs: clean up {cic,dic}.ref handling · 887347a0
      Chao Yu authored
      {cic,dic}.ref should be initialized to number of compressed pages,
      let's initialize it directly rather than doing w/
      f2fs_set_compressed_page().
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      887347a0
    • Chao Yu's avatar
      f2fs: fix to use f2fs_readpage_limit() in f2fs_read_multi_pages() · 7496affa
      Chao Yu authored
      Multipage read flow should consider fsverity, so it needs to use
      f2fs_readpage_limit() instead of i_size_read() to check EOF condition.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      7496affa
    • YueHaibing's avatar
      f2fs: xattr.h: Make stub helpers inline · db251553
      YueHaibing authored
      Fix gcc warnings:
      
      In file included from fs/f2fs/dir.c:15:0:
      fs/f2fs/xattr.h:157:13: warning: 'f2fs_destroy_xattr_caches' defined but not used [-Wunused-function]
       static void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) { }
                   ^~~~~~~~~~~~~~~~~~~~~~~~~
      fs/f2fs/xattr.h:156:12: warning: 'f2fs_init_xattr_caches' defined but not used [-Wunused-function]
       static int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) { return 0; }
      Reported-by: default avatarHulk Robot <hulkci@huawei.com>
      Fixes: a999150f ("f2fs: use kmem_cache pool during inline xattr lookups")
      Signed-off-by: default avatarYueHaibing <yuehaibing@huawei.com>
      Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      db251553
    • Chao Yu's avatar
      f2fs: fix to avoid double unlock · 74878565
      Chao Yu authored
      On image that has verity and compression feature, if compressed pages
      and non-compressed pages are mixed in one bio, we may double unlock
      non-compressed page in below flow:
      
      - f2fs_post_read_work
       - f2fs_decompress_work
        - f2fs_decompress_bio
         - __read_end_io
          - unlock_page
       - fsverity_enqueue_verify_work
        - f2fs_verity_work
         - f2fs_verify_bio
          - unlock_page
      
      So it should skip handling non-compressed page in f2fs_decompress_work()
      if verity is on.
      
      Besides, add missing dec_page_count() in f2fs_verify_bio().
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      74878565
    • Chao Yu's avatar
      f2fs: fix potential .flags overflow on 32bit architecture · 7653b9d8
      Chao Yu authored
      f2fs_inode_info.flags is unsigned long variable, it has 32 bits
      in 32bit architecture, since we introduced FI_MMAP_FILE flag
      when we support data compression, we may access memory cross
      the border of .flags field, corrupting .i_sem field, result in
      below deadlock.
      
      To fix this issue, let's expand .flags as an array to grab enough
      space to store new flags.
      
      Call Trace:
       __schedule+0x8d0/0x13fc
       ? mark_held_locks+0xac/0x100
       schedule+0xcc/0x260
       rwsem_down_write_slowpath+0x3ab/0x65d
       down_write+0xc7/0xe0
       f2fs_drop_nlink+0x3d/0x600 [f2fs]
       f2fs_delete_inline_entry+0x300/0x440 [f2fs]
       f2fs_delete_entry+0x3a1/0x7f0 [f2fs]
       f2fs_unlink+0x500/0x790 [f2fs]
       vfs_unlink+0x211/0x490
       do_unlinkat+0x483/0x520
       sys_unlink+0x4a/0x70
       do_fast_syscall_32+0x12b/0x683
       entry_SYSENTER_32+0xaa/0x102
      
      Fixes: 4c8ff709 ("f2fs: support data compression")
      Tested-by: default avatarOndrej Jirman <megous@megous.com>
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      7653b9d8
    • Chao Yu's avatar
      f2fs: fix NULL pointer dereference in f2fs_verity_work() · 79bbefb1
      Chao Yu authored
      If both compression and fsverity feature is on, generic/572 will
      report below NULL pointer dereference bug.
      
       BUG: kernel NULL pointer dereference, address: 0000000000000018
       RIP: 0010:f2fs_verity_work+0x60/0x90 [f2fs]
       #PF: supervisor read access in kernel mode
       Workqueue: fsverity_read_queue f2fs_verity_work [f2fs]
       RIP: 0010:f2fs_verity_work+0x60/0x90 [f2fs]
       Call Trace:
        process_one_work+0x16c/0x3f0
        worker_thread+0x4c/0x440
        ? rescuer_thread+0x350/0x350
        kthread+0xf8/0x130
        ? kthread_unpark+0x70/0x70
        ret_from_fork+0x35/0x40
      
      There are two issue in f2fs_verity_work():
      - it needs to traverse and verify all pages in bio.
      - if pages in bio belong to non-compressed cluster, accessing
      decompress IO context stored in page private will cause NULL
      pointer dereference.
      
      Fix them.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      79bbefb1
    • Chao Yu's avatar
      f2fs: fix to clear PG_error if fsverity failed · 23c51bed
      Chao Yu authored
      In f2fs_decompress_end_io(), we should clear PG_error flag before page
      unlock, otherwise reread will fail due to the flag as described in
      commit fb7d70db ("f2fs: clear PageError on the read path").
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      23c51bed
    • Chao Yu's avatar
      f2fs: don't call fscrypt_get_encryption_info() explicitly in f2fs_tmpfile() · d76af0d6
      Chao Yu authored
      In f2fs_tmpfile(), parent inode's encryption info is only used when
      inheriting encryption context to its child inode, however, we have
      already called fscrypt_get_encryption_info() in fscrypt_inherit_context()
      to get the encryption info, so just removing unneeded one in
      f2fs_tmpfile().
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      d76af0d6
    • Chao Yu's avatar
      f2fs: don't trigger data flush in foreground operation · 7bcd0cfa
      Chao Yu authored
      Data flush can generate heavy IO and cause long latency during
      flush, so it's not appropriate to trigger it in foreground
      operation.
      
      And also, we may face below potential deadlock during data flush:
      - f2fs_write_multi_pages
       - f2fs_write_raw_pages
        - f2fs_write_single_data_page
         - f2fs_balance_fs
          - f2fs_balance_fs_bg
           - f2fs_sync_dirty_inodes
            - filemap_fdatawrite   -- stuck on flush same cluster
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      7bcd0cfa
    • Chao Yu's avatar
      f2fs: fix NULL pointer dereference in f2fs_write_begin() · 62f63eea
      Chao Yu authored
      BUG: kernel NULL pointer dereference, address: 0000000000000000
      RIP: 0010:f2fs_write_begin+0x823/0xb90 [f2fs]
      Call Trace:
       f2fs_quota_write+0x139/0x1d0 [f2fs]
       write_blk+0x36/0x80 [quota_tree]
       get_free_dqblk+0x42/0xa0 [quota_tree]
       do_insert_tree+0x235/0x4a0 [quota_tree]
       do_insert_tree+0x26e/0x4a0 [quota_tree]
       do_insert_tree+0x26e/0x4a0 [quota_tree]
       do_insert_tree+0x26e/0x4a0 [quota_tree]
       qtree_write_dquot+0x70/0x190 [quota_tree]
       v2_write_dquot+0x43/0x90 [quota_v2]
       dquot_acquire+0x77/0x100
       f2fs_dquot_acquire+0x2f/0x60 [f2fs]
       dqget+0x310/0x450
       dquot_transfer+0x7e/0x120
       f2fs_setattr+0x11a/0x4a0 [f2fs]
       notify_change+0x349/0x480
       chown_common+0x168/0x1c0
       do_fchownat+0xbc/0xf0
       __x64_sys_fchownat+0x20/0x30
       do_syscall_64+0x5f/0x220
       entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      Passing fsdata parameter to .write_{begin,end} in f2fs_quota_write(),
      so that if quota file is compressed one, we can avoid above NULL
      pointer dereference when updating quota content.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      62f63eea
    • Chao Yu's avatar
      f2fs: clean up f2fs_may_encrypt() · 8c7d4b57
      Chao Yu authored
      Merge below two conditions into f2fs_may_encrypt() for cleanup
      - IS_ENCRYPTED()
      - DUMMY_ENCRYPTION_ENABLED()
      
      Check IS_ENCRYPTED(inode) condition in f2fs_init_inode_metadata()
      is enough since we have already set encrypt flag in f2fs_new_inode().
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      8c7d4b57
    • Chao Yu's avatar
      f2fs: fix to avoid potential deadlock · b13f67ff
      Chao Yu authored
      We should always check F2FS_I(inode)->cp_task condition in prior to other
      conditions in __should_serialize_io() to avoid deadloop described in
      commit 040d2bb3 ("f2fs: fix to avoid deadloop if data_flush is on"),
      however we break this rule when we support compression, fix it.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      b13f67ff
    • Chao Yu's avatar
      f2fs: don't change inode status under page lock · 9995e401
      Chao Yu authored
      In order to shrink page lock coverage.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      9995e401
    • Chao Yu's avatar
      f2fs: fix potential deadlock on compressed quota file · 466357dc
      Chao Yu authored
      generic/232 reports below deadlock:
      
      fsstress        D    0 96980  96969 0x00084000
      Call Trace:
       schedule+0x4a/0xb0
       io_schedule+0x12/0x40
       __lock_page+0x127/0x1d0
       pagecache_get_page+0x1d8/0x250
       prepare_compress_overwrite+0xe0/0x490 [f2fs]
       f2fs_prepare_compress_overwrite+0x5d/0x80 [f2fs]
       f2fs_write_begin+0x833/0xb90 [f2fs]
       f2fs_quota_write+0x145/0x1e0 [f2fs]
       write_blk+0x36/0x80 [quota_tree]
       do_insert_tree+0x2ac/0x4a0 [quota_tree]
       do_insert_tree+0x26e/0x4a0 [quota_tree]
       qtree_write_dquot+0x70/0x190 [quota_tree]
       v2_write_dquot+0x43/0x90 [quota_v2]
       dquot_acquire+0x77/0x100
       f2fs_dquot_acquire+0x2f/0x60 [f2fs]
       dqget+0x310/0x450
       dquot_transfer+0xb2/0x120
       f2fs_setattr+0x11a/0x4a0 [f2fs]
       notify_change+0x349/0x480
       chown_common+0x168/0x1c0
       do_fchownat+0xbc/0xf0
       __x64_sys_lchown+0x21/0x30
       do_syscall_64+0x5f/0x220
       entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
        task                        PC stack   pid father
      kworker/u256:0  D    0 103444      2 0x80084000
      Workqueue: writeback wb_workfn (flush-251:1)
      Call Trace:
       schedule+0x4a/0xb0
       schedule_timeout+0x15e/0x2f0
       io_schedule_timeout+0x19/0x40
       congestion_wait+0x7e/0x120
       f2fs_write_multi_pages+0x12a/0x840 [f2fs]
       f2fs_write_cache_pages+0x48f/0x790 [f2fs]
       f2fs_write_data_pages+0x2db/0x330 [f2fs]
       do_writepages+0x1a/0x60
       __writeback_single_inode+0x3d/0x340
       writeback_sb_inodes+0x225/0x4a0
       wb_writeback+0xf7/0x320
       wb_workfn+0xba/0x470
       process_one_work+0x16c/0x3f0
       worker_thread+0x4c/0x440
       kthread+0xf8/0x130
       ret_from_fork+0x35/0x40
      
      fsstress        D    0  5277   5266 0x00084000
      Call Trace:
       schedule+0x4a/0xb0
       rwsem_down_write_slowpath+0x29d/0x540
       block_operations+0x105/0x360 [f2fs]
       f2fs_write_checkpoint+0x101/0x1010 [f2fs]
       f2fs_sync_fs+0xa8/0x130 [f2fs]
       f2fs_do_sync_file+0x1ad/0x890 [f2fs]
       do_fsync+0x38/0x60
       __x64_sys_fdatasync+0x13/0x20
       do_syscall_64+0x5f/0x220
       entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      The root cause is there is potential deadlock between quota data
      update and writeback.
      
      Kworker					Thread B			Thread C
      - f2fs_write_cache_pages
       - lock whole cluster	--- A
       - f2fs_write_multi_pages
        - f2fs_write_raw_pages
         - f2fs_write_single_data_page
          - f2fs_do_write_data_page
      					- f2fs_setattr
      					 - f2fs_lock_op	--- B
      									- f2fs_write_checkpoint
      									 - block_operations
      									  - f2fs_lock_all --- B
      					 - dquot_transfer
      					  - f2fs_quota_write
      					   - f2fs_prepare_compress_overwrite
      					    - pagecache_get_page --- A
           - f2fs_trylock_op failed	--- B
        - congestion_wait
        - goto rewrite
      
      To fix this issue, during quota file writeback, just redirty all pages
      left in cluster rather holding pages' lock in cluster and looping retrying
      lock cp_rwsem.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      466357dc
    • DongDongJu's avatar
      f2fs: delete DIO read lock · ad8d6a02
      DongDongJu authored
      This lock can be a contention with multi 4k random read IO with single inode.
      
      example) fio --output=test --name=test --numjobs=60 --filename=/media/samsung960pro/file_test --rw=randread --bs=4k
       --direct=1 --time_based --runtime=7 --ioengine=libaio --iodepth=256 --group_reporting --size=10G
      
      With this commit, it remove that possible lock contention.
      Signed-off-by: default avatarDongjoo Seo <commisori28@gmail.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      ad8d6a02
    • Chao Yu's avatar
      f2fs: don't mark compressed inode dirty during f2fs_iget() · 530e0704
      Chao Yu authored
      - f2fs_iget
       - do_read_inode
        - set_inode_flag(, FI_COMPRESSED_FILE)
         - __mark_inode_dirty_flag(, true)
      
      It's unnecessary, so let's just mark compressed inode dirty while
      compressed inode conversion.
      Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
      530e0704
  3. 23 Mar, 2020 6 commits
  4. 19 Mar, 2020 11 commits