Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 Feb 2018 21:49:22 +0000 (13:49 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 Feb 2018 21:49:22 +0000 (13:49 -0800)
Pull ext4 updates from Ted Ts'o:
 "Only miscellaneous cleanups and bug fixes for ext4 this cycle"

* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: create ext4_kset dynamically
  ext4: create ext4_feat kobject dynamically
  ext4: release kobject/kset even when init/register fail
  ext4: fix incorrect indentation of if statement
  ext4: correct documentation for grpid mount option
  ext4: use 'sbi' instead of 'EXT4_SB(sb)'
  ext4: save error to disk in __ext4_grp_locked_error()
  jbd2: fix sphinx kernel-doc build warnings
  ext4: fix a race in the ext4 shutdown path
  mbcache: make sure c_entry_count is not decremented past zero
  ext4: no need flush workqueue before destroying it
  ext4: fixed alignment and minor code cleanup in ext4.h
  ext4: fix ENOSPC handling in DAX page fault handler
  dax: pass detailed error code from dax_iomap_fault()
  mbcache: revert "fs/mbcache.c: make count_objects() more robust"
  mbcache: initialize entry->e_referenced in mb_cache_entry_create()
  ext4: fix up remaining files with SPDX cleanups

1  2 
Documentation/filesystems/ext4.txt
fs/dax.c
fs/ext4/inline.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/super.c

index 8cd63e16f171c5dbcede0e53ea3a955a07fc05a8,d081ce0482cc9bb1e3d398c2be6324cd02eba9ba..7f628b9f7c4b4821589f357ec92b0ee91fa41b7b
@@@ -202,14 -202,15 +202,14 @@@ inode_readahead_blks=n  This tuning para
                        the buffer cache.  The default value is 32 blocks.
  
  nouser_xattr          Disables Extended User Attributes.  See the
 -                      attr(5) manual page and http://acl.bestbits.at/
 -                      for more information about extended attributes.
 +                      attr(5) manual page for more information about
 +                      extended attributes.
  
  noacl                 This option disables POSIX Access Control List
                        support. If ACL support is enabled in the kernel
                        configuration (CONFIG_EXT4_FS_POSIX_ACL), ACL is
                        enabled by default on mount. See the acl(5) manual
 -                      page and http://acl.bestbits.at/ for more information
 -                      about acl.
 +                      page for more information about acl.
  
  bsddf         (*)     Make 'df' act like BSD.
  minixdf                       Make 'df' act like Minix.
@@@ -232,7 -233,7 +232,7 @@@ data_err=ignore(*) Just print an error 
  data_err=abort                Abort the journal if an error occurs in a file
                        data buffer in ordered mode.
  
- grpid                 Give objects the same group ID as their creator.
+ grpid                 New objects have the group ID of their parent.
  bsdgroups
  
  nogrpid               (*)     New objects have the group ID of their creator.
diff --combined fs/dax.c
index 6ee6f7e24f5a4b8f90a35cde75f0987d63eeb152,f3afa1d6156cfbb13a2d0ea3775822186659a8f4..0276df90e86c588f1908409fee23c0152e0d63a6
+++ b/fs/dax.c
@@@ -44,7 -44,6 +44,7 @@@
  
  /* The 'colour' (ie low bits) within a PMD of a page offset.  */
  #define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1)
 +#define PG_PMD_NR     (PMD_SIZE >> PAGE_SHIFT)
  
  static wait_queue_head_t wait_table[DAX_WAIT_TABLE_ENTRIES];
  
@@@ -376,8 -375,8 +376,8 @@@ restart
                 * unmapped.
                 */
                if (pmd_downgrade && dax_is_zero_entry(entry))
 -                      unmap_mapping_range(mapping,
 -                              (index << PAGE_SHIFT) & PMD_MASK, PMD_SIZE, 0);
 +                      unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR,
 +                                                      PG_PMD_NR, false);
  
                err = radix_tree_preload(
                                mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM);
@@@ -539,10 -538,12 +539,10 @@@ static void *dax_insert_mapping_entry(s
        if (dax_is_zero_entry(entry) && !(flags & RADIX_DAX_ZERO_PAGE)) {
                /* we are replacing a zero page with block mapping */
                if (dax_is_pmd_entry(entry))
 -                      unmap_mapping_range(mapping,
 -                                      (vmf->pgoff << PAGE_SHIFT) & PMD_MASK,
 -                                      PMD_SIZE, 0);
 +                      unmap_mapping_pages(mapping, index & ~PG_PMD_COLOUR,
 +                                                      PG_PMD_NR, false);
                else /* pte entry */
 -                      unmap_mapping_range(mapping, vmf->pgoff << PAGE_SHIFT,
 -                                      PAGE_SIZE, 0);
 +                      unmap_mapping_pages(mapping, vmf->pgoff, 1, false);
        }
  
        spin_lock_irq(&mapping->tree_lock);
@@@ -635,8 -636,8 +635,8 @@@ static void dax_mapping_entry_mkclean(s
                        pmd = pmd_mkclean(pmd);
                        set_pmd_at(vma->vm_mm, address, pmdp, pmd);
  unlock_pmd:
 -                      spin_unlock(ptl);
  #endif
 +                      spin_unlock(ptl);
                } else {
                        if (pfn != pte_pfn(*ptep))
                                goto unlock_pte;
@@@ -1095,7 -1096,7 +1095,7 @@@ static bool dax_fault_is_synchronous(un
  }
  
  static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
-                              const struct iomap_ops *ops)
+                              int *iomap_errp, const struct iomap_ops *ops)
  {
        struct vm_area_struct *vma = vmf->vma;
        struct address_space *mapping = vma->vm_file->f_mapping;
         * that we never have to deal with more than a single extent here.
         */
        error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap);
+       if (iomap_errp)
+               *iomap_errp = error;
        if (error) {
                vmf_ret = dax_fault_return(error);
                goto unlock_entry;
  }
  
  #ifdef CONFIG_FS_DAX_PMD
 -/*
 - * The 'colour' (ie low bits) within a PMD of a page offset.  This comes up
 - * more often than one might expect in the below functions.
 - */
 -#define PG_PMD_COLOUR ((PMD_SIZE >> PAGE_SHIFT) - 1)
 -
  static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap,
                void *entry)
  {
@@@ -1481,6 -1490,7 +1483,7 @@@ static int dax_iomap_pmd_fault(struct v
   * @vmf: The description of the fault
   * @pe_size: Size of the page to fault in
   * @pfnp: PFN to insert for synchronous faults if fsync is required
+  * @iomap_errp: Storage for detailed error code in case of error
   * @ops: Iomap ops passed from the file system
   *
   * When a page fault occurs, filesystems may call this helper in
   * successfully.
   */
  int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size,
-                   pfn_t *pfnp, const struct iomap_ops *ops)
+                   pfn_t *pfnp, int *iomap_errp, const struct iomap_ops *ops)
  {
        switch (pe_size) {
        case PE_SIZE_PTE:
-               return dax_iomap_pte_fault(vmf, pfnp, ops);
+               return dax_iomap_pte_fault(vmf, pfnp, iomap_errp, ops);
        case PE_SIZE_PMD:
                return dax_iomap_pmd_fault(vmf, pfnp, ops);
        default:
diff --combined fs/ext4/inline.c
index a8b987b7117356cfee659fe57b9b9379a4fc3751,8b1f2901a5df10a940de3eb620eb9633985da6d2..7c4165b8850516f027530b0b71b9ef080d050219
@@@ -1,20 -1,11 +1,12 @@@
+ // SPDX-License-Identifier: LGPL-2.1
  /*
   * Copyright (c) 2012 Taobao.
   * Written by Tao Ma <boyu.mt@taobao.com>
-  *
-  * This program is free software; you can redistribute it and/or modify it
-  * under the terms of version 2.1 of the GNU Lesser General Public License
-  * as published by the Free Software Foundation.
-  *
-  * This program is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  * GNU General Public License for more details.
   */
  
  #include <linux/iomap.h>
  #include <linux/fiemap.h>
 +#include <linux/iversion.h>
  
  #include "ext4_jbd2.h"
  #include "ext4.h"
@@@ -1043,7 -1034,7 +1035,7 @@@ static int ext4_add_dirent_to_inline(ha
         */
        dir->i_mtime = dir->i_ctime = current_time(dir);
        ext4_update_dx_flag(dir);
 -      dir->i_version++;
 +      inode_inc_iversion(dir);
        return 1;
  }
  
@@@ -1495,7 -1486,7 +1487,7 @@@ int ext4_read_inline_dir(struct file *f
         * dirent right now.  Scan from the start of the inline
         * dir to make sure.
         */
 -      if (file->f_version != inode->i_version) {
 +      if (inode_cmp_iversion(inode, file->f_version)) {
                for (i = 0; i < extra_size && i < offset;) {
                        /*
                         * "." is with offset 0 and
                }
                offset = i;
                ctx->pos = offset;
 -              file->f_version = inode->i_version;
 +              file->f_version = inode_query_iversion(inode);
        }
  
        while (ctx->pos < extra_size) {
diff --combined fs/ext4/inode.c
index 0eff5b761c6e0687a91daf716b44c683f06a5b47,4c2f8b57bdc7331ae6ac2f2335f823c119c40607..c94780075b04f752b1cfdec9ccf6f631bd874116
@@@ -39,7 -39,6 +39,7 @@@
  #include <linux/slab.h>
  #include <linux/bitops.h>
  #include <linux/iomap.h>
 +#include <linux/iversion.h>
  
  #include "ext4_jbd2.h"
  #include "xattr.h"
@@@ -3768,10 -3767,18 +3768,18 @@@ static ssize_t ext4_direct_IO_write(str
                /* Credits for sb + inode write */
                handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
                if (IS_ERR(handle)) {
-                       /* This is really bad luck. We've written the data
-                        * but cannot extend i_size. Bail out and pretend
-                        * the write failed... */
-                       ret = PTR_ERR(handle);
+                       /*
+                        * We wrote the data but cannot extend
+                        * i_size. Bail out. In async io case, we do
+                        * not return error here because we have
+                        * already submmitted the corresponding
+                        * bio. Returning error here makes the caller
+                        * think that this IO is done and failed
+                        * resulting in race with bio's completion
+                        * handler.
+                        */
+                       if (!ret)
+                               ret = PTR_ERR(handle);
                        if (inode->i_nlink)
                                ext4_orphan_del(NULL, inode);
  
@@@ -4883,14 -4890,12 +4891,14 @@@ struct inode *ext4_iget(struct super_bl
        EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
  
        if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
 -              inode->i_version = le32_to_cpu(raw_inode->i_disk_version);
 +              u64 ivers = le32_to_cpu(raw_inode->i_disk_version);
 +
                if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
                        if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
 -                              inode->i_version |=
 +                              ivers |=
                    (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
                }
 +              inode_set_iversion_queried(inode, ivers);
        }
  
        ret = 0;
@@@ -5176,13 -5181,11 +5184,13 @@@ static int ext4_do_update_inode(handle_
        }
  
        if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) {
 -              raw_inode->i_disk_version = cpu_to_le32(inode->i_version);
 +              u64 ivers = inode_peek_iversion(inode);
 +
 +              raw_inode->i_disk_version = cpu_to_le32(ivers);
                if (ei->i_extra_isize) {
                        if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
                                raw_inode->i_version_hi =
 -                                      cpu_to_le32(inode->i_version >> 32);
 +                                      cpu_to_le32(ivers >> 32);
                        raw_inode->i_extra_isize =
                                cpu_to_le16(ei->i_extra_isize);
                }
diff --combined fs/ext4/namei.c
index 6660686e505a394818aa38cd4bb9fece1129fef4,c5696a93a3a606be9dd214ee8cd2d0544639730f..9aa1deb1a5256daf58dddf15b9c269b6c0969a9b
@@@ -34,7 -34,6 +34,7 @@@
  #include <linux/quotaops.h>
  #include <linux/buffer_head.h>
  #include <linux/bio.h>
 +#include <linux/iversion.h>
  #include "ext4.h"
  #include "ext4_jbd2.h"
  
@@@ -2960,7 -2959,7 +2960,7 @@@ static int ext4_rmdir(struct inode *dir
                             "empty directory '%.*s' has too many links (%u)",
                             dentry->d_name.len, dentry->d_name.name,
                             inode->i_nlink);
 -      inode->i_version++;
 +      inode_inc_iversion(inode);
        clear_nlink(inode);
        /* There's no need to set i_disksize: the fact that i_nlink is
         * zero will ensure that the right thing happens during any
@@@ -3222,9 -3221,9 +3222,9 @@@ static int ext4_link(struct dentry *old
        if (err)
                return err;
  
-        if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) &&
-          (!projid_eq(EXT4_I(dir)->i_projid,
-                      EXT4_I(old_dentry->d_inode)->i_projid)))
+       if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) &&
+           (!projid_eq(EXT4_I(dir)->i_projid,
+                       EXT4_I(old_dentry->d_inode)->i_projid)))
                return -EXDEV;
  
        err = dquot_initialize(dir);
@@@ -3366,7 -3365,7 +3366,7 @@@ static int ext4_setent(handle_t *handle
        ent->de->inode = cpu_to_le32(ino);
        if (ext4_has_feature_filetype(ent->dir->i_sb))
                ent->de->file_type = file_type;
 -      ent->dir->i_version++;
 +      inode_inc_iversion(ent->dir);
        ent->dir->i_ctime = ent->dir->i_mtime =
                current_time(ent->dir);
        ext4_mark_inode_dirty(handle, ent->dir);
diff --combined fs/ext4/super.c
index 5de959fb0244291b2b29874a242c049fd8e6bcf0,e82e35ae5cf990fdc13da2c5f8e88eab142f7193..82eead1c8b84a62e50f77b6547a515bff1c72084
@@@ -1,3 -1,4 +1,4 @@@
+ // SPDX-License-Identifier: GPL-2.0
  /*
   *  linux/fs/ext4/super.c
   *
@@@ -40,7 -41,6 +41,7 @@@
  #include <linux/dax.h>
  #include <linux/cleancache.h>
  #include <linux/uaccess.h>
 +#include <linux/iversion.h>
  
  #include <linux/kthread.h>
  #include <linux/freezer.h>
@@@ -743,6 -743,7 +744,7 @@@ __acquires(bitlock
        }
  
        ext4_unlock_group(sb, grp);
+       ext4_commit_super(sb, 1);
        ext4_handle_error(sb);
        /*
         * We only get here in the ERRORS_RO case; relocking the group
@@@ -871,7 -872,6 +873,6 @@@ static void ext4_put_super(struct super
        ext4_unregister_li_request(sb);
        ext4_quota_off_umount(sb);
  
-       flush_workqueue(sbi->rsv_conversion_wq);
        destroy_workqueue(sbi->rsv_conversion_wq);
  
        if (sbi->s_journal) {
@@@ -968,7 -968,7 +969,7 @@@ static struct inode *ext4_alloc_inode(s
        if (!ei)
                return NULL;
  
 -      ei->vfs_inode.i_version = 1;
 +      inode_set_iversion(&ei->vfs_inode, 1);
        spin_lock_init(&ei->i_raw_lock);
        INIT_LIST_HEAD(&ei->i_prealloc_list);
        spin_lock_init(&ei->i_prealloc_lock);
@@@ -2677,7 -2677,7 +2678,7 @@@ static ext4_fsblk_t descriptor_loc(stru
         * compensate.
         */
        if (sb->s_blocksize == 1024 && nr == 0 &&
-           le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block) == 0)
+           le32_to_cpu(sbi->s_es->s_first_data_block) == 0)
                has_super++;
  
        return (has_super + ext4_group_first_block_no(sb, bg));
@@@ -3122,7 -3122,7 +3123,7 @@@ int ext4_register_li_request(struct sup
  {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        struct ext4_li_request *elr = NULL;
-       ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
+       ext4_group_t ngroups = sbi->s_groups_count;
        int ret = 0;
  
        mutex_lock(&ext4_li_mtx);
@@@ -4837,7 -4837,7 +4838,7 @@@ static int ext4_sync_fs(struct super_bl
        bool needs_barrier = false;
        struct ext4_sb_info *sbi = EXT4_SB(sb);
  
-       if (unlikely(ext4_forced_shutdown(EXT4_SB(sb))))
+       if (unlikely(ext4_forced_shutdown(sbi)))
                return 0;
  
        trace_ext4_sync_fs(sb, wait);