1. 24 9月, 2020 1 次提交
  2. 22 9月, 2020 1 次提交
    • E
      f2fs: use fscrypt_prepare_new_inode() and fscrypt_set_context() · e075b690
      Eric Biggers 提交于
      Convert f2fs to use the new functions fscrypt_prepare_new_inode() and
      fscrypt_set_context().  This avoids calling
      fscrypt_get_encryption_info() from under f2fs_lock_op(), which can
      deadlock because fscrypt_get_encryption_info() isn't GFP_NOFS-safe.
      
      For more details about this problem, see the earlier patch
      "fscrypt: add fscrypt_prepare_new_inode() and fscrypt_set_context()".
      
      This also fixes a f2fs-specific deadlock when the filesystem is mounted
      with '-o test_dummy_encryption' and a file is created in an unencrypted
      directory other than the root directory:
      
          INFO: task touch:207 blocked for more than 30 seconds.
                Not tainted 5.9.0-rc4-00099-g729e3d09 #2
          "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
          task:touch           state:D stack:    0 pid:  207 ppid:   167 flags:0x00000000
          Call Trace:
           [...]
           lock_page include/linux/pagemap.h:548 [inline]
           pagecache_get_page+0x25e/0x310 mm/filemap.c:1682
           find_or_create_page include/linux/pagemap.h:348 [inline]
           grab_cache_page include/linux/pagemap.h:424 [inline]
           f2fs_grab_cache_page fs/f2fs/f2fs.h:2395 [inline]
           f2fs_grab_cache_page fs/f2fs/f2fs.h:2373 [inline]
           __get_node_page.part.0+0x39/0x2d0 fs/f2fs/node.c:1350
           __get_node_page fs/f2fs/node.c:35 [inline]
           f2fs_get_node_page+0x2e/0x60 fs/f2fs/node.c:1399
           read_inline_xattr+0x88/0x140 fs/f2fs/xattr.c:288
           lookup_all_xattrs+0x1f9/0x2c0 fs/f2fs/xattr.c:344
           f2fs_getxattr+0x9b/0x160 fs/f2fs/xattr.c:532
           f2fs_get_context+0x1e/0x20 fs/f2fs/super.c:2460
           fscrypt_get_encryption_info+0x9b/0x450 fs/crypto/keysetup.c:472
           fscrypt_inherit_context+0x2f/0xb0 fs/crypto/policy.c:640
           f2fs_init_inode_metadata+0xab/0x340 fs/f2fs/dir.c:540
           f2fs_add_inline_entry+0x145/0x390 fs/f2fs/inline.c:621
           f2fs_add_dentry+0x31/0x80 fs/f2fs/dir.c:757
           f2fs_do_add_link+0xcd/0x130 fs/f2fs/dir.c:798
           f2fs_add_link fs/f2fs/f2fs.h:3234 [inline]
           f2fs_create+0x104/0x290 fs/f2fs/namei.c:344
           lookup_open.isra.0+0x2de/0x500 fs/namei.c:3103
           open_last_lookups+0xa9/0x340 fs/namei.c:3177
           path_openat+0x8f/0x1b0 fs/namei.c:3365
           do_filp_open+0x87/0x130 fs/namei.c:3395
           do_sys_openat2+0x96/0x150 fs/open.c:1168
           [...]
      
      That happened because f2fs_add_inline_entry() locks the directory
      inode's page in order to add the dentry, then f2fs_get_context() tries
      to lock it recursively in order to read the encryption xattr.  This
      problem is specific to "test_dummy_encryption" because normally the
      directory's fscrypt_info would be set up prior to
      f2fs_add_inline_entry() in order to encrypt the new filename.
      
      Regardless, the new design fixes this test_dummy_encryption deadlock as
      well as potential deadlocks with fs reclaim, by setting up any needed
      fscrypt_info structs prior to taking so many locks.
      
      The test_dummy_encryption deadlock was reported by Daniel Rosenberg.
      Reported-by: NDaniel Rosenberg <drosen@google.com>
      Acked-by: NJaegeuk Kim <jaegeuk@kernel.org>
      Link: https://lore.kernel.org/r/20200917041136.178600-5-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      e075b690
  3. 08 9月, 2020 1 次提交
  4. 08 7月, 2020 1 次提交
  5. 09 6月, 2020 1 次提交
    • E
      f2fs: avoid utf8_strncasecmp() with unstable name · fc3bb095
      Eric Biggers 提交于
      If the dentry name passed to ->d_compare() fits in dentry::d_iname, then
      it may be concurrently modified by a rename.  This can cause undefined
      behavior (possibly out-of-bounds memory accesses or crashes) in
      utf8_strncasecmp(), since fs/unicode/ isn't written to handle strings
      that may be concurrently modified.
      
      Fix this by first copying the filename to a stack buffer if needed.
      This way we get a stable snapshot of the filename.
      
      Fixes: 2c2eb7a3 ("f2fs: Support case-insensitive file name lookups")
      Cc: <stable@vger.kernel.org> # v5.4+
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Daniel Rosenberg <drosen@google.com>
      Cc: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      fc3bb095
  6. 12 5月, 2020 2 次提交
    • E
      f2fs: rework filename handling · 43c780ba
      Eric Biggers 提交于
      Rework f2fs's handling of filenames to use a new 'struct f2fs_filename'.
      Similar to 'struct ext4_filename', this stores the usr_fname, disk_name,
      dirhash, crypto_buf, and casefolded name.  Some of these names can be
      NULL in some cases.  'struct f2fs_filename' differs from
      'struct fscrypt_name' mainly in that the casefolded name is included.
      
      For user-initiated directory operations like lookup() and create(),
      initialize the f2fs_filename by translating the corresponding
      fscrypt_name, then computing the dirhash and casefolded name if needed.
      
      This makes the dirhash and casefolded name be cached for each syscall,
      so we don't have to recompute them repeatedly.  (Previously, f2fs
      computed the dirhash once per directory level, and the casefolded name
      once per directory block.)  This improves performance.
      
      This rework also makes it much easier to correctly handle all
      combinations of normal, encrypted, casefolded, and encrypted+casefolded
      directories.  (The fourth isn't supported yet but is being worked on.)
      
      The only other cases where an f2fs_filename gets initialized are for two
      filesystem-internal operations: (1) when converting an inline directory
      to a regular one, we grab the needed disk_name and hash from an existing
      f2fs_dir_entry; and (2) when roll-forward recovering a new dentry, we
      grab the needed disk_name from f2fs_inode::i_name and compute the hash.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      43c780ba
    • E
      f2fs: split f2fs_d_compare() from f2fs_match_name() · f874fa1c
      Eric Biggers 提交于
      Sharing f2fs_ci_compare() between comparing cached dentries
      (f2fs_d_compare()) and comparing on-disk dentries (f2fs_match_name())
      doesn't work as well as intended, as these actions fundamentally differ
      in several ways (e.g. whether the task may sleep, whether the directory
      is stable, whether the casefolded name was precomputed, whether the
      dentry will need to be decrypted once we allow casefold+encrypt, etc.)
      
      Just make f2fs_d_compare() implement what it needs directly, and rework
      f2fs_ci_compare() to be specialized for f2fs_match_name().
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      f874fa1c
  7. 31 3月, 2020 2 次提交
  8. 25 1月, 2020 2 次提交
    • E
      f2fs: fix race conditions in ->d_compare() and ->d_hash() · 80f2388a
      Eric Biggers 提交于
      Since ->d_compare() and ->d_hash() can be called in RCU-walk mode,
      ->d_parent and ->d_inode can be concurrently modified, and in
      particular, ->d_inode may be changed to NULL.  For f2fs_d_hash() this
      resulted in a reproducible NULL dereference if a lookup is done in a
      directory being deleted, e.g. with:
      
      	int main()
      	{
      		if (fork()) {
      			for (;;) {
      				mkdir("subdir", 0700);
      				rmdir("subdir");
      			}
      		} else {
      			for (;;)
      				access("subdir/file", 0);
      		}
      	}
      
      ... or by running the 't_encrypted_d_revalidate' program from xfstests.
      Both repros work in any directory on a filesystem with the encoding
      feature, even if the directory doesn't actually have the casefold flag.
      
      I couldn't reproduce a crash in f2fs_d_compare(), but it appears that a
      similar crash is possible there.
      
      Fix these bugs by reading ->d_parent and ->d_inode using READ_ONCE() and
      falling back to the case sensitive behavior if the inode is NULL.
      Reported-by: NAl Viro <viro@zeniv.linux.org.uk>
      Fixes: 2c2eb7a3 ("f2fs: Support case-insensitive file name lookups")
      Cc: <stable@vger.kernel.org> # v5.4+
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      80f2388a
    • E
      f2fs: fix dcache lookup of !casefolded directories · 5515eae6
      Eric Biggers 提交于
      Do the name comparison for non-casefolded directories correctly.
      
      This is analogous to ext4's commit 66883da1 ("ext4: fix dcache
      lookup of !casefolded directories").
      
      Fixes: 2c2eb7a3 ("f2fs: Support case-insensitive file name lookups")
      Cc: <stable@vger.kernel.org> # v5.4+
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      5515eae6
  9. 18 1月, 2020 1 次提交
  10. 01 1月, 2020 1 次提交
  11. 20 11月, 2019 1 次提交
  12. 16 9月, 2019 1 次提交
    • C
      f2fs: fix to avoid accessing uninitialized field of inode page in is_alive() · 98194030
      Chao Yu 提交于
      If inode is newly created, inode page may not synchronize with inode cache,
      so fields like .i_inline or .i_extra_isize could be wrong, in below call
      path, we may access such wrong fields, result in failing to migrate valid
      target block.
      
      Thread A				Thread B
      - f2fs_create
       - f2fs_add_link
        - f2fs_add_dentry
         - f2fs_init_inode_metadata
          - f2fs_add_inline_entry
           - f2fs_new_inode_page
           - f2fs_put_page
           : inode page wasn't updated with inode cache
      					- gc_data_segment
      					 - is_alive
      					  - f2fs_get_node_page
      					  - datablock_addr
      					   - offset_in_addr
      					   : access uninitialized fields
      
      Fixes: 7a2af766 ("f2fs: enhance on-disk inode structure scalability")
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      98194030
  13. 07 9月, 2019 1 次提交
  14. 23 8月, 2019 2 次提交
    • C
      f2fs: introduce f2fs_match_name() for cleanup · fe76a166
      Chao Yu 提交于
      This patch introduces f2fs_match_name() for cleanup.
      
      BTW, it avoids to fallback to normal comparison once it doesn't
      match casefolded name.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      fe76a166
    • D
      f2fs: Support case-insensitive file name lookups · 2c2eb7a3
      Daniel Rosenberg 提交于
      Modeled after commit b886ee3e ("ext4: Support case-insensitive file
      name lookups")
      
      """
      This patch implements the actual support for case-insensitive file name
      lookups in f2fs, based on the feature bit and the encoding stored in the
      superblock.
      
      A filesystem that has the casefold feature set is able to configure
      directories with the +F (F2FS_CASEFOLD_FL) attribute, enabling lookups
      to succeed in that directory in a case-insensitive fashion, i.e: match
      a directory entry even if the name used by userspace is not a byte per
      byte match with the disk name, but is an equivalent case-insensitive
      version of the Unicode string.  This operation is called a
      case-insensitive file name lookup.
      
      The feature is configured as an inode attribute applied to directories
      and inherited by its children.  This attribute can only be enabled on
      empty directories for filesystems that support the encoding feature,
      thus preventing collision of file names that only differ by case.
      
      * dcache handling:
      
      For a +F directory, F2Fs only stores the first equivalent name dentry
      used in the dcache. This is done to prevent unintentional duplication of
      dentries in the dcache, while also allowing the VFS code to quickly find
      the right entry in the cache despite which equivalent string was used in
      a previous lookup, without having to resort to ->lookup().
      
      d_hash() of casefolded directories is implemented as the hash of the
      casefolded string, such that we always have a well-known bucket for all
      the equivalencies of the same string. d_compare() uses the
      utf8_strncasecmp() infrastructure, which handles the comparison of
      equivalent, same case, names as well.
      
      For now, negative lookups are not inserted in the dcache, since they
      would need to be invalidated anyway, because we can't trust missing file
      dentries.  This is bad for performance but requires some leveraging of
      the vfs layer to fix.  We can live without that for now, and so does
      everyone else.
      
      * on-disk data:
      
      Despite using a specific version of the name as the internal
      representation within the dcache, the name stored and fetched from the
      disk is a byte-per-byte match with what the user requested, making this
      implementation 'name-preserving'. i.e. no actual information is lost
      when writing to storage.
      
      DX is supported by modifying the hashes used in +F directories to make
      them case/encoding-aware.  The new disk hashes are calculated as the
      hash of the full casefolded string, instead of the string directly.
      This allows us to efficiently search for file names in the htree without
      requiring the user to provide an exact name.
      
      * Dealing with invalid sequences:
      
      By default, when a invalid UTF-8 sequence is identified, ext4 will treat
      it as an opaque byte sequence, ignoring the encoding and reverting to
      the old behavior for that unique file.  This means that case-insensitive
      file name lookup will not work only for that file.  An optional bit can
      be set in the superblock telling the filesystem code and userspace tools
      to enforce the encoding.  When that optional bit is set, any attempt to
      create a file name using an invalid UTF-8 sequence will fail and return
      an error to userspace.
      
      * Normalization algorithm:
      
      The UTF-8 algorithms used to compare strings in f2fs is implemented
      in fs/unicode, and is based on a previous version developed by
      SGI.  It implements the Canonical decomposition (NFD) algorithm
      described by the Unicode specification 12.1, or higher, combined with
      the elimination of ignorable code points (NFDi) and full
      case-folding (CF) as documented in fs/unicode/utf8_norm.c.
      
      NFD seems to be the best normalization method for F2FS because:
      
        - It has a lower cost than NFC/NFKC (which requires
          decomposing to NFD as an intermediary step)
        - It doesn't eliminate important semantic meaning like
          compatibility decompositions.
      
      Although:
      
      - This implementation is not completely linguistic accurate, because
      different languages have conflicting rules, which would require the
      specialization of the filesystem to a given locale, which brings all
      sorts of problems for removable media and for users who use more than
      one language.
      """
      Signed-off-by: NDaniel Rosenberg <drosen@google.com>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      2c2eb7a3
  15. 03 7月, 2019 2 次提交
  16. 31 5月, 2019 1 次提交
  17. 13 3月, 2019 2 次提交
  18. 24 1月, 2019 1 次提交
  19. 23 1月, 2019 2 次提交
  20. 27 12月, 2018 1 次提交
  21. 27 11月, 2018 1 次提交
  22. 23 10月, 2018 1 次提交
  23. 21 10月, 2018 1 次提交
  24. 17 10月, 2018 1 次提交
  25. 13 9月, 2018 1 次提交
  26. 12 9月, 2018 1 次提交
  27. 15 8月, 2018 1 次提交
    • A
      f2fs: rework fault injection handling to avoid a warning · 7fa750a1
      Arnd Bergmann 提交于
      When CONFIG_F2FS_FAULT_INJECTION is disabled, we get a warning about an
      unused label:
      
      fs/f2fs/segment.c: In function '__submit_discard_cmd':
      fs/f2fs/segment.c:1059:1: error: label 'submit' defined but not used [-Werror=unused-label]
      
      This could be fixed by adding another #ifdef around it, but the more
      reliable way of doing this seems to be to remove the other #ifdefs
      where that is easily possible.
      
      By defining time_to_inject() as a trivial stub, most of the checks for
      CONFIG_F2FS_FAULT_INJECTION can go away. This also leads to nicer
      formatting of the code.
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      7fa750a1
  28. 01 6月, 2018 3 次提交
    • C
      f2fs: clean up symbol namespace · 4d57b86d
      Chao Yu 提交于
      As Ted reported:
      
      "Hi, I was looking at f2fs's sources recently, and I noticed that there
      is a very large number of non-static symbols which don't have a f2fs
      prefix.  There's well over a hundred (see attached below).
      
      As one example, in fs/f2fs/dir.c there is:
      
      unsigned char get_de_type(struct f2fs_dir_entry *de)
      
      This function is clearly only useful for f2fs, but it has a generic
      name.  This means that if any other file system tries to have the same
      symbol name, there will be a symbol conflict and the kernel would not
      successfully build.  It also means that when someone is looking f2fs
      sources, it's not at all obvious whether a function such as
      read_data_page(), invalidate_blocks(), is a generic kernel function
      found in the fs, mm, or block layers, or a f2fs specific function.
      
      You might want to fix this at some point.  Hopefully Kent's bcachefs
      isn't similarly using genericly named functions, since that might
      cause conflicts with f2fs's functions --- but just as this would be a
      problem that we would rightly insist that Kent fix, this is something
      that we should have rightly insisted that f2fs should have fixed
      before it was integrated into the mainline kernel.
      
      acquire_orphan_inode
      add_ino_entry
      add_orphan_inode
      allocate_data_block
      allocate_new_segments
      alloc_nid
      alloc_nid_done
      alloc_nid_failed
      available_free_memory
      ...."
      
      This patch adds "f2fs_" prefix for all non-static symbols in order to:
      a) avoid conflict with other kernel generic symbols;
      b) to indicate the function is f2fs specific one instead of generic
      one;
      Reported-by: NTheodore Ts'o <tytso@mit.edu>
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      4d57b86d
    • C
      f2fs: make set_de_type() static · 2e79d951
      Chao Yu 提交于
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      2e79d951
    • C
      f2fs: clean up with clear_radix_tree_dirty_tag · aec2f729
      Chao Yu 提交于
      Introduce clear_radix_tree_dirty_tag to include common codes for cleanup.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      aec2f729
  29. 12 4月, 2018 1 次提交
  30. 17 3月, 2018 2 次提交