1. 12 5月, 2020 2 次提交
    • C
      f2fs: remove redundant assignment to variable err · deaf160f
      Colin Ian King 提交于
      The variable err is being assigned with a value that is never read
      and it is being updated later with a new value. The initialization is
      redundant and can be removed.
      
      Addresses-Coverity: ("Unused value")
      Signed-off-by: NColin Ian King <colin.king@canonical.com>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      deaf160f
    • 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
  2. 31 3月, 2020 2 次提交
  3. 11 3月, 2020 1 次提交
  4. 18 1月, 2020 2 次提交
    • J
      f2fs: convert inline_dir early before starting rename · b06af2af
      Jaegeuk Kim 提交于
      If we hit an error during rename, we'll get two dentries in different
      directories.
      
      Chao adds to check the room in inline_dir which can avoid needless
      inversion. This should be done by inode_lock(&old_dir).
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      b06af2af
    • C
      f2fs: support data compression · 4c8ff709
      Chao Yu 提交于
      This patch tries to support compression in f2fs.
      
      - New term named cluster is defined as basic unit of compression, file can
      be divided into multiple clusters logically. One cluster includes 4 << n
      (n >= 0) logical pages, compression size is also cluster size, each of
      cluster can be compressed or not.
      
      - In cluster metadata layout, one special flag is used to indicate cluster
      is compressed one or normal one, for compressed cluster, following metadata
      maps cluster to [1, 4 << n - 1] physical blocks, in where f2fs stores
      data including compress header and compressed data.
      
      - In order to eliminate write amplification during overwrite, F2FS only
      support compression on write-once file, data can be compressed only when
      all logical blocks in file are valid and cluster compress ratio is lower
      than specified threshold.
      
      - To enable compression on regular inode, there are three ways:
      * chattr +c file
      * chattr +c dir; touch dir/file
      * mount w/ -o compress_extension=ext; touch file.ext
      
      Compress metadata layout:
                                   [Dnode Structure]
                   +-----------------------------------------------+
                   | cluster 1 | cluster 2 | ......... | cluster N |
                   +-----------------------------------------------+
                   .           .                       .           .
             .                       .                .                      .
        .         Compressed Cluster       .        .        Normal Cluster            .
      +----------+---------+---------+---------+  +---------+---------+---------+---------+
      |compr flag| block 1 | block 2 | block 3 |  | block 1 | block 2 | block 3 | block 4 |
      +----------+---------+---------+---------+  +---------+---------+---------+---------+
                 .                             .
               .                                           .
             .                                                           .
            +-------------+-------------+----------+----------------------------+
            | data length | data chksum | reserved |      compressed data       |
            +-------------+-------------+----------+----------------------------+
      
      Changelog:
      
      20190326:
      - fix error handling of read_end_io().
      - remove unneeded comments in f2fs_encrypt_one_page().
      
      20190327:
      - fix wrong use of f2fs_cluster_is_full() in f2fs_mpage_readpages().
      - don't jump into loop directly to avoid uninitialized variables.
      - add TODO tag in error path of f2fs_write_cache_pages().
      
      20190328:
      - fix wrong merge condition in f2fs_read_multi_pages().
      - check compressed file in f2fs_post_read_required().
      
      20190401
      - allow overwrite on non-compressed cluster.
      - check cluster meta before writing compressed data.
      
      20190402
      - don't preallocate blocks for compressed file.
      
      - add lz4 compress algorithm
      - process multiple post read works in one workqueue
        Now f2fs supports processing post read work in multiple workqueue,
        it shows low performance due to schedule overhead of multiple
        workqueue executing orderly.
      
      20190921
      - compress: support buffered overwrite
      C: compress cluster flag
      V: valid block address
      N: NEW_ADDR
      
      One cluster contain 4 blocks
      
       before overwrite   after overwrite
      
      - VVVV		->	CVNN
      - CVNN		->	VVVV
      
      - CVNN		->	CVNN
      - CVNN		->	CVVV
      
      - CVVV		->	CVNN
      - CVVV		->	CVVV
      
      20191029
      - add kconfig F2FS_FS_COMPRESSION to isolate compression related
      codes, add kconfig F2FS_FS_{LZO,LZ4} to cover backend algorithm.
      note that: will remove lzo backend if Jaegeuk agreed that too.
      - update codes according to Eric's comments.
      
      20191101
      - apply fixes from Jaegeuk
      
      20191113
      - apply fixes from Jaegeuk
      - split workqueue for fsverity
      
      20191216
      - apply fixes from Jaegeuk
      
      20200117
      - fix to avoid NULL pointer dereference
      
      [Jaegeuk Kim]
      - add tracepoint for f2fs_{,de}compress_pages()
      - fix many bugs and add some compression stats
      - fix overwrite/mmap bugs
      - address 32bit build error, reported by Geert.
      - bug fixes when handling errors and i_compressed_blocks
      
      Reported-by: <noreply@ellerman.id.au>
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      4c8ff709
  5. 16 1月, 2020 2 次提交
    • J
      f2fs: don't put new_page twice in f2fs_rename · 762e4db5
      Jaegeuk Kim 提交于
      In f2fs_rename(), new_page is gone after f2fs_set_link(), but it tries
      to put again when whiteout is failed and jumped to put_out_dir.
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      762e4db5
    • J
      f2fs: set I_LINKABLE early to avoid wrong access by vfs · 5b1dbb08
      Jaegeuk Kim 提交于
      This patch moves setting I_LINKABLE early in rename2(whiteout) to avoid the
      below warning.
      
      [ 3189.163385] WARNING: CPU: 3 PID: 59523 at fs/inode.c:358 inc_nlink+0x32/0x40
      [ 3189.246979] Call Trace:
      [ 3189.248707]  f2fs_init_inode_metadata+0x2d6/0x440 [f2fs]
      [ 3189.251399]  f2fs_add_inline_entry+0x162/0x8c0 [f2fs]
      [ 3189.254010]  f2fs_add_dentry+0x69/0xe0 [f2fs]
      [ 3189.256353]  f2fs_do_add_link+0xc5/0x100 [f2fs]
      [ 3189.258774]  f2fs_rename2+0xabf/0x1010 [f2fs]
      [ 3189.261079]  vfs_rename+0x3f8/0xaa0
      [ 3189.263056]  ? tomoyo_path_rename+0x44/0x60
      [ 3189.265283]  ? do_renameat2+0x49b/0x550
      [ 3189.267324]  do_renameat2+0x49b/0x550
      [ 3189.269316]  __x64_sys_renameat2+0x20/0x30
      [ 3189.271441]  do_syscall_64+0x5a/0x230
      [ 3189.273410]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
      [ 3189.275848] RIP: 0033:0x7f270b4d9a49
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      5b1dbb08
  6. 08 11月, 2019 1 次提交
    • C
      f2fs: fix to update dir's i_pino during cross_rename · 2a60637f
      Chao Yu 提交于
      As Eric reported:
      
      RENAME_EXCHANGE support was just added to fsstress in xfstests:
      
      	commit 65dfd40a97b6bbbd2a22538977bab355c5bc0f06
      	Author: kaixuxia <xiakaixu1987@gmail.com>
      	Date:   Thu Oct 31 14:41:48 2019 +0800
      
      	    fsstress: add EXCHANGE renameat2 support
      
      This is causing xfstest generic/579 to fail due to fsck.f2fs reporting errors.
      I'm not sure what the problem is, but it still happens even with all the
      fs-verity stuff in the test commented out, so that the test just runs fsstress.
      
      generic/579 23s ... 	[10:02:25]
      [    7.745370] run fstests generic/579 at 2019-11-04 10:02:25
      _check_generic_filesystem: filesystem on /dev/vdc is inconsistent
      (see /results/f2fs/results-default/generic/579.full for details)
       [10:02:47]
      Ran: generic/579
      Failures: generic/579
      Failed 1 of 1 tests
      Xunit report: /results/f2fs/results-default/result.xml
      
      Here's the contents of 579.full:
      
      _check_generic_filesystem: filesystem on /dev/vdc is inconsistent
      *** fsck.f2fs output ***
      [ASSERT] (__chk_dots_dentries:1378)  --> Bad inode number[0x24] for '..', parent parent ino is [0xd10]
      
      The root cause is that we forgot to update directory's i_pino during
      cross_rename, fix it.
      
      Fixes: 32f9bc25 ("f2fs: support ->rename2()")
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Tested-by: NEric Biggers <ebiggers@kernel.org>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      2a60637f
  7. 07 9月, 2019 1 次提交
  8. 23 8月, 2019 3 次提交
    • 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
    • C
      f2fs: fix to spread f2fs_is_checkpoint_ready() · 955ebcd3
      Chao Yu 提交于
      We missed to call f2fs_is_checkpoint_ready() in several places, it may
      allow space allocation even when free space was exhausted during
      checkpoint is disabled, fix to add them.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      955ebcd3
    • C
      f2fs: support fiemap() for directory inode · 7975f349
      Chao Yu 提交于
      Adjust f2fs_fiemap() to support fiemap() on directory inode.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      7975f349
  9. 03 7月, 2019 1 次提交
  10. 09 5月, 2019 1 次提交
  11. 17 4月, 2019 1 次提交
    • E
      fscrypt: fix race where ->lookup() marks plaintext dentry as ciphertext · b01531db
      Eric Biggers 提交于
      ->lookup() in an encrypted directory begins as follows:
      
      1. fscrypt_prepare_lookup():
          a. Try to load the directory's encryption key.
          b. If the key is unavailable, mark the dentry as a ciphertext name
             via d_flags.
      2. fscrypt_setup_filename():
          a. Try to load the directory's encryption key.
          b. If the key is available, encrypt the name (treated as a plaintext
             name) to get the on-disk name.  Otherwise decode the name
             (treated as a ciphertext name) to get the on-disk name.
      
      But if the key is concurrently added, it may be found at (2a) but not at
      (1a).  In this case, the dentry will be wrongly marked as a ciphertext
      name even though it was actually treated as plaintext.
      
      This will cause the dentry to be wrongly invalidated on the next lookup,
      potentially causing problems.  For example, if the racy ->lookup() was
      part of sys_mount(), then the new mount will be detached when anything
      tries to access it.  This is despite the mountpoint having a plaintext
      path, which should remain valid now that the key was added.
      
      Of course, this is only possible if there's a userspace race.  Still,
      the additional kernel-side race is confusing and unexpected.
      
      Close the kernel-side race by changing fscrypt_prepare_lookup() to also
      set the on-disk filename (step 2b), consistent with the d_flags update.
      
      Fixes: 28b4c263 ("ext4 crypto: revalidate dentry after adding or removing the key")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      b01531db
  12. 13 3月, 2019 1 次提交
  13. 24 1月, 2019 1 次提交
  14. 27 12月, 2018 1 次提交
    • J
      f2fs: use kvmalloc, if kmalloc is failed · 5222595d
      Jaegeuk Kim 提交于
      One report says memalloc failure during mount.
      
       (unwind_backtrace) from [<c010cd4c>] (show_stack+0x10/0x14)
       (show_stack) from [<c049c6b8>] (dump_stack+0x8c/0xa0)
       (dump_stack) from [<c024fcf0>] (warn_alloc+0xc4/0x160)
       (warn_alloc) from [<c0250218>] (__alloc_pages_nodemask+0x3f4/0x10d0)
       (__alloc_pages_nodemask) from [<c0270450>] (kmalloc_order_trace+0x2c/0x120)
       (kmalloc_order_trace) from [<c03fa748>] (build_node_manager+0x35c/0x688)
       (build_node_manager) from [<c03de494>] (f2fs_fill_super+0xf0c/0x16cc)
       (f2fs_fill_super) from [<c02a5864>] (mount_bdev+0x15c/0x188)
       (mount_bdev) from [<c03da624>] (f2fs_mount+0x18/0x20)
       (f2fs_mount) from [<c02a68b8>] (mount_fs+0x158/0x19c)
       (mount_fs) from [<c02c3c9c>] (vfs_kern_mount+0x78/0x134)
       (vfs_kern_mount) from [<c02c76ac>] (do_mount+0x474/0xca4)
       (do_mount) from [<c02c8264>] (SyS_mount+0x94/0xbc)
       (SyS_mount) from [<c0108180>] (ret_fast_syscall+0x0/0x48)
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      5222595d
  15. 27 11月, 2018 1 次提交
  16. 23 10月, 2018 2 次提交
    • C
      f2fs: guarantee journalled quota data by checkpoint · af033b2a
      Chao Yu 提交于
      For journalled quota mode, let checkpoint to flush dquot dirty data
      and quota file data to guarntee persistence of all quota sysfile in
      last checkpoint, by this way, we can avoid corrupting quota sysfile
      when encountering SPO.
      
      The implementation is as below:
      
      1. add a global state SBI_QUOTA_NEED_FLUSH to indicate that there is
      cached dquot metadata changes in quota subsystem, and later checkpoint
      should:
       a) flush dquot metadata into quota file.
       b) flush quota file to storage to keep file usage be consistent.
      
      2. add a global state SBI_QUOTA_NEED_REPAIR to indicate that quota
      operation failed due to -EIO or -ENOSPC, so later,
       a) checkpoint will skip syncing dquot metadata.
       b) CP_QUOTA_NEED_FSCK_FLAG will be set in last cp pack to give a
          hint for fsck repairing.
      
      3. add a global state SBI_QUOTA_SKIP_FLUSH, in checkpoint, if quota
      data updating is very heavy, it may cause hungtask in block_operation().
      To avoid this, if our retry time exceed threshold, let's just skip
      flushing and retry in next checkpoint().
      Signed-off-by: NWeichao Guo <guoweichao@huawei.com>
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      [Jaegeuk Kim: avoid warnings and set fsck flag]
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      af033b2a
    • C
      f2fs: spread f2fs_set_inode_flags() · 9149a5eb
      Chao Yu 提交于
      This patch changes codes as below:
      - use f2fs_set_inode_flags() to update i_flags atomically to avoid
      potential race.
      - synchronize F2FS_I(inode)->i_flags to inode->i_flags in
      f2fs_new_inode().
      - use f2fs_set_inode_flags() to simply codes in f2fs_quota_{on,off}.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      9149a5eb
  17. 17 10月, 2018 3 次提交
  18. 27 9月, 2018 1 次提交
  19. 13 9月, 2018 1 次提交
  20. 29 7月, 2018 1 次提交
    • G
      f2fs: Replace strncpy with memcpy · b1385478
      Guenter Roeck 提交于
      gcc 8.1.0 complains:
      
      fs/f2fs/namei.c: In function 'f2fs_update_extension_list':
      fs/f2fs/namei.c:257:3: warning:
      	'strncpy' output truncated before terminating nul copying
      	as many bytes from a string as its length
      fs/f2fs/namei.c:249:3: warning:
      	'strncpy' output truncated before terminating nul copying
      	as many bytes from a string as its length
      
      Using strncpy() is indeed less than perfect since the length of data to
      be copied has already been determined with strlen(). Replace strncpy()
      with memcpy() to address the warning and optimize the code a little.
      Signed-off-by: NGuenter Roeck <linux@roeck-us.net>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      b1385478
  21. 27 7月, 2018 1 次提交
  22. 06 6月, 2018 1 次提交
    • D
      vfs: change inode times to use struct timespec64 · 95582b00
      Deepa Dinamani 提交于
      struct timespec is not y2038 safe. Transition vfs to use
      y2038 safe struct timespec64 instead.
      
      The change was made with the help of the following cocinelle
      script. This catches about 80% of the changes.
      All the header file and logic changes are included in the
      first 5 rules. The rest are trivial substitutions.
      I avoid changing any of the function signatures or any other
      filesystem specific data structures to keep the patch simple
      for review.
      
      The script can be a little shorter by combining different cases.
      But, this version was sufficient for my usecase.
      
      virtual patch
      
      @ depends on patch @
      identifier now;
      @@
      - struct timespec
      + struct timespec64
        current_time ( ... )
        {
      - struct timespec now = current_kernel_time();
      + struct timespec64 now = current_kernel_time64();
        ...
      - return timespec_trunc(
      + return timespec64_trunc(
        ... );
        }
      
      @ depends on patch @
      identifier xtime;
      @@
       struct \( iattr \| inode \| kstat \) {
       ...
      -       struct timespec xtime;
      +       struct timespec64 xtime;
       ...
       }
      
      @ depends on patch @
      identifier t;
      @@
       struct inode_operations {
       ...
      int (*update_time) (...,
      -       struct timespec t,
      +       struct timespec64 t,
      ...);
       ...
       }
      
      @ depends on patch @
      identifier t;
      identifier fn_update_time =~ "update_time$";
      @@
       fn_update_time (...,
      - struct timespec *t,
      + struct timespec64 *t,
       ...) { ... }
      
      @ depends on patch @
      identifier t;
      @@
      lease_get_mtime( ... ,
      - struct timespec *t
      + struct timespec64 *t
        ) { ... }
      
      @te depends on patch forall@
      identifier ts;
      local idexpression struct inode *inode_node;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn_update_time =~ "update_time$";
      identifier fn;
      expression e, E3;
      local idexpression struct inode *node1;
      local idexpression struct inode *node2;
      local idexpression struct iattr *attr1;
      local idexpression struct iattr *attr2;
      local idexpression struct iattr attr;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      @@
      (
      (
      - struct timespec ts;
      + struct timespec64 ts;
      |
      - struct timespec ts = current_time(inode_node);
      + struct timespec64 ts = current_time(inode_node);
      )
      
      <+... when != ts
      (
      - timespec_equal(&inode_node->i_xtime, &ts)
      + timespec64_equal(&inode_node->i_xtime, &ts)
      |
      - timespec_equal(&ts, &inode_node->i_xtime)
      + timespec64_equal(&ts, &inode_node->i_xtime)
      |
      - timespec_compare(&inode_node->i_xtime, &ts)
      + timespec64_compare(&inode_node->i_xtime, &ts)
      |
      - timespec_compare(&ts, &inode_node->i_xtime)
      + timespec64_compare(&ts, &inode_node->i_xtime)
      |
      ts = current_time(e)
      |
      fn_update_time(..., &ts,...)
      |
      inode_node->i_xtime = ts
      |
      node1->i_xtime = ts
      |
      ts = inode_node->i_xtime
      |
      <+... attr1->ia_xtime ...+> = ts
      |
      ts = attr1->ia_xtime
      |
      ts.tv_sec
      |
      ts.tv_nsec
      |
      btrfs_set_stack_timespec_sec(..., ts.tv_sec)
      |
      btrfs_set_stack_timespec_nsec(..., ts.tv_nsec)
      |
      - ts = timespec64_to_timespec(
      + ts =
      ...
      -)
      |
      - ts = ktime_to_timespec(
      + ts = ktime_to_timespec64(
      ...)
      |
      - ts = E3
      + ts = timespec_to_timespec64(E3)
      |
      - ktime_get_real_ts(&ts)
      + ktime_get_real_ts64(&ts)
      |
      fn(...,
      - ts
      + timespec64_to_timespec(ts)
      ,...)
      )
      ...+>
      (
      <... when != ts
      - return ts;
      + return timespec64_to_timespec(ts);
      ...>
      )
      |
      - timespec_equal(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_equal(&node1->i_xtime2, &node2->i_xtime2)
      |
      - timespec_equal(&node1->i_xtime1, &attr2->ia_xtime2)
      + timespec64_equal(&node1->i_xtime2, &attr2->ia_xtime2)
      |
      - timespec_compare(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_compare(&node1->i_xtime1, &node2->i_xtime2)
      |
      node1->i_xtime1 =
      - timespec_trunc(attr1->ia_xtime1,
      + timespec64_trunc(attr1->ia_xtime1,
      ...)
      |
      - attr1->ia_xtime1 = timespec_trunc(attr2->ia_xtime2,
      + attr1->ia_xtime1 =  timespec64_trunc(attr2->ia_xtime2,
      ...)
      |
      - ktime_get_real_ts(&attr1->ia_xtime1)
      + ktime_get_real_ts64(&attr1->ia_xtime1)
      |
      - ktime_get_real_ts(&attr.ia_xtime1)
      + ktime_get_real_ts64(&attr.ia_xtime1)
      )
      
      @ depends on patch @
      struct inode *node;
      struct iattr *attr;
      identifier fn;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      expression e;
      @@
      (
      - fn(node->i_xtime);
      + fn(timespec64_to_timespec(node->i_xtime));
      |
       fn(...,
      - node->i_xtime);
      + timespec64_to_timespec(node->i_xtime));
      |
      - e = fn(attr->ia_xtime);
      + e = fn(timespec64_to_timespec(attr->ia_xtime));
      )
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      )
      ...+>
      }
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      struct kstat *stat;
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier i_xtime =~ "^i_[acm]time$";
      identifier xtime =~ "^[acm]time$";
      identifier fn, ret;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(stat->xtime);
      ret = fn (...,
      - &stat->xtime);
      + &ts);
      )
      ...+>
      }
      
      @ depends on patch @
      struct inode *node;
      struct inode *node2;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier i_xtime3 =~ "^i_[acm]time$";
      struct iattr *attrp;
      struct iattr *attrp2;
      struct iattr attr ;
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      struct kstat *stat;
      struct kstat stat1;
      struct timespec64 ts;
      identifier xtime =~ "^[acmb]time$";
      expression e;
      @@
      (
      ( node->i_xtime2 \| attrp->ia_xtime2 \| attr.ia_xtime2 \) = node->i_xtime1  ;
      |
       node->i_xtime2 = \( node2->i_xtime1 \| timespec64_trunc(...) \);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       stat->xtime = node2->i_xtime1;
      |
       stat1.xtime = node2->i_xtime1;
      |
      ( node->i_xtime2 \| attrp->ia_xtime2 \) = attrp->ia_xtime1  ;
      |
      ( attrp->ia_xtime1 \| attr.ia_xtime1 \) = attrp2->ia_xtime2;
      |
      - e = node->i_xtime1;
      + e = timespec64_to_timespec( node->i_xtime1 );
      |
      - e = attrp->ia_xtime1;
      + e = timespec64_to_timespec( attrp->ia_xtime1 );
      |
      node->i_xtime1 = current_time(...);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
       node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
      - node->i_xtime1 = e;
      + node->i_xtime1 = timespec_to_timespec64(e);
      )
      Signed-off-by: NDeepa Dinamani <deepa.kernel@gmail.com>
      Cc: <anton@tuxera.com>
      Cc: <balbi@kernel.org>
      Cc: <bfields@fieldses.org>
      Cc: <darrick.wong@oracle.com>
      Cc: <dhowells@redhat.com>
      Cc: <dsterba@suse.com>
      Cc: <dwmw2@infradead.org>
      Cc: <hch@lst.de>
      Cc: <hirofumi@mail.parknet.co.jp>
      Cc: <hubcap@omnibond.com>
      Cc: <jack@suse.com>
      Cc: <jaegeuk@kernel.org>
      Cc: <jaharkes@cs.cmu.edu>
      Cc: <jslaby@suse.com>
      Cc: <keescook@chromium.org>
      Cc: <mark@fasheh.com>
      Cc: <miklos@szeredi.hu>
      Cc: <nico@linaro.org>
      Cc: <reiserfs-devel@vger.kernel.org>
      Cc: <richard@nod.at>
      Cc: <sage@redhat.com>
      Cc: <sfrench@samba.org>
      Cc: <swhiteho@redhat.com>
      Cc: <tj@kernel.org>
      Cc: <trond.myklebust@primarydata.com>
      Cc: <tytso@mit.edu>
      Cc: <viro@zeniv.linux.org.uk>
      95582b00
  23. 01 6月, 2018 4 次提交
    • 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: fix to initialize i_current_depth according to inode type · 1c41e680
      Chao Yu 提交于
      i_current_depth is used only for directory inode, but its space is
      shared with i_gc_failures field used for regular inode, in order to
      avoid affecting i_gc_failures' value, this patch fixes to initialize
      the union's fields according to inode type.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      1c41e680
    • J
      f2fs: enforce fsync_mode=strict for renamed directory · ade990f9
      Jaegeuk Kim 提交于
      This is to give a option for user to be able to recover B/foo in the below
      case.
      
      mkdir A
      sync()
      rename(A, B)
      creat (B/foo)
      fsync (B/foo)
      ---crash---
      Sugessted-by: NVelayudhan Pillai <vijay@cs.utexas.edu>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      ade990f9
    • C
      f2fs: introduce private inode status mapping · 59c84408
      Chao Yu 提交于
      Previously, we use generic FS_*_FL defined by vfs to indicate inode status
      for each bit of i_flags, so f2fs's flag status definition is tied to vfs'
      one, it will be hard for f2fs to reuse bits f2fs never used to indicate
      new status..
      
      In order to solve this issue, we introduce private inode status mapping,
      Note, for these bits have already been persisted into disk, we should
      never change their definition, for other ones, we can remap them for
      later new coming status.
      Signed-off-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      59c84408
  24. 12 5月, 2018 1 次提交
    • A
      do d_instantiate/unlock_new_inode combinations safely · 1e2e547a
      Al Viro 提交于
      For anything NFS-exported we do _not_ want to unlock new inode
      before it has grown an alias; original set of fixes got the
      ordering right, but missed the nasty complication in case of
      lockdep being enabled - unlock_new_inode() does
      	lockdep_annotate_inode_mutex_key(inode)
      which can only be done before anyone gets a chance to touch
      ->i_mutex.  Unfortunately, flipping the order and doing
      unlock_new_inode() before d_instantiate() opens a window when
      mkdir can race with open-by-fhandle on a guessed fhandle, leading
      to multiple aliases for a directory inode and all the breakage
      that follows from that.
      
      	Correct solution: a new primitive (d_instantiate_new())
      combining these two in the right order - lockdep annotate, then
      d_instantiate(), then the rest of unlock_new_inode().  All
      combinations of d_instantiate() with unlock_new_inode() should
      be converted to that.
      
      Cc: stable@kernel.org	# 2.6.29 and later
      Tested-by: NMike Marshall <hubcap@omnibond.com>
      Reviewed-by: NAndreas Dilger <adilger@dilger.ca>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      1e2e547a
  25. 03 5月, 2018 1 次提交
    • E
      f2fs: call unlock_new_inode() before d_instantiate() · ab3835aa
      Eric Biggers 提交于
      xfstest generic/429 sometimes hangs on f2fs, caused by a thread being
      unable to take a directory's i_rwsem for write in vfs_rmdir().  In the
      test, one thread repeatedly creates and removes a directory, and other
      threads repeatedly look up a file in the directory.  The bug is that
      f2fs_mkdir() calls d_instantiate() before unlock_new_inode(), resulting
      in the directory inode being exposed to lookups before it has been fully
      initialized.  And with CONFIG_DEBUG_LOCK_ALLOC, unlock_new_inode()
      reinitializes ->i_rwsem, corrupting its state when it is already held.
      
      Fix it by calling unlock_new_inode() before d_instantiate().  This
      matches what other filesystems do.
      
      Fixes: 57397d86 ("f2fs: add inode operations for special inodes")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Reviewed-by: NChao Yu <yuchao0@huawei.com>
      Signed-off-by: NJaegeuk Kim <jaegeuk@kernel.org>
      ab3835aa
  26. 17 3月, 2018 3 次提交