]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 15 Jul 2017 19:00:42 +0000 (12:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 15 Jul 2017 19:00:42 +0000 (12:00 -0700)
Pull ->s_options removal from Al Viro:
 "Preparations for fsmount/fsopen stuff (coming next cycle). Everything
  gets moved to explicit ->show_options(), killing ->s_options off +
  some cosmetic bits around fs/namespace.c and friends. Basically, the
  stuff needed to work with fsmount series with minimum of conflicts
  with other work.

  It's not strictly required for this merge window, but it would reduce
  the PITA during the coming cycle, so it would be nice to have those
  bits and pieces out of the way"

* 'work.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  isofs: Fix isofs_show_options()
  VFS: Kill off s_options and helpers
  orangefs: Implement show_options
  9p: Implement show_options
  isofs: Implement show_options
  afs: Implement show_options
  affs: Implement show_options
  befs: Implement show_options
  spufs: Implement show_options
  bpf: Implement show_options
  ramfs: Implement show_options
  pstore: Implement show_options
  omfs: Implement show_options
  hugetlbfs: Implement show_options
  VFS: Don't use save/replace_mount_options if not using generic_show_options
  VFS: Provide empty name qstr
  VFS: Make get_filesystem() return the affected filesystem
  VFS: Clean up whitespace in fs/namespace.c and fs/super.c
  Provide a function to create a NUL-terminated string from unterminated data

19 files changed:
1  2 
Documentation/filesystems/vfs.txt
fs/afs/super.c
fs/btrfs/super.c
fs/dcache.c
fs/debugfs/inode.c
fs/filesystems.c
fs/gfs2/dir.c
fs/hugetlbfs/inode.c
fs/namei.c
fs/namespace.c
fs/pstore/inode.c
fs/pstore/internal.h
fs/pstore/platform.c
include/linux/dcache.h
include/linux/fs.h
include/linux/hugetlb.h
include/linux/string.h
mm/util.c
net/9p/trans_fd.c

index 48c9faa73a761ef1c7880fc6c7e1f6927d597f74,ee56a7d10da9043bc6ec4da22b68bb6f1810a44e..73e7d91f03dce56266ad1806e056c2a4f7e5321e
@@@ -576,43 -576,7 +576,43 @@@ should clear PG_Dirty and set PG_Writeb
  written at any point after PG_Dirty is clear.  Once it is known to be
  safe, PG_Writeback is cleared.
  
 -Writeback makes use of a writeback_control structure...
 +Writeback makes use of a writeback_control structure to direct the
 +operations.  This gives the the writepage and writepages operations some
 +information about the nature of and reason for the writeback request,
 +and the constraints under which it is being done.  It is also used to
 +return information back to the caller about the result of a writepage or
 +writepages request.
 +
 +Handling errors during writeback
 +--------------------------------
 +Most applications that do buffered I/O will periodically call a file
 +synchronization call (fsync, fdatasync, msync or sync_file_range) to
 +ensure that data written has made it to the backing store.  When there
 +is an error during writeback, they expect that error to be reported when
 +a file sync request is made.  After an error has been reported on one
 +request, subsequent requests on the same file descriptor should return
 +0, unless further writeback errors have occurred since the previous file
 +syncronization.
 +
 +Ideally, the kernel would report errors only on file descriptions on
 +which writes were done that subsequently failed to be written back.  The
 +generic pagecache infrastructure does not track the file descriptions
 +that have dirtied each individual page however, so determining which
 +file descriptors should get back an error is not possible.
 +
 +Instead, the generic writeback error tracking infrastructure in the
 +kernel settles for reporting errors to fsync on all file descriptions
 +that were open at the time that the error occurred.  In a situation with
 +multiple writers, all of them will get back an error on a subsequent fsync,
 +even if all of the writes done through that particular file descriptor
 +succeeded (or even if there were no writes on that file descriptor at all).
 +
 +Filesystems that wish to use this infrastructure should call
 +mapping_set_error to record the error in the address_space when it
 +occurs.  Then, after writing back data from the pagecache in their
 +file->fsync operation, they should call file_check_and_advance_wb_err to
 +ensure that the struct file's error cursor has advanced to the correct
 +point in the stream of errors emitted by the backing device(s).
  
  struct address_space_operations
  -------------------------------
@@@ -840,8 -804,7 +840,8 @@@ struct address_space_operations 
  The File Object
  ===============
  
 -A file object represents a file opened by a process.
 +A file object represents a file opened by a process. This is also known
 +as an "open file description" in POSIX parlance.
  
  
  struct file_operations
@@@ -924,8 -887,7 +924,8 @@@ otherwise noted
  
    release: called when the last reference to an open file is closed
  
 -  fsync: called by the fsync(2) system call
 +  fsync: called by the fsync(2) system call. Also see the section above
 +       entitled "Handling errors during writeback".
  
    fasync: called by the fcntl(2) system call when asynchronous
        (non-blocking) mode is enabled for a file
@@@ -1225,12 -1187,6 +1225,6 @@@ The underlying reason for the above rul
  mount can be accurately replicated (e.g. umounting and mounting again)
  based on the information found in /proc/mounts.
  
- A simple method of saving options at mount/remount time and showing
- them is provided with the save_mount_options() and
- generic_show_options() helper functions.  Please note, that using
- these may have drawbacks.  For more info see header comments for these
- functions in fs/namespace.c.
  Resources
  =========
  
diff --combined fs/afs/super.c
index 67680c2d96cf0ebdbad87a1c8b87e50339b8a171,35d7e550b29cb055b8b442f3a9648217e003ef62..689173c0a682fd2861a6836bc097e49e15696abc
@@@ -37,6 -37,8 +37,8 @@@ static void afs_kill_super(struct super
  static struct inode *afs_alloc_inode(struct super_block *sb);
  static void afs_destroy_inode(struct inode *inode);
  static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
+ static int afs_show_devname(struct seq_file *m, struct dentry *root);
+ static int afs_show_options(struct seq_file *m, struct dentry *root);
  
  struct file_system_type afs_fs_type = {
        .owner          = THIS_MODULE,
@@@ -53,7 -55,8 +55,8 @@@ static const struct super_operations af
        .drop_inode     = afs_drop_inode,
        .destroy_inode  = afs_destroy_inode,
        .evict_inode    = afs_evict_inode,
-       .show_options   = generic_show_options,
+       .show_devname   = afs_show_devname,
+       .show_options   = afs_show_options,
  };
  
  static struct kmem_cache *afs_inode_cachep;
@@@ -135,6 -138,45 +138,45 @@@ void __exit afs_fs_exit(void
        _leave("");
  }
  
+ /*
+  * Display the mount device name in /proc/mounts.
+  */
+ static int afs_show_devname(struct seq_file *m, struct dentry *root)
+ {
+       struct afs_super_info *as = root->d_sb->s_fs_info;
+       struct afs_volume *volume = as->volume;
+       struct afs_cell *cell = volume->cell;
+       const char *suf = "";
+       char pref = '%';
+       switch (volume->type) {
+       case AFSVL_RWVOL:
+               break;
+       case AFSVL_ROVOL:
+               pref = '#';
+               if (volume->type_force)
+                       suf = ".readonly";
+               break;
+       case AFSVL_BACKVOL:
+               pref = '#';
+               suf = ".backup";
+               break;
+       }
+       seq_printf(m, "%c%s:%s%s", pref, cell->name, volume->vlocation->vldb.name, suf);
+       return 0;
+ }
+ /*
+  * Display the mount options in /proc/mounts.
+  */
+ static int afs_show_options(struct seq_file *m, struct dentry *root)
+ {
+       if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags))
+               seq_puts(m, "autocell");
+       return 0;
+ }
  /*
   * parse the mount options
   * - this function has been shamelessly adapted from the ext3 fs which
@@@ -319,7 -361,6 +361,7 @@@ static int afs_fill_super(struct super_
        sb->s_blocksize_bits    = PAGE_SHIFT;
        sb->s_magic             = AFS_FS_MAGIC;
        sb->s_op                = &afs_super_ops;
 +      sb->s_xattr             = afs_xattr_handlers;
        ret = super_setup_bdi(sb);
        if (ret)
                return ret;
@@@ -427,7 -468,6 +469,6 @@@ static struct dentry *afs_mount(struct 
                        deactivate_locked_super(sb);
                        goto error;
                }
-               save_mount_options(sb, new_opts);
                sb->s_flags |= MS_ACTIVE;
        } else {
                _debug("reuse");
diff --combined fs/btrfs/super.c
index 74e47794e63ffdda6921f8445bd4f576f22f1434,8e9758b3eb232f1f07e4f60b3d4ed4ed9003729c..12540b6104b5d9269baf4b35de420eca930b15af
@@@ -601,8 -601,18 +601,8 @@@ int btrfs_parse_options(struct btrfs_fs
                        }
                        break;
                case Opt_alloc_start:
 -                      num = match_strdup(&args[0]);
 -                      if (num) {
 -                              mutex_lock(&info->chunk_mutex);
 -                              info->alloc_start = memparse(num, NULL);
 -                              mutex_unlock(&info->chunk_mutex);
 -                              kfree(num);
 -                              btrfs_info(info, "allocations start at %llu",
 -                                         info->alloc_start);
 -                      } else {
 -                              ret = -ENOMEM;
 -                              goto out;
 -                      }
 +                      btrfs_info(info,
 +                              "option alloc_start is obsolete, ignored");
                        break;
                case Opt_acl:
  #ifdef CONFIG_BTRFS_FS_POSIX_ACL
@@@ -1154,7 -1164,6 +1154,6 @@@ static int btrfs_fill_super(struct supe
                goto fail_close;
        }
  
-       save_mount_options(sb, data);
        cleancache_init_fs(sb);
        sb->s_flags |= MS_ACTIVE;
        return 0;
@@@ -1177,7 -1186,7 +1176,7 @@@ int btrfs_sync_fs(struct super_block *s
                return 0;
        }
  
 -      btrfs_wait_ordered_roots(fs_info, -1, 0, (u64)-1);
 +      btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1);
  
        trans = btrfs_attach_transaction_barrier(root);
        if (IS_ERR(trans)) {
@@@ -1222,6 -1231,8 +1221,6 @@@ static int btrfs_show_options(struct se
                seq_puts(seq, ",nobarrier");
        if (info->max_inline != BTRFS_DEFAULT_MAX_INLINE)
                seq_printf(seq, ",max_inline=%llu", info->max_inline);
 -      if (info->alloc_start != 0)
 -              seq_printf(seq, ",alloc_start=%llu", info->alloc_start);
        if (info->thread_pool_size !=  min_t(unsigned long,
                                             num_online_cpus() + 2, 8))
                seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
@@@ -1704,6 -1715,7 +1703,6 @@@ static int btrfs_remount(struct super_b
        unsigned long old_opts = fs_info->mount_opt;
        unsigned long old_compress_type = fs_info->compress_type;
        u64 old_max_inline = fs_info->max_inline;
 -      u64 old_alloc_start = fs_info->alloc_start;
        int old_thread_pool_size = fs_info->thread_pool_size;
        unsigned int old_metadata_ratio = fs_info->metadata_ratio;
        int ret;
@@@ -1842,6 -1854,9 +1841,6 @@@ restore
        fs_info->mount_opt = old_opts;
        fs_info->compress_type = old_compress_type;
        fs_info->max_inline = old_max_inline;
 -      mutex_lock(&fs_info->chunk_mutex);
 -      fs_info->alloc_start = old_alloc_start;
 -      mutex_unlock(&fs_info->chunk_mutex);
        btrfs_resize_thread_pool(fs_info,
                old_thread_pool_size, fs_info->thread_pool_size);
        fs_info->metadata_ratio = old_metadata_ratio;
@@@ -1882,15 -1897,18 +1881,15 @@@ static inline void btrfs_descending_sor
  static int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info,
                                       u64 *free_bytes)
  {
 -      struct btrfs_root *root = fs_info->tree_root;
        struct btrfs_device_info *devices_info;
        struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
        struct btrfs_device *device;
        u64 skip_space;
        u64 type;
        u64 avail_space;
 -      u64 used_space;
        u64 min_stripe_size;
        int min_stripes = 1, num_stripes = 1;
        int i = 0, nr_devices;
 -      int ret;
  
        /*
         * We aren't under the device list lock, so this is racy-ish, but good
        }
  
        devices_info = kmalloc_array(nr_devices, sizeof(*devices_info),
 -                             GFP_NOFS);
 +                             GFP_KERNEL);
        if (!devices_info)
                return -ENOMEM;
  
        /* calc min stripe number for data space allocation */
 -      type = btrfs_get_alloc_profile(root, 1);
 +      type = btrfs_data_alloc_profile(fs_info);
        if (type & BTRFS_BLOCK_GROUP_RAID0) {
                min_stripes = 2;
                num_stripes = nr_devices;
        else
                min_stripe_size = BTRFS_STRIPE_LEN;
  
 -      if (fs_info->alloc_start)
 -              mutex_lock(&fs_devices->device_list_mutex);
        rcu_read_lock();
        list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) {
                if (!device->in_fs_metadata || !device->bdev ||
                 */
                skip_space = SZ_1M;
  
 -              /* user can set the offset in fs_info->alloc_start. */
 -              if (fs_info->alloc_start &&
 -                  fs_info->alloc_start + BTRFS_STRIPE_LEN <=
 -                  device->total_bytes) {
 -                      rcu_read_unlock();
 -                      skip_space = max(fs_info->alloc_start, skip_space);
 -
 -                      /*
 -                       * btrfs can not use the free space in
 -                       * [0, skip_space - 1], we must subtract it from the
 -                       * total. In order to implement it, we account the used
 -                       * space in this range first.
 -                       */
 -                      ret = btrfs_account_dev_extents_size(device, 0,
 -                                                           skip_space - 1,
 -                                                           &used_space);
 -                      if (ret) {
 -                              kfree(devices_info);
 -                              mutex_unlock(&fs_devices->device_list_mutex);
 -                              return ret;
 -                      }
 -
 -                      rcu_read_lock();
 -
 -                      /* calc the free space in [0, skip_space - 1] */
 -                      skip_space -= used_space;
 -              }
 -
                /*
                 * we can use the free space in [0, skip_space - 1], subtract
                 * it from the total.
                i++;
        }
        rcu_read_unlock();
 -      if (fs_info->alloc_start)
 -              mutex_unlock(&fs_devices->device_list_mutex);
  
        nr_devices = i;
  
   * multiplier to scale the sizes.
   *
   * Unused device space usage is based on simulating the chunk allocator
 - * algorithm that respects the device sizes, order of allocations and the
 - * 'alloc_start' value, this is a close approximation of the actual use but
 - * there are other factors that may change the result (like a new metadata
 - * chunk).
 + * algorithm that respects the device sizes and order of allocations.  This is
 + * a close approximation of the actual use but there are other factors that may
 + * change the result (like a new metadata chunk).
   *
   * If metadata is exhausted, f_bavail will be 0.
   */
@@@ -2191,7 -2242,7 +2190,7 @@@ static int btrfs_freeze(struct super_bl
        struct btrfs_fs_info *fs_info = btrfs_sb(sb);
        struct btrfs_root *root = fs_info->tree_root;
  
 -      fs_info->fs_frozen = 1;
 +      set_bit(BTRFS_FS_FROZEN, &fs_info->flags);
        /*
         * We don't need a barrier here, we'll wait for any transaction that
         * could be in progress on other threads (and do delayed iputs that
  
  static int btrfs_unfreeze(struct super_block *sb)
  {
 -      btrfs_sb(sb)->fs_frozen = 0;
 +      struct btrfs_fs_info *fs_info = btrfs_sb(sb);
 +
 +      clear_bit(BTRFS_FS_FROZEN, &fs_info->flags);
        return 0;
  }
  
diff --combined fs/dcache.c
index 6c30be668487ca53725efc2229ac64dce68b9abc,95efb7b2bf841fe3d3f6aff9bf9759a937a1ddd5..f90141387f01ea4ed61bae215e137042527182c5
@@@ -90,6 -90,11 +90,11 @@@ EXPORT_SYMBOL(rename_lock)
  
  static struct kmem_cache *dentry_cache __read_mostly;
  
+ const struct qstr empty_name = QSTR_INIT("", 0);
+ EXPORT_SYMBOL(empty_name);
+ const struct qstr slash_name = QSTR_INIT("/", 1);
+ EXPORT_SYMBOL(slash_name);
  /*
   * This is the single most critical data structure when it comes
   * to the dcache: the hashtable for lookups. Somebody should try
@@@ -277,33 -282,6 +282,33 @@@ static inline int dname_external(const 
        return dentry->d_name.name != dentry->d_iname;
  }
  
 +void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
 +{
 +      spin_lock(&dentry->d_lock);
 +      if (unlikely(dname_external(dentry))) {
 +              struct external_name *p = external_name(dentry);
 +              atomic_inc(&p->u.count);
 +              spin_unlock(&dentry->d_lock);
 +              name->name = p->name;
 +      } else {
 +              memcpy(name->inline_name, dentry->d_iname, DNAME_INLINE_LEN);
 +              spin_unlock(&dentry->d_lock);
 +              name->name = name->inline_name;
 +      }
 +}
 +EXPORT_SYMBOL(take_dentry_name_snapshot);
 +
 +void release_dentry_name_snapshot(struct name_snapshot *name)
 +{
 +      if (unlikely(name->name != name->inline_name)) {
 +              struct external_name *p;
 +              p = container_of(name->name, struct external_name, name[0]);
 +              if (unlikely(atomic_dec_and_test(&p->u.count)))
 +                      kfree_rcu(p, u.head);
 +      }
 +}
 +EXPORT_SYMBOL(release_dentry_name_snapshot);
 +
  static inline void __d_set_inode_and_type(struct dentry *dentry,
                                          struct inode *inode,
                                          unsigned type_flags)
@@@ -1160,12 -1138,11 +1165,12 @@@ void shrink_dcache_sb(struct super_bloc
                LIST_HEAD(dispose);
  
                freed = list_lru_walk(&sb->s_dentry_lru,
 -                      dentry_lru_isolate_shrink, &dispose, UINT_MAX);
 +                      dentry_lru_isolate_shrink, &dispose, 1024);
  
                this_cpu_sub(nr_dentry_unused, freed);
                shrink_dentry_list(&dispose);
 -      } while (freed > 0);
 +              cond_resched();
 +      } while (list_lru_count(&sb->s_dentry_lru) > 0);
  }
  EXPORT_SYMBOL(shrink_dcache_sb);
  
@@@ -1606,8 -1583,7 +1611,7 @@@ struct dentry *__d_alloc(struct super_b
         */
        dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
        if (unlikely(!name)) {
-               static const struct qstr anon = QSTR_INIT("/", 1);
-               name = &anon;
+               name = &slash_name;
                dname = dentry->d_iname;
        } else if (name->len > DNAME_INLINE_LEN-1) {
                size_t size = offsetof(struct external_name, name[1]);
@@@ -3574,6 -3550,8 +3578,6 @@@ __setup("dhash_entries=", set_dhash_ent
  
  static void __init dcache_init_early(void)
  {
 -      unsigned int loop;
 -
        /* If hashes are distributed across NUMA nodes, defer
         * hash allocation until vmalloc space is available.
         */
                                        sizeof(struct hlist_bl_head),
                                        dhash_entries,
                                        13,
 -                                      HASH_EARLY,
 +                                      HASH_EARLY | HASH_ZERO,
                                        &d_hash_shift,
                                        &d_hash_mask,
                                        0,
                                        0);
 -
 -      for (loop = 0; loop < (1U << d_hash_shift); loop++)
 -              INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
  }
  
  static void __init dcache_init(void)
  {
 -      unsigned int loop;
 -
 -      /* 
 +      /*
         * A constructor could be added for stable state like the lists,
         * but it is probably not worth it because of the cache nature
 -       * of the dcache. 
 +       * of the dcache.
         */
        dentry_cache = KMEM_CACHE(dentry,
                SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD|SLAB_ACCOUNT);
                                        sizeof(struct hlist_bl_head),
                                        dhash_entries,
                                        13,
 -                                      0,
 +                                      HASH_ZERO,
                                        &d_hash_shift,
                                        &d_hash_mask,
                                        0,
                                        0);
 -
 -      for (loop = 0; loop < (1U << d_hash_shift); loop++)
 -              INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
  }
  
  /* SLAB cache for __getname() consumers */
@@@ -3626,11 -3612,6 +3630,11 @@@ EXPORT_SYMBOL(d_genocide)
  
  void __init vfs_caches_init_early(void)
  {
 +      int i;
 +
 +      for (i = 0; i < ARRAY_SIZE(in_lookup_hashtable); i++)
 +              INIT_HLIST_BL_HEAD(&in_lookup_hashtable[i]);
 +
        dcache_init_early();
        inode_init_early();
  }
diff --combined fs/debugfs/inode.c
index a0e4e2f7e0befb47c22f9d275e90c039457e1b86,0dc9e9c0e0f813ef7b85baf0bff4d8918f7267c4..c59f015f386eba1e58b4cba397e1b4910e62ace9
@@@ -9,7 -9,7 +9,7 @@@
   *    2 as published by the Free Software Foundation.
   *
   *  debugfs is for people to use instead of /proc or /sys.
 - *  See Documentation/DocBook/kernel-api for more details.
 + *  See ./Documentation/core-api/kernel-api.rst for more details.
   *
   */
  
@@@ -203,8 -203,6 +203,6 @@@ static int debug_fill_super(struct supe
        struct debugfs_fs_info *fsi;
        int err;
  
-       save_mount_options(sb, data);
        fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
        sb->s_fs_info = fsi;
        if (!fsi) {
@@@ -766,7 -764,7 +764,7 @@@ struct dentry *debugfs_rename(struct de
  {
        int error;
        struct dentry *dentry = NULL, *trap;
 -      const char *old_name;
 +      struct name_snapshot old_name;
  
        trap = lock_rename(new_dir, old_dir);
        /* Source or destination directories don't exist? */
        if (IS_ERR(dentry) || dentry == trap || d_really_is_positive(dentry))
                goto exit;
  
 -      old_name = fsnotify_oldname_init(old_dentry->d_name.name);
 +      take_dentry_name_snapshot(&old_name, old_dentry);
  
        error = simple_rename(d_inode(old_dir), old_dentry, d_inode(new_dir),
                              dentry, 0);
        if (error) {
 -              fsnotify_oldname_free(old_name);
 +              release_dentry_name_snapshot(&old_name);
                goto exit;
        }
        d_move(old_dentry, dentry);
 -      fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name,
 +      fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name,
                d_is_dir(old_dentry),
                NULL, old_dentry);
 -      fsnotify_oldname_free(old_name);
 +      release_dentry_name_snapshot(&old_name);
        unlock_rename(new_dir, old_dir);
        dput(dentry);
        return old_dentry;
diff --combined fs/filesystems.c
index 8b99955e3504e2e8725ff4f4394b84898e88d155,591e52d23ed4d22f4e11b840d5ac8975faaeb575..a920ad2629ac73481cc9c5e2cd38d3ba4b8915dd
@@@ -33,9 -33,10 +33,10 @@@ static struct file_system_type *file_sy
  static DEFINE_RWLOCK(file_systems_lock);
  
  /* WARNING: This can be used only if we _already_ own a reference */
void get_filesystem(struct file_system_type *fs)
struct file_system_type *get_filesystem(struct file_system_type *fs)
  {
        __module_get(fs->owner);
+       return fs;
  }
  
  void put_filesystem(struct file_system_type *fs)
@@@ -275,10 -276,8 +276,10 @@@ struct file_system_type *get_fs_type(co
        int len = dot ? dot - name : strlen(name);
  
        fs = __get_fs_type(name, len);
 -      if (!fs && (request_module("fs-%.*s", len, name) == 0))
 +      if (!fs && (request_module("fs-%.*s", len, name) == 0)) {
                fs = __get_fs_type(name, len);
 +              WARN_ONCE(!fs, "request_module fs-%.*s succeeded, but still no fs?\n", len, name);
 +      }
  
        if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
                put_filesystem(fs);
diff --combined fs/gfs2/dir.c
index db427658ccd9bc1e2a82030cf6cee6e097dd3fc3,a5dfff6a033ebdf86ef19f9b00e12853a2c0a202..5ee2e2f8576cd8811509e33769515e3a5a403281
@@@ -872,7 -872,6 +872,6 @@@ static struct gfs2_leaf *new_leaf(struc
        struct buffer_head *bh;
        struct gfs2_leaf *leaf;
        struct gfs2_dirent *dent;
-       struct qstr name = { .name = "" };
        struct timespec tv = current_time(inode);
  
        error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL);
        leaf->lf_sec = cpu_to_be64(tv.tv_sec);
        memset(leaf->lf_reserved2, 0, sizeof(leaf->lf_reserved2));
        dent = (struct gfs2_dirent *)(leaf+1);
-       gfs2_qstr2dirent(&name, bh->b_size - sizeof(struct gfs2_leaf), dent);
+       gfs2_qstr2dirent(&empty_name, bh->b_size - sizeof(struct gfs2_leaf), dent);
        *pbh = bh;
        return leaf;
  }
@@@ -1444,7 -1443,7 +1443,7 @@@ static int gfs2_dir_read_leaf(struct in
                                                "g.offset (%u)\n",
                                        (unsigned long long)bh->b_blocknr,
                                        entries2, g.offset);
 -                                      
 +                              gfs2_consist_inode(ip);
                                error = -EIO;
                                goto out_free;
                        }
@@@ -1612,7 -1611,6 +1611,7 @@@ int gfs2_dir_read(struct inode *inode, 
                                (unsigned long long)dip->i_no_addr,
                                dip->i_entries,
                                g.offset);
 +                      gfs2_consist_inode(dip);
                        error = -EIO;
                        goto out;
                }
@@@ -2032,8 -2030,8 +2031,8 @@@ static int leaf_dealloc(struct gfs2_ino
        gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
  
        for (x = 0; x < rlist.rl_rgrps; x++) {
 -              struct gfs2_rgrpd *rgd;
 -              rgd = rlist.rl_ghs[x].gh_gl->gl_object;
 +              struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl);
 +
                rg_blocks += rgd->rd_length;
        }
  
diff --combined fs/hugetlbfs/inode.c
index 52388611635e29df0bd6286f3d97b0f1a137498e,99b3b9836575cc807097c17bfaf9046e6a6280c7..28d2753be09498769282facb66593c95b91f498a
@@@ -46,13 -46,13 +46,13 @@@ static const struct inode_operations hu
  static const struct inode_operations hugetlbfs_inode_operations;
  
  struct hugetlbfs_config {
-       kuid_t   uid;
-       kgid_t   gid;
-       umode_t mode;
-       long    max_hpages;
-       long    nr_inodes;
-       struct hstate *hstate;
-       long    min_hpages;
+       struct hstate           *hstate;
+       long                    max_hpages;
+       long                    nr_inodes;
+       long                    min_hpages;
+       kuid_t                  uid;
+       kgid_t                  gid;
+       umode_t                 mode;
  };
  
  struct hugetlbfs_inode_info {
@@@ -851,16 -851,46 +851,56 @@@ static int hugetlbfs_migrate_page(struc
        return MIGRATEPAGE_SUCCESS;
  }
  
 +static int hugetlbfs_error_remove_page(struct address_space *mapping,
 +                              struct page *page)
 +{
 +      struct inode *inode = mapping->host;
 +
 +      remove_huge_page(page);
 +      hugetlb_fix_reserve_counts(inode);
 +      return 0;
 +}
 +
+ /*
+  * Display the mount options in /proc/mounts.
+  */
+ static int hugetlbfs_show_options(struct seq_file *m, struct dentry *root)
+ {
+       struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(root->d_sb);
+       struct hugepage_subpool *spool = sbinfo->spool;
+       unsigned long hpage_size = huge_page_size(sbinfo->hstate);
+       unsigned hpage_shift = huge_page_shift(sbinfo->hstate);
+       char mod;
+       if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
+               seq_printf(m, ",uid=%u",
+                          from_kuid_munged(&init_user_ns, sbinfo->uid));
+       if (!gid_eq(sbinfo->gid, GLOBAL_ROOT_GID))
+               seq_printf(m, ",gid=%u",
+                          from_kgid_munged(&init_user_ns, sbinfo->gid));
+       if (sbinfo->mode != 0755)
+               seq_printf(m, ",mode=%o", sbinfo->mode);
+       if (sbinfo->max_inodes != -1)
+               seq_printf(m, ",nr_inodes=%lu", sbinfo->max_inodes);
+       hpage_size /= 1024;
+       mod = 'K';
+       if (hpage_size >= 1024) {
+               hpage_size /= 1024;
+               mod = 'M';
+       }
+       seq_printf(m, ",pagesize=%lu%c", hpage_size, mod);
+       if (spool) {
+               if (spool->max_hpages != -1)
+                       seq_printf(m, ",size=%llu",
+                                  (unsigned long long)spool->max_hpages << hpage_shift);
+               if (spool->min_hpages != -1)
+                       seq_printf(m, ",min_size=%llu",
+                                  (unsigned long long)spool->min_hpages << hpage_shift);
+       }
+       return 0;
+ }
  static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
  {
        struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
@@@ -976,7 -1006,6 +1016,7 @@@ static const struct address_space_opera
        .write_end      = hugetlbfs_write_end,
        .set_page_dirty = hugetlbfs_set_page_dirty,
        .migratepage    = hugetlbfs_migrate_page,
 +      .error_remove_page      = hugetlbfs_error_remove_page,
  };
  
  
@@@ -1019,19 -1048,19 +1059,19 @@@ static const struct super_operations hu
        .evict_inode    = hugetlbfs_evict_inode,
        .statfs         = hugetlbfs_statfs,
        .put_super      = hugetlbfs_put_super,
-       .show_options   = generic_show_options,
+       .show_options   = hugetlbfs_show_options,
  };
  
- enum { NO_SIZE, SIZE_STD, SIZE_PERCENT };
+ enum hugetlbfs_size_type { NO_SIZE, SIZE_STD, SIZE_PERCENT };
  
  /*
   * Convert size option passed from command line to number of huge pages
   * in the pool specified by hstate.  Size option could be in bytes
   * (val_type == SIZE_STD) or percentage of the pool (val_type == SIZE_PERCENT).
   */
- static long long
+ static long
  hugetlbfs_size_to_hpages(struct hstate *h, unsigned long long size_opt,
-                                                               int val_type)
+                        enum hugetlbfs_size_type val_type)
  {
        if (val_type == NO_SIZE)
                return -1;
@@@ -1053,7 -1082,7 +1093,7 @@@ hugetlbfs_parse_options(char *options, 
        substring_t args[MAX_OPT_ARGS];
        int option;
        unsigned long long max_size_opt = 0, min_size_opt = 0;
-       int max_val_type = NO_SIZE, min_val_type = NO_SIZE;
+       enum hugetlbfs_size_type max_val_type = NO_SIZE, min_val_type = NO_SIZE;
  
        if (!options)
                return 0;
@@@ -1167,8 -1196,6 +1207,6 @@@ hugetlbfs_fill_super(struct super_bloc
        struct hugetlbfs_config config;
        struct hugetlbfs_sb_info *sbinfo;
  
-       save_mount_options(sb, data);
        config.max_hpages = -1; /* No limit on size by default */
        config.nr_inodes = -1; /* No limit on number of inodes by default */
        config.uid = current_fsuid();
        sbinfo->max_inodes = config.nr_inodes;
        sbinfo->free_inodes = config.nr_inodes;
        sbinfo->spool = NULL;
+       sbinfo->uid = config.uid;
+       sbinfo->gid = config.gid;
+       sbinfo->mode = config.mode;
        /*
         * Allocate and initialize subpool if maximum or minimum size is
         * specified.  Any needed reservations (for minimim size) are taken
diff --combined fs/namei.c
index e0b46eb0e2129ca337bba8e4634d96edf0683117,0d35760fee00a5be32856d36f3d519ee5bf33b55..88fd38d1e3e7ae8b9a6e0df2ea4baedb0c423cfa
@@@ -1008,7 -1008,7 +1008,7 @@@ static int may_linkat(struct path *link
        /* Source inode owner (or CAP_FOWNER) can hardlink all they like,
         * otherwise, it must be a safe source.
         */
 -      if (inode_owner_or_capable(inode) || safe_hardlink_source(inode))
 +      if (safe_hardlink_source(inode) || inode_owner_or_capable(inode))
                return 0;
  
        audit_log_link_denied("linkat", link);
@@@ -3400,7 -3400,6 +3400,6 @@@ out
  
  struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag)
  {
-       static const struct qstr name = QSTR_INIT("/", 1);
        struct dentry *child = NULL;
        struct inode *dir = dentry->d_inode;
        struct inode *inode;
        if (!dir->i_op->tmpfile)
                goto out_err;
        error = -ENOMEM;
-       child = d_alloc(dentry, &name);
+       child = d_alloc(dentry, &slash_name);
        if (unlikely(!child))
                goto out_err;
        error = dir->i_op->tmpfile(dir, child, mode);
@@@ -4332,7 -4331,6 +4331,7 @@@ SYSCALL_DEFINE2(link, const char __use
   * The worst of all namespace operations - renaming directory. "Perverted"
   * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
   * Problems:
 + *
   *    a) we can get into loop creation.
   *    b) race potential - two innocent renames can create a loop together.
   *       That's where 4.4 screws up. Current fix: serialization on
@@@ -4363,11 -4361,11 +4362,11 @@@ int vfs_rename(struct inode *old_dir, s
  {
        int error;
        bool is_dir = d_is_dir(old_dentry);
 -      const unsigned char *old_name;
        struct inode *source = old_dentry->d_inode;
        struct inode *target = new_dentry->d_inode;
        bool new_is_dir = false;
        unsigned max_links = new_dir->i_sb->s_max_links;
 +      struct name_snapshot old_name;
  
        if (source == target)
                return 0;
        if (error)
                return error;
  
 -      old_name = fsnotify_oldname_init(old_dentry->d_name.name);
 +      take_dentry_name_snapshot(&old_name, old_dentry);
        dget(new_dentry);
        if (!is_dir || (flags & RENAME_EXCHANGE))
                lock_two_nondirectories(source, target);
                inode_unlock(target);
        dput(new_dentry);
        if (!error) {
 -              fsnotify_move(old_dir, new_dir, old_name, is_dir,
 +              fsnotify_move(old_dir, new_dir, old_name.name, is_dir,
                              !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry);
                if (flags & RENAME_EXCHANGE) {
                        fsnotify_move(new_dir, old_dir, old_dentry->d_name.name,
                                      new_is_dir, NULL, new_dentry);
                }
        }
 -      fsnotify_oldname_free(old_name);
 +      release_dentry_name_snapshot(&old_name);
  
        return error;
  }
diff --combined fs/namespace.c
index 81f934b5d5718665cbfe6c3c44d3bdb716bc6711,0e1fdb30613368c2aef348350ff744d0ef50c673..f8893dc6a989dc6c9b0f4e8daba2e985a64976e6
@@@ -236,7 -236,6 +236,7 @@@ static struct mount *alloc_vfsmnt(cons
                INIT_LIST_HEAD(&mnt->mnt_slave_list);
                INIT_LIST_HEAD(&mnt->mnt_slave);
                INIT_HLIST_NODE(&mnt->mnt_mp_list);
 +              INIT_LIST_HEAD(&mnt->mnt_umounting);
                init_fs_pin(&mnt->mnt_umount, drop_mountpoint);
        }
        return mnt;
@@@ -1238,65 -1237,6 +1238,6 @@@ struct vfsmount *mnt_clone_internal(con
        return &p->mnt;
  }
  
- static inline void mangle(struct seq_file *m, const char *s)
- {
-       seq_escape(m, s, " \t\n\\");
- }
- /*
-  * Simple .show_options callback for filesystems which don't want to
-  * implement more complex mount option showing.
-  *
-  * See also save_mount_options().
-  */
- int generic_show_options(struct seq_file *m, struct dentry *root)
- {
-       const char *options;
-       rcu_read_lock();
-       options = rcu_dereference(root->d_sb->s_options);
-       if (options != NULL && options[0]) {
-               seq_putc(m, ',');
-               mangle(m, options);
-       }
-       rcu_read_unlock();
-       return 0;
- }
- EXPORT_SYMBOL(generic_show_options);
- /*
-  * If filesystem uses generic_show_options(), this function should be
-  * called from the fill_super() callback.
-  *
-  * The .remount_fs callback usually needs to be handled in a special
-  * way, to make sure, that previous options are not overwritten if the
-  * remount fails.
-  *
-  * Also note, that if the filesystem's .remount_fs function doesn't
-  * reset all options to their default value, but changes only newly
-  * given options, then the displayed options will not reflect reality
-  * any more.
-  */
- void save_mount_options(struct super_block *sb, char *options)
- {
-       BUG_ON(sb->s_options);
-       rcu_assign_pointer(sb->s_options, kstrdup(options, GFP_KERNEL));
- }
- EXPORT_SYMBOL(save_mount_options);
- void replace_mount_options(struct super_block *sb, char *options)
- {
-       char *old = sb->s_options;
-       rcu_assign_pointer(sb->s_options, options);
-       if (old) {
-               synchronize_rcu();
-               kfree(old);
-       }
- }
- EXPORT_SYMBOL(replace_mount_options);
  #ifdef CONFIG_PROC_FS
  /* iterator; we want it to have access to namespace_sem, thus here... */
  static void *m_start(struct seq_file *m, loff_t *pos)
@@@ -1657,7 -1597,7 +1598,7 @@@ out_unlock
        namespace_unlock();
  }
  
- /* 
+ /*
   * Is the caller allowed to modify his namespace?
   */
  static inline bool may_mount(void)
@@@ -2211,7 -2151,7 +2152,7 @@@ static int do_loopback(struct path *pat
  
        err = -EINVAL;
        if (mnt_ns_loop(old_path.dentry))
-               goto out; 
+               goto out;
  
        mp = lock_mount(path);
        err = PTR_ERR(mp);
@@@ -3239,6 -3179,7 +3180,6 @@@ static void __init init_mount_tree(void
  
  void __init mnt_init(void)
  {
 -      unsigned u;
        int err;
  
        mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
        mount_hashtable = alloc_large_system_hash("Mount-cache",
                                sizeof(struct hlist_head),
                                mhash_entries, 19,
 -                              0,
 +                              HASH_ZERO,
                                &m_hash_shift, &m_hash_mask, 0, 0);
        mountpoint_hashtable = alloc_large_system_hash("Mountpoint-cache",
                                sizeof(struct hlist_head),
                                mphash_entries, 19,
 -                              0,
 +                              HASH_ZERO,
                                &mp_hash_shift, &mp_hash_mask, 0, 0);
  
        if (!mount_hashtable || !mountpoint_hashtable)
                panic("Failed to allocate mount hash table\n");
  
 -      for (u = 0; u <= m_hash_mask; u++)
 -              INIT_HLIST_HEAD(&mount_hashtable[u]);
 -      for (u = 0; u <= mp_hash_mask; u++)
 -              INIT_HLIST_HEAD(&mountpoint_hashtable[u]);
 -
        kernfs_init();
  
        err = sysfs_init();
diff --combined fs/pstore/inode.c
index 4d02c3b65061fdedea4d544d463e8f042a908d91,913e839ac1f5b7972c718ee2a034840bfba6cd24..fefd22611cf60b1c25b7842b63da5957876a444f
@@@ -283,6 -283,16 +283,16 @@@ static void parse_options(char *options
        }
  }
  
+ /*
+  * Display the mount options in /proc/mounts.
+  */
+ static int pstore_show_options(struct seq_file *m, struct dentry *root)
+ {
+       if (kmsg_bytes != PSTORE_DEFAULT_KMSG_BYTES)
+               seq_printf(m, ",kmsg_bytes=%lu", kmsg_bytes);
+       return 0;
+ }
  static int pstore_remount(struct super_block *sb, int *flags, char *data)
  {
        sync_filesystem(sb);
@@@ -296,7 -306,7 +306,7 @@@ static const struct super_operations ps
        .drop_inode     = generic_delete_inode,
        .evict_inode    = pstore_evict_inode,
        .remount_fs     = pstore_remount,
-       .show_options   = generic_show_options,
+       .show_options   = pstore_show_options,
  };
  
  static struct super_block *pstore_sb;
@@@ -349,48 -359,48 +359,48 @@@ int pstore_mkfile(struct dentry *root, 
  
        switch (record->type) {
        case PSTORE_TYPE_DMESG:
 -              scnprintf(name, sizeof(name), "dmesg-%s-%lld%s",
 +              scnprintf(name, sizeof(name), "dmesg-%s-%llu%s",
                          record->psi->name, record->id,
                          record->compressed ? ".enc.z" : "");
                break;
        case PSTORE_TYPE_CONSOLE:
 -              scnprintf(name, sizeof(name), "console-%s-%lld",
 +              scnprintf(name, sizeof(name), "console-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_FTRACE:
 -              scnprintf(name, sizeof(name), "ftrace-%s-%lld",
 +              scnprintf(name, sizeof(name), "ftrace-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_MCE:
 -              scnprintf(name, sizeof(name), "mce-%s-%lld",
 +              scnprintf(name, sizeof(name), "mce-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_PPC_RTAS:
 -              scnprintf(name, sizeof(name), "rtas-%s-%lld",
 +              scnprintf(name, sizeof(name), "rtas-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_PPC_OF:
 -              scnprintf(name, sizeof(name), "powerpc-ofw-%s-%lld",
 +              scnprintf(name, sizeof(name), "powerpc-ofw-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_PPC_COMMON:
 -              scnprintf(name, sizeof(name), "powerpc-common-%s-%lld",
 +              scnprintf(name, sizeof(name), "powerpc-common-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_PMSG:
 -              scnprintf(name, sizeof(name), "pmsg-%s-%lld",
 +              scnprintf(name, sizeof(name), "pmsg-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_PPC_OPAL:
 -              scnprintf(name, sizeof(name), "powerpc-opal-%s-%lld",
 +              scnprintf(name, sizeof(name), "powerpc-opal-%s-%llu",
                          record->psi->name, record->id);
                break;
        case PSTORE_TYPE_UNKNOWN:
 -              scnprintf(name, sizeof(name), "unknown-%s-%lld",
 +              scnprintf(name, sizeof(name), "unknown-%s-%llu",
                          record->psi->name, record->id);
                break;
        default:
 -              scnprintf(name, sizeof(name), "type%d-%s-%lld",
 +              scnprintf(name, sizeof(name), "type%d-%s-%llu",
                          record->type, record->psi->name, record->id);
                break;
        }
@@@ -448,8 -458,6 +458,6 @@@ static int pstore_fill_super(struct sup
  {
        struct inode *inode;
  
-       save_mount_options(sb, data);
        pstore_sb = sb;
  
        sb->s_maxbytes          = MAX_LFS_FILESIZE;
diff --combined fs/pstore/internal.h
index 58051265626fefa9fb63e72ab238b16a9cf697d8,4d5913130580eaa1275f027caf9278dec1f073c1..7f4e48c8d1884dc122834193969f77761abc7676
@@@ -5,6 -5,9 +5,9 @@@
  #include <linux/time.h>
  #include <linux/pstore.h>
  
+ #define PSTORE_DEFAULT_KMSG_BYTES 10240
+ extern unsigned long kmsg_bytes;
  #ifdef CONFIG_PSTORE_FTRACE
  extern void pstore_register_ftrace(void);
  extern void pstore_unregister_ftrace(void);
@@@ -30,7 -33,5 +33,7 @@@ extern void   pstore_get_backend_records(
  extern int    pstore_mkfile(struct dentry *root,
                              struct pstore_record *record);
  extern bool   pstore_is_mounted(void);
 +extern void   pstore_record_init(struct pstore_record *record,
 +                                 struct pstore_info *psi);
  
  #endif
diff --combined fs/pstore/platform.c
index 1b6e0ff6bff5e498f851b42f744f9275ada957d9,6640df40908d4c91fba9b1e53dd654877800f64f..2b21d180157c16a823f2f21d41e31d820bf77232
@@@ -99,7 -99,7 +99,7 @@@ static char *big_oops_buf
  static size_t big_oops_buf_sz;
  
  /* How much of the console log to snapshot */
static unsigned long kmsg_bytes = 10240;
unsigned long kmsg_bytes = PSTORE_DEFAULT_KMSG_BYTES;
  
  void pstore_set_kmsg_bytes(int bytes)
  {
@@@ -474,20 -474,6 +474,20 @@@ static size_t copy_kmsg_to_buffer(int h
        return total_len;
  }
  
 +void pstore_record_init(struct pstore_record *record,
 +                      struct pstore_info *psinfo)
 +{
 +      memset(record, 0, sizeof(*record));
 +
 +      record->psi = psinfo;
 +
 +      /* Report zeroed timestamp if called before timekeeping has resumed. */
 +      if (__getnstimeofday(&record->time)) {
 +              record->time.tv_sec = 0;
 +              record->time.tv_nsec = 0;
 +      }
 +}
 +
  /*
   * callback from kmsg_dump. (s2,l2) has the most recently
   * written bytes, older bytes are in (s1,l1). Save as much
@@@ -523,14 -509,15 +523,14 @@@ static void pstore_dump(struct kmsg_dum
                int header_size;
                int zipped_len = -1;
                size_t dump_size;
 -              struct pstore_record record = {
 -                      .type = PSTORE_TYPE_DMESG,
 -                      .count = oopscount,
 -                      .reason = reason,
 -                      .part = part,
 -                      .compressed = false,
 -                      .buf = psinfo->buf,
 -                      .psi = psinfo,
 -              };
 +              struct pstore_record record;
 +
 +              pstore_record_init(&record, psinfo);
 +              record.type = PSTORE_TYPE_DMESG;
 +              record.count = oopscount;
 +              record.reason = reason;
 +              record.part = part;
 +              record.buf = psinfo->buf;
  
                if (big_oops_buf && is_locked) {
                        dst = big_oops_buf;
@@@ -600,12 -587,12 +600,12 @@@ static void pstore_console_write(struc
        const char *e = s + c;
  
        while (s < e) {
 -              struct pstore_record record = {
 -                      .type = PSTORE_TYPE_CONSOLE,
 -                      .psi = psinfo,
 -              };
 +              struct pstore_record record;
                unsigned long flags;
  
 +              pstore_record_init(&record, psinfo);
 +              record.type = PSTORE_TYPE_CONSOLE;
 +
                if (c > psinfo->bufsize)
                        c = psinfo->bufsize;
  
@@@ -653,16 -640,19 +653,16 @@@ static int pstore_write_user_compat(str
        if (record->buf)
                return -EINVAL;
  
 -      record->buf = kmalloc(record->size, GFP_KERNEL);
 -      if (!record->buf)
 -              return -ENOMEM;
 -
 -      if (unlikely(copy_from_user(record->buf, buf, record->size))) {
 -              ret = -EFAULT;
 +      record->buf = memdup_user(buf, record->size);
 +      if (unlikely(IS_ERR(record->buf))) {
 +              ret = PTR_ERR(record->buf);
                goto out;
        }
  
        ret = record->psi->write(record);
  
 -out:
        kfree(record->buf);
 +out:
        record->buf = NULL;
  
        return unlikely(ret < 0) ? ret : record->size;
@@@ -780,11 -770,8 +780,11 @@@ static void decompress_record(struct ps
        int unzipped_len;
        char *decompressed;
  
 +      if (!record->compressed)
 +              return;
 +
        /* Only PSTORE_TYPE_DMESG support compression. */
 -      if (!record->compressed || record->type != PSTORE_TYPE_DMESG) {
 +      if (record->type != PSTORE_TYPE_DMESG) {
                pr_warn("ignored compressed record type %d\n", record->type);
                return;
        }
@@@ -832,7 -819,6 +832,7 @@@ void pstore_get_backend_records(struct 
                                struct dentry *root, int quiet)
  {
        int failed = 0;
 +      unsigned int stop_loop = 65536;
  
        if (!psi || !root)
                return;
         * may reallocate record.buf. On success, pstore_mkfile() will keep
         * the record.buf, so free it only on failure.
         */
 -      for (;;) {
 +      for (; stop_loop; stop_loop--) {
                struct pstore_record *record;
                int rc;
  
                        pr_err("out of memory creating record\n");
                        break;
                }
 -              record->psi = psi;
 +              pstore_record_init(record, psi);
  
                record->size = psi->read(record);
  
                /* No more records left in backend? */
 -              if (record->size <= 0)
 +              if (record->size <= 0) {
 +                      kfree(record);
                        break;
 +              }
  
                decompress_record(record);
                rc = pstore_mkfile(root, record);
@@@ -881,11 -865,8 +881,11 @@@ out
        mutex_unlock(&psi->read_mutex);
  
        if (failed)
 -              pr_warn("failed to load %d record(s) from '%s'\n",
 +              pr_warn("failed to create %d record(s) from '%s'\n",
                        failed, psi->name);
 +      if (!stop_loop)
 +              pr_err("looping? Too many records seen from '%s'\n",
 +                      psi->name);
  }
  
  static void pstore_dowork(struct work_struct *work)
diff --combined include/linux/dcache.h
index c706eaac692e8129ce4b0a9d41b298eb3c3756c8,3f65a4fa72edad0dc90ebd1373f2c57629701579..3f3ff4ccdc3fdc37c87ac345e2c49037ab3294e3
@@@ -55,6 -55,11 +55,11 @@@ struct qstr 
  
  #define QSTR_INIT(n,l) { { { .len = l } }, .name = n }
  
+ extern const char empty_string[];
+ extern const struct qstr empty_name;
+ extern const char slash_string[];
+ extern const struct qstr slash_name;
  struct dentry_stat_t {
        long nr_dentry;
        long nr_unused;
@@@ -591,11 -596,5 +596,11 @@@ static inline struct inode *d_real_inod
        return d_backing_inode(d_real((struct dentry *) dentry, NULL, 0));
  }
  
 +struct name_snapshot {
 +      const unsigned char *name;
 +      unsigned char inline_name[DNAME_INLINE_LEN];
 +};
 +void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
 +void release_dentry_name_snapshot(struct name_snapshot *);
  
  #endif        /* __LINUX_DCACHE_H */
diff --combined include/linux/fs.h
index 976aaa1af82aad51f6805a0d1d7a5479f872872a,e265b2ea72c6308fb3f30408e578733f5bc3aa63..7b5d6816542b7f5af171d5680961aeb03184707b
@@@ -2,7 -2,7 +2,7 @@@
  #define _LINUX_FS_H
  
  #include <linux/linkage.h>
 -#include <linux/wait.h>
 +#include <linux/wait_bit.h>
  #include <linux/kdev_t.h>
  #include <linux/dcache.h>
  #include <linux/path.h>
  #include <linux/bug.h>
  #include <linux/mutex.h>
  #include <linux/rwsem.h>
 +#include <linux/mm_types.h>
  #include <linux/capability.h>
  #include <linux/semaphore.h>
 +#include <linux/fcntl.h>
  #include <linux/fiemap.h>
  #include <linux/rculist_bl.h>
  #include <linux/atomic.h>
@@@ -32,8 -30,6 +32,8 @@@
  #include <linux/percpu-rwsem.h>
  #include <linux/workqueue.h>
  #include <linux/delayed_call.h>
 +#include <linux/uuid.h>
 +#include <linux/errseq.h>
  
  #include <asm/byteorder.h>
  #include <uapi/linux/fs.h>
@@@ -146,9 -142,6 +146,9 @@@ typedef int (dio_iodone_t)(struct kioc
  /* File was opened by fanotify and shouldn't generate fanotify events */
  #define FMODE_NONOTIFY                ((__force fmode_t)0x4000000)
  
 +/* File is capable of returning -EAGAIN if AIO will block */
 +#define FMODE_AIO_NOWAIT      ((__force fmode_t)0x8000000)
 +
  /*
   * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
   * that indicates that they should check the contents of the iovec are
@@@ -268,18 -261,6 +268,18 @@@ struct page
  struct address_space;
  struct writeback_control;
  
 +/*
 + * Write life time hint values.
 + */
 +enum rw_hint {
 +      WRITE_LIFE_NOT_SET      = 0,
 +      WRITE_LIFE_NONE         = RWH_WRITE_LIFE_NONE,
 +      WRITE_LIFE_SHORT        = RWH_WRITE_LIFE_SHORT,
 +      WRITE_LIFE_MEDIUM       = RWH_WRITE_LIFE_MEDIUM,
 +      WRITE_LIFE_LONG         = RWH_WRITE_LIFE_LONG,
 +      WRITE_LIFE_EXTREME      = RWH_WRITE_LIFE_EXTREME,
 +};
 +
  #define IOCB_EVENTFD          (1 << 0)
  #define IOCB_APPEND           (1 << 1)
  #define IOCB_DIRECT           (1 << 2)
  #define IOCB_DSYNC            (1 << 4)
  #define IOCB_SYNC             (1 << 5)
  #define IOCB_WRITE            (1 << 6)
 +#define IOCB_NOWAIT           (1 << 7)
  
  struct kiocb {
        struct file             *ki_filp;
        void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
        void                    *private;
        int                     ki_flags;
 +      enum rw_hint            ki_hint;
  };
  
  static inline bool is_sync_kiocb(struct kiocb *kiocb)
        return kiocb->ki_complete == NULL;
  }
  
 -static inline int iocb_flags(struct file *file);
 -
 -static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
 -{
 -      *kiocb = (struct kiocb) {
 -              .ki_filp = filp,
 -              .ki_flags = iocb_flags(filp),
 -      };
 -}
 -
  /*
   * "descriptor" for what we're up to with a read.
   * This allows us to use the same read code yet
@@@ -403,7 -392,6 +403,7 @@@ struct address_space 
        gfp_t                   gfp_mask;       /* implicit gfp mask for allocations */
        struct list_head        private_list;   /* ditto */
        void                    *private_data;  /* ditto */
 +      errseq_t                wb_err;
  } __attribute__((aligned(sizeof(long))));
        /*
         * On most architectures that alignment is already the case; but
@@@ -604,7 -592,6 +604,7 @@@ struct inode 
        spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
        unsigned short          i_bytes;
        unsigned int            i_blkbits;
 +      enum rw_hint            i_write_hint;
        blkcnt_t                i_blocks;
  
  #ifdef __NEED_I_SIZE_ORDERED
@@@ -859,7 -846,6 +859,7 @@@ struct file 
         * Must not be taken from IRQ context.
         */
        spinlock_t              f_lock;
 +      enum rw_hint            f_write_hint;
        atomic_long_t           f_count;
        unsigned int            f_flags;
        fmode_t                 f_mode;
        struct list_head        f_tfile_llink;
  #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
 +      errseq_t                f_wb_err;
  } __attribute__((aligned(4)));        /* lest something weird decides that 2 is OK */
  
  struct file_handle {
@@@ -1036,6 -1021,8 +1036,6 @@@ struct file_lock_context 
  #define OFFT_OFFSET_MAX       INT_LIMIT(off_t)
  #endif
  
 -#include <linux/fcntl.h>
 -
  extern void send_sigio(struct fown_struct *fown, int fd, int band);
  
  /*
@@@ -1051,14 -1038,14 +1051,14 @@@ static inline struct inode *locks_inode
  }
  
  #ifdef CONFIG_FILE_LOCKING
 -extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *);
 +extern int fcntl_getlk(struct file *, unsigned int, struct flock *);
  extern int fcntl_setlk(unsigned int, struct file *, unsigned int,
 -                      struct flock __user *);
 +                      struct flock *);
  
  #if BITS_PER_LONG == 32
 -extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 __user *);
 +extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 *);
  extern int fcntl_setlk64(unsigned int, struct file *, unsigned int,
 -                      struct flock64 __user *);
 +                      struct flock64 *);
  #endif
  
  extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
@@@ -1262,7 -1249,7 +1262,7 @@@ extern void fasync_free(struct fasync_s
  extern void kill_fasync(struct fasync_struct **, int, int);
  
  extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
 -extern void f_setown(struct file *filp, unsigned long arg, int force);
 +extern int f_setown(struct file *filp, unsigned long arg, int force);
  extern void f_delown(struct file *filp);
  extern pid_t f_getown(struct file *filp);
  extern int send_sigurg(struct fown_struct *fown);
@@@ -1341,8 -1328,8 +1341,8 @@@ struct super_block 
  
        struct sb_writers       s_writers;
  
 -      char s_id[32];                          /* Informational name */
 -      u8 s_uuid[16];                          /* UUID */
 +      char                    s_id[32];       /* Informational name */
 +      uuid_t                  s_uuid;         /* UUID */
  
        void                    *s_fs_info;     /* Filesystem private info */
        unsigned int            s_max_links;
         */
        char *s_subtype;
  
-       /*
-        * Saved mount options for lazy filesystems using
-        * generic_show_options()
-        */
-       char __rcu *s_options;
        const struct dentry_operations *s_d_op; /* default d_op for dentries */
  
        /*
@@@ -1752,6 -1734,12 +1747,6 @@@ static inline int call_mmap(struct fil
        return file->f_op->mmap(file, vma);
  }
  
 -static inline int call_fsync(struct file *file, loff_t start, loff_t end,
 -                           int datasync)
 -{
 -      return file->f_op->fsync(file, start, end, datasync);
 -}
 -
  ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
                              unsigned long nr_segs, unsigned long fast_segs,
                              struct iovec *fast_pointer,
@@@ -1880,25 -1868,6 +1875,25 @@@ static inline bool HAS_UNMAPPED_ID(stru
        return !uid_valid(inode->i_uid) || !gid_valid(inode->i_gid);
  }
  
 +static inline enum rw_hint file_write_hint(struct file *file)
 +{
 +      if (file->f_write_hint != WRITE_LIFE_NOT_SET)
 +              return file->f_write_hint;
 +
 +      return file_inode(file)->i_write_hint;
 +}
 +
 +static inline int iocb_flags(struct file *file);
 +
 +static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
 +{
 +      *kiocb = (struct kiocb) {
 +              .ki_filp = filp,
 +              .ki_flags = iocb_flags(filp),
 +              .ki_hint = file_write_hint(filp),
 +      };
 +}
 +
  /*
   * Inode state bits.  Protected by inode->i_lock
   *
   *                    wb stat updates to grab mapping->tree_lock.  See
   *                    inode_switch_wb_work_fn() for details.
   *
 + * I_OVL_INUSE                Used by overlayfs to get exclusive ownership on upper
 + *                    and work dirs among overlayfs mounts.
 + *
   * Q: What is the difference between I_WILL_FREE and I_FREEING?
   */
  #define I_DIRTY_SYNC          (1 << 0)
  #define __I_DIRTY_TIME_EXPIRED        12
  #define I_DIRTY_TIME_EXPIRED  (1 << __I_DIRTY_TIME_EXPIRED)
  #define I_WB_SWITCH           (1 << 13)
 +#define I_OVL_INUSE                   (1 << 14)
  
  #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
  #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME)
@@@ -2544,11 -2509,9 +2539,11 @@@ extern int write_inode_now(struct inod
  extern int filemap_fdatawrite(struct address_space *);
  extern int filemap_flush(struct address_space *);
  extern int filemap_fdatawait(struct address_space *);
 -extern void filemap_fdatawait_keep_errors(struct address_space *);
 +extern int filemap_fdatawait_keep_errors(struct address_space *mapping);
  extern int filemap_fdatawait_range(struct address_space *, loff_t lstart,
                                   loff_t lend);
 +extern bool filemap_range_has_page(struct address_space *, loff_t lstart,
 +                                loff_t lend);
  extern int filemap_write_and_wait(struct address_space *mapping);
  extern int filemap_write_and_wait_range(struct address_space *mapping,
                                        loff_t lstart, loff_t lend);
@@@ -2558,62 -2521,6 +2553,62 @@@ extern int filemap_fdatawrite_range(str
                                loff_t start, loff_t end);
  extern int filemap_check_errors(struct address_space *mapping);
  
 +extern void __filemap_set_wb_err(struct address_space *mapping, int err);
 +extern int __must_check file_check_and_advance_wb_err(struct file *file);
 +extern int __must_check file_write_and_wait_range(struct file *file,
 +                                              loff_t start, loff_t end);
 +
 +/**
 + * filemap_set_wb_err - set a writeback error on an address_space
 + * @mapping: mapping in which to set writeback error
 + * @err: error to be set in mapping
 + *
 + * When writeback fails in some way, we must record that error so that
 + * userspace can be informed when fsync and the like are called.  We endeavor
 + * to report errors on any file that was open at the time of the error.  Some
 + * internal callers also need to know when writeback errors have occurred.
 + *
 + * When a writeback error occurs, most filesystems will want to call
 + * filemap_set_wb_err to record the error in the mapping so that it will be
 + * automatically reported whenever fsync is called on the file.
 + *
 + * FIXME: mention FS_* flag here?
 + */
 +static inline void filemap_set_wb_err(struct address_space *mapping, int err)
 +{
 +      /* Fastpath for common case of no error */
 +      if (unlikely(err))
 +              __filemap_set_wb_err(mapping, err);
 +}
 +
 +/**
 + * filemap_check_wb_error - has an error occurred since the mark was sampled?
 + * @mapping: mapping to check for writeback errors
 + * @since: previously-sampled errseq_t
 + *
 + * Grab the errseq_t value from the mapping, and see if it has changed "since"
 + * the given value was sampled.
 + *
 + * If it has then report the latest error set, otherwise return 0.
 + */
 +static inline int filemap_check_wb_err(struct address_space *mapping,
 +                                      errseq_t since)
 +{
 +      return errseq_check(&mapping->wb_err, since);
 +}
 +
 +/**
 + * filemap_sample_wb_err - sample the current errseq_t to test for later errors
 + * @mapping: mapping to be sampled
 + *
 + * Writeback errors are always reported relative to a particular sample point
 + * in the past. This function provides those sample points.
 + */
 +static inline errseq_t filemap_sample_wb_err(struct address_space *mapping)
 +{
 +      return errseq_sample(&mapping->wb_err);
 +}
 +
  extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end,
                           int datasync);
  extern int vfs_fsync(struct file *file, int datasync);
@@@ -2877,10 -2784,8 +2872,10 @@@ extern ssize_t generic_file_write_iter(
  extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *);
  extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t);
  
 -ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos);
 -ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos);
 +ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos,
 +              int flags);
 +ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos,
 +              int flags);
  
  /* fs/block_dev.c */
  extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to);
@@@ -2933,7 -2838,7 +2928,7 @@@ enum 
        DIO_SKIP_DIO_COUNT = 0x08,
  };
  
 -void dio_end_io(struct bio *bio, int error);
 +void dio_end_io(struct bio *bio);
  
  ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
                             struct block_device *bdev, struct iov_iter *iter,
@@@ -3046,7 -2951,7 +3041,7 @@@ extern int generic_block_fiemap(struct 
                                struct fiemap_extent_info *fieinfo, u64 start,
                                u64 len, get_block_t *get_block);
  
- extern void get_filesystem(struct file_system_type *fs);
+ extern struct file_system_type *get_filesystem(struct file_system_type *fs);
  extern void put_filesystem(struct file_system_type *fs);
  extern struct file_system_type *get_fs_type(const char *name);
  extern struct super_block *get_super(struct block_device *);
@@@ -3123,20 -3028,11 +3118,16 @@@ extern void setattr_copy(struct inode *
  
  extern int file_update_time(struct file *file);
  
- extern int generic_show_options(struct seq_file *m, struct dentry *root);
- extern void save_mount_options(struct super_block *sb, char *options);
- extern void replace_mount_options(struct super_block *sb, char *options);
  static inline bool io_is_direct(struct file *filp)
  {
        return (filp->f_flags & O_DIRECT) || IS_DAX(filp->f_mapping->host);
  }
  
 +static inline bool vma_is_dax(struct vm_area_struct *vma)
 +{
 +      return vma->vm_file && IS_DAX(vma->vm_file->f_mapping->host);
 +}
 +
  static inline int iocb_flags(struct file *file)
  {
        int res = 0;
        return res;
  }
  
 +static inline int kiocb_set_rw_flags(struct kiocb *ki, int flags)
 +{
 +      if (unlikely(flags & ~RWF_SUPPORTED))
 +              return -EOPNOTSUPP;
 +
 +      if (flags & RWF_NOWAIT) {
 +              if (!(ki->ki_filp->f_mode & FMODE_AIO_NOWAIT))
 +                      return -EOPNOTSUPP;
 +              ki->ki_flags |= IOCB_NOWAIT;
 +      }
 +      if (flags & RWF_HIPRI)
 +              ki->ki_flags |= IOCB_HIPRI;
 +      if (flags & RWF_DSYNC)
 +              ki->ki_flags |= IOCB_DSYNC;
 +      if (flags & RWF_SYNC)
 +              ki->ki_flags |= (IOCB_DSYNC | IOCB_SYNC);
 +      return 0;
 +}
 +
  static inline ino_t parent_ino(struct dentry *dentry)
  {
        ino_t res;
diff --combined include/linux/hugetlb.h
index 8d9fe131a24092b140f6a3da5f190cc5cbb42bfd,3b6eeaad2f77926613e9066b7dae5f196d820a12..0ed8e41aaf1173d3722a058f3be7c01828ca9284
@@@ -14,30 -14,6 +14,30 @@@ struct ctl_table
  struct user_struct;
  struct mmu_gather;
  
 +#ifndef is_hugepd
 +/*
 + * Some architectures requires a hugepage directory format that is
 + * required to support multiple hugepage sizes. For example
 + * a4fe3ce76 "powerpc/mm: Allow more flexible layouts for hugepage pagetables"
 + * introduced the same on powerpc. This allows for a more flexible hugepage
 + * pagetable layout.
 + */
 +typedef struct { unsigned long pd; } hugepd_t;
 +#define is_hugepd(hugepd) (0)
 +#define __hugepd(x) ((hugepd_t) { (x) })
 +static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
 +                            unsigned pdshift, unsigned long end,
 +                            int write, struct page **pages, int *nr)
 +{
 +      return 0;
 +}
 +#else
 +extern int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
 +                     unsigned pdshift, unsigned long end,
 +                     int write, struct page **pages, int *nr);
 +#endif
 +
 +
  #ifdef CONFIG_HUGETLB_PAGE
  
  #include <linux/mempolicy.h>
@@@ -116,6 -92,7 +116,6 @@@ int hugetlb_reserve_pages(struct inode 
                                                vm_flags_t vm_flags);
  long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
                                                long freed);
 -int dequeue_hwpoisoned_huge_page(struct page *page);
  bool isolate_huge_page(struct page *page, struct list_head *list);
  void putback_active_hugepage(struct page *page);
  void free_huge_page(struct page *page);
@@@ -136,27 -113,19 +136,27 @@@ extern struct list_head huge_boot_pages
  
  pte_t *huge_pte_alloc(struct mm_struct *mm,
                        unsigned long addr, unsigned long sz);
 -pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr);
 +pte_t *huge_pte_offset(struct mm_struct *mm,
 +                     unsigned long addr, unsigned long sz);
  int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep);
  struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
                              int write);
 +struct page *follow_huge_pd(struct vm_area_struct *vma,
 +                          unsigned long address, hugepd_t hpd,
 +                          int flags, int pdshift);
  struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
                                pmd_t *pmd, int flags);
  struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
                                pud_t *pud, int flags);
 +struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,
 +                           pgd_t *pgd, int flags);
 +
  int pmd_huge(pmd_t pmd);
  int pud_huge(pud_t pud);
  unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
                unsigned long address, unsigned long end, pgprot_t newprot);
  
 +bool is_hugetlb_entry_migration(pte_t pte);
  #else /* !CONFIG_HUGETLB_PAGE */
  
  static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma)
@@@ -178,10 -147,8 +178,10 @@@ static inline void hugetlb_report_memin
  static inline void hugetlb_show_meminfo(void)
  {
  }
 +#define follow_huge_pd(vma, addr, hpd, flags, pdshift) NULL
  #define follow_huge_pmd(mm, addr, pmd, flags) NULL
  #define follow_huge_pud(mm, addr, pud, flags) NULL
 +#define follow_huge_pgd(mm, addr, pgd, flags) NULL
  #define prepare_hugepage_range(file, addr, len)       (-EINVAL)
  #define pmd_huge(x)   0
  #define pud_huge(x)   0
  #define hugetlb_fault(mm, vma, addr, flags)   ({ BUG(); 0; })
  #define hugetlb_mcopy_atomic_pte(dst_mm, dst_pte, dst_vma, dst_addr, \
                                src_addr, pagep)        ({ BUG(); 0; })
 -#define huge_pte_offset(mm, address)  0
 -static inline int dequeue_hwpoisoned_huge_page(struct page *page)
 -{
 -      return 0;
 -}
 +#define huge_pte_offset(mm, address, sz)      0
  
  static inline bool isolate_huge_page(struct page *page, struct list_head *list)
  {
@@@ -246,6 -217,29 +246,6 @@@ static inline int pud_write(pud_t pud
  }
  #endif
  
 -#ifndef is_hugepd
 -/*
 - * Some architectures requires a hugepage directory format that is
 - * required to support multiple hugepage sizes. For example
 - * a4fe3ce76 "powerpc/mm: Allow more flexible layouts for hugepage pagetables"
 - * introduced the same on powerpc. This allows for a more flexible hugepage
 - * pagetable layout.
 - */
 -typedef struct { unsigned long pd; } hugepd_t;
 -#define is_hugepd(hugepd) (0)
 -#define __hugepd(x) ((hugepd_t) { (x) })
 -static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
 -                            unsigned pdshift, unsigned long end,
 -                            int write, struct page **pages, int *nr)
 -{
 -      return 0;
 -}
 -#else
 -extern int gup_huge_pd(hugepd_t hugepd, unsigned long addr,
 -                     unsigned pdshift, unsigned long end,
 -                     int write, struct page **pages, int *nr);
 -#endif
 -
  #define HUGETLB_ANON_FILE "anon_hugepage"
  
  enum {
@@@ -268,6 -262,9 +268,9 @@@ struct hugetlbfs_sb_info 
        spinlock_t      stat_lock;
        struct hstate *hstate;
        struct hugepage_subpool *spool;
+       kuid_t  uid;
+       kgid_t  gid;
+       umode_t mode;
  };
  
  static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
@@@ -349,8 -346,6 +352,8 @@@ struct page *alloc_huge_page(struct vm_
  struct page *alloc_huge_page_node(struct hstate *h, int nid);
  struct page *alloc_huge_page_noerr(struct vm_area_struct *vma,
                                unsigned long addr, int avoid_reserve);
 +struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
 +                              nodemask_t *nmask);
  int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
                        pgoff_t idx);
  
@@@ -469,17 -464,12 +472,17 @@@ static inline pgoff_t basepage_index(st
        return __basepage_index(page);
  }
  
 +extern int dissolve_free_huge_page(struct page *page);
  extern int dissolve_free_huge_pages(unsigned long start_pfn,
                                    unsigned long end_pfn);
  static inline bool hugepage_migration_supported(struct hstate *h)
  {
  #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
 -      return huge_page_shift(h) == PMD_SHIFT;
 +      if ((huge_page_shift(h) == PMD_SHIFT) ||
 +              (huge_page_shift(h) == PGDIR_SHIFT))
 +              return true;
 +      else
 +              return false;
  #else
        return false;
  #endif
@@@ -514,19 -504,10 +517,19 @@@ static inline void hugetlb_count_sub(lo
  {
        atomic_long_sub(l, &mm->hugetlb_usage);
  }
 +
 +#ifndef set_huge_swap_pte_at
 +static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
 +                                      pte_t *ptep, pte_t pte, unsigned long sz)
 +{
 +      set_huge_pte_at(mm, addr, ptep, pte);
 +}
 +#endif
  #else /* CONFIG_HUGETLB_PAGE */
  struct hstate {};
  #define alloc_huge_page(v, a, r) NULL
  #define alloc_huge_page_node(h, nid) NULL
 +#define alloc_huge_page_nodemask(h, preferred_nid, nmask) NULL
  #define alloc_huge_page_noerr(v, a, r) NULL
  #define alloc_bootmem_huge_page(h) NULL
  #define hstate_file(f) NULL
  #define vma_mmu_pagesize(v) PAGE_SIZE
  #define huge_page_order(h) 0
  #define huge_page_shift(h) PAGE_SHIFT
 +static inline bool hstate_is_gigantic(struct hstate *h)
 +{
 +      return false;
 +}
 +
  static inline unsigned int pages_per_huge_page(struct hstate *h)
  {
        return 1;
  }
 -#define hstate_index_to_shift(index) 0
 -#define hstate_index(h) 0
 +
 +static inline unsigned hstate_index_to_shift(unsigned index)
 +{
 +      return 0;
 +}
 +
 +static inline int hstate_index(struct hstate *h)
 +{
 +      return 0;
 +}
  
  static inline pgoff_t basepage_index(struct page *page)
  {
        return page->index;
  }
 -#define dissolve_free_huge_pages(s, e)        0
 -#define hugepage_migration_supported(h)       false
 +
 +static inline int dissolve_free_huge_page(struct page *page)
 +{
 +      return 0;
 +}
 +
 +static inline int dissolve_free_huge_pages(unsigned long start_pfn,
 +                                         unsigned long end_pfn)
 +{
 +      return 0;
 +}
 +
 +static inline bool hugepage_migration_supported(struct hstate *h)
 +{
 +      return false;
 +}
  
  static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
                                           struct mm_struct *mm, pte_t *pte)
@@@ -594,11 -548,6 +597,11 @@@ static inline void hugetlb_report_usage
  static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
  {
  }
 +
 +static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
 +                                      pte_t *ptep, pte_t pte, unsigned long sz)
 +{
 +}
  #endif        /* CONFIG_HUGETLB_PAGE */
  
  static inline spinlock_t *huge_pte_lock(struct hstate *h,
diff --combined include/linux/string.h
index 049866760e8bb604358fed5355442d0b097597d0,3dd944cfe171f0094011f5d9f60f01dc371a963c..a467e617eeb08cde480b7e5e2b65ffa208d2243c
@@@ -122,12 -122,6 +122,12 @@@ static inline __must_check int memcpy_m
        return 0;
  }
  #endif
 +#ifndef __HAVE_ARCH_MEMCPY_FLUSHCACHE
 +static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
 +{
 +      memcpy(dst, src, cnt);
 +}
 +#endif
  void *memchr_inv(const void *s, int c, size_t n);
  char *strreplace(char *s, char old, char new);
  
@@@ -137,6 -131,7 +137,7 @@@ extern char *kstrdup(const char *s, gfp
  extern const char *kstrdup_const(const char *s, gfp_t gfp);
  extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
  extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
+ extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
  
  extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
  extern void argv_free(char **argv);
@@@ -193,205 -188,4 +194,205 @@@ static inline const char *kbasename(con
        return tail ? tail + 1 : path;
  }
  
 +#define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline))
 +#define __RENAME(x) __asm__(#x)
 +
 +void fortify_panic(const char *name) __noreturn __cold;
 +void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter");
 +void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter");
 +void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
 +
 +#if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
 +__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (__builtin_constant_p(size) && p_size < size)
 +              __write_overflow();
 +      if (p_size < size)
 +              fortify_panic(__func__);
 +      return __builtin_strncpy(p, q, size);
 +}
 +
 +__FORTIFY_INLINE char *strcat(char *p, const char *q)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (p_size == (size_t)-1)
 +              return __builtin_strcat(p, q);
 +      if (strlcat(p, q, p_size) >= p_size)
 +              fortify_panic(__func__);
 +      return p;
 +}
 +
 +__FORTIFY_INLINE __kernel_size_t strlen(const char *p)
 +{
 +      __kernel_size_t ret;
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (p_size == (size_t)-1)
 +              return __builtin_strlen(p);
 +      ret = strnlen(p, p_size);
 +      if (p_size <= ret)
 +              fortify_panic(__func__);
 +      return ret;
 +}
 +
 +extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
 +__FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      __kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
 +      if (p_size <= ret && maxlen != ret)
 +              fortify_panic(__func__);
 +      return ret;
 +}
 +
 +/* defined after fortified strlen to reuse it */
 +extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
 +__FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
 +{
 +      size_t ret;
 +      size_t p_size = __builtin_object_size(p, 0);
 +      size_t q_size = __builtin_object_size(q, 0);
 +      if (p_size == (size_t)-1 && q_size == (size_t)-1)
 +              return __real_strlcpy(p, q, size);
 +      ret = strlen(q);
 +      if (size) {
 +              size_t len = (ret >= size) ? size - 1 : ret;
 +              if (__builtin_constant_p(len) && len >= p_size)
 +                      __write_overflow();
 +              if (len >= p_size)
 +                      fortify_panic(__func__);
 +              __builtin_memcpy(p, q, len);
 +              p[len] = '\0';
 +      }
 +      return ret;
 +}
 +
 +/* defined after fortified strlen and strnlen to reuse them */
 +__FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
 +{
 +      size_t p_len, copy_len;
 +      size_t p_size = __builtin_object_size(p, 0);
 +      size_t q_size = __builtin_object_size(q, 0);
 +      if (p_size == (size_t)-1 && q_size == (size_t)-1)
 +              return __builtin_strncat(p, q, count);
 +      p_len = strlen(p);
 +      copy_len = strnlen(q, count);
 +      if (p_size < p_len + copy_len + 1)
 +              fortify_panic(__func__);
 +      __builtin_memcpy(p + p_len, q, copy_len);
 +      p[p_len + copy_len] = '\0';
 +      return p;
 +}
 +
 +__FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (__builtin_constant_p(size) && p_size < size)
 +              __write_overflow();
 +      if (p_size < size)
 +              fortify_panic(__func__);
 +      return __builtin_memset(p, c, size);
 +}
 +
 +__FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      size_t q_size = __builtin_object_size(q, 0);
 +      if (__builtin_constant_p(size)) {
 +              if (p_size < size)
 +                      __write_overflow();
 +              if (q_size < size)
 +                      __read_overflow2();
 +      }
 +      if (p_size < size || q_size < size)
 +              fortify_panic(__func__);
 +      return __builtin_memcpy(p, q, size);
 +}
 +
 +__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      size_t q_size = __builtin_object_size(q, 0);
 +      if (__builtin_constant_p(size)) {
 +              if (p_size < size)
 +                      __write_overflow();
 +              if (q_size < size)
 +                      __read_overflow2();
 +      }
 +      if (p_size < size || q_size < size)
 +              fortify_panic(__func__);
 +      return __builtin_memmove(p, q, size);
 +}
 +
 +extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
 +__FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (__builtin_constant_p(size) && p_size < size)
 +              __read_overflow();
 +      if (p_size < size)
 +              fortify_panic(__func__);
 +      return __real_memscan(p, c, size);
 +}
 +
 +__FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      size_t q_size = __builtin_object_size(q, 0);
 +      if (__builtin_constant_p(size)) {
 +              if (p_size < size)
 +                      __read_overflow();
 +              if (q_size < size)
 +                      __read_overflow2();
 +      }
 +      if (p_size < size || q_size < size)
 +              fortify_panic(__func__);
 +      return __builtin_memcmp(p, q, size);
 +}
 +
 +__FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (__builtin_constant_p(size) && p_size < size)
 +              __read_overflow();
 +      if (p_size < size)
 +              fortify_panic(__func__);
 +      return __builtin_memchr(p, c, size);
 +}
 +
 +void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
 +__FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (__builtin_constant_p(size) && p_size < size)
 +              __read_overflow();
 +      if (p_size < size)
 +              fortify_panic(__func__);
 +      return __real_memchr_inv(p, c, size);
 +}
 +
 +extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
 +__FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      if (__builtin_constant_p(size) && p_size < size)
 +              __read_overflow();
 +      if (p_size < size)
 +              fortify_panic(__func__);
 +      return __real_kmemdup(p, size, gfp);
 +}
 +
 +/* defined after fortified strlen and memcpy to reuse them */
 +__FORTIFY_INLINE char *strcpy(char *p, const char *q)
 +{
 +      size_t p_size = __builtin_object_size(p, 0);
 +      size_t q_size = __builtin_object_size(q, 0);
 +      if (p_size == (size_t)-1 && q_size == (size_t)-1)
 +              return __builtin_strcpy(p, q);
 +      memcpy(p, q, strlen(q) + 1);
 +      return p;
 +}
 +
 +#endif
 +
  #endif /* _LINUX_STRING_H_ */
diff --combined mm/util.c
index ee250e2cde344ef586a65661f8c51271cfe6e648,21ddf90f883d9fe8cf4c3d6f993100a4ca1559fd..7b07ec852e01fa931b2b302e8df5cff9f17f62d6
+++ b/mm/util.c
@@@ -83,6 -83,8 +83,8 @@@ EXPORT_SYMBOL(kstrdup_const)
   * @s: the string to duplicate
   * @max: read at most @max chars from @s
   * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+  *
+  * Note: Use kmemdup_nul() instead if the size is known exactly.
   */
  char *kstrndup(const char *s, size_t max, gfp_t gfp)
  {
@@@ -120,6 -122,28 +122,28 @@@ void *kmemdup(const void *src, size_t l
  }
  EXPORT_SYMBOL(kmemdup);
  
+ /**
+  * kmemdup_nul - Create a NUL-terminated string from unterminated data
+  * @s: The data to stringify
+  * @len: The size of the data
+  * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+  */
+ char *kmemdup_nul(const char *s, size_t len, gfp_t gfp)
+ {
+       char *buf;
+       if (!s)
+               return NULL;
+       buf = kmalloc_track_caller(len + 1, gfp);
+       if (buf) {
+               memcpy(buf, s, len);
+               buf[len] = '\0';
+       }
+       return buf;
+ }
+ EXPORT_SYMBOL(kmemdup_nul);
  /**
   * memdup_user - duplicate memory region from user space
   *
@@@ -339,9 -363,9 +363,9 @@@ EXPORT_SYMBOL(vm_mmap)
   * Uses kmalloc to get the memory but if the allocation fails then falls back
   * to the vmalloc allocator. Use kvfree for freeing the memory.
   *
 - * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT
 - * is supported only for large (>32kB) allocations, and it should be used only if
 - * kmalloc is preferable to the vmalloc fallback, due to visible performance drawbacks.
 + * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported.
 + * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is
 + * preferable to the vmalloc fallback, due to visible performance drawbacks.
   *
   * Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people.
   */
@@@ -366,7 -390,13 +390,7 @@@ void *kvmalloc_node(size_t size, gfp_t 
        if (size > PAGE_SIZE) {
                kmalloc_flags |= __GFP_NOWARN;
  
 -              /*
 -               * We have to override __GFP_REPEAT by __GFP_NORETRY for !costly
 -               * requests because there is no other way to tell the allocator
 -               * that we want to fail rather than retry endlessly.
 -               */
 -              if (!(kmalloc_flags & __GFP_REPEAT) ||
 -                              (size <= PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER))
 +              if (!(kmalloc_flags & __GFP_RETRY_MAYFAIL))
                        kmalloc_flags |= __GFP_NORETRY;
        }
  
diff --combined net/9p/trans_fd.c
index dca3cdd1a014bf1fd070dae5449e594cea38d18b,f2e0eaf58018efd8e7c7e461491af56e1739a77f..ddfa86648f957de9eef3d45d8815eb4154b0a7bc
@@@ -41,6 -41,7 +41,7 @@@
  #include <linux/file.h>
  #include <linux/parser.h>
  #include <linux/slab.h>
+ #include <linux/seq_file.h>
  #include <net/9p/9p.h>
  #include <net/9p/client.h>
  #include <net/9p/transport.h>
@@@ -51,6 -52,9 +52,9 @@@
  #define MAX_SOCK_BUF (64*1024)
  #define MAXPOLLWADDR  2
  
+ static struct p9_trans_module p9_tcp_trans;
+ static struct p9_trans_module p9_fd_trans;
  /**
   * struct p9_fd_opts - per-transport options
   * @rfd: file descriptor for reading (trans=fd)
@@@ -63,7 -67,7 +67,7 @@@ struct p9_fd_opts 
        int rfd;
        int wfd;
        u16 port;
-       int privport;
+       bool privport;
  };
  
  /*
@@@ -95,7 -99,7 +99,7 @@@ enum 
  
  struct p9_poll_wait {
        struct p9_conn *conn;
 -      wait_queue_t wait;
 +      wait_queue_entry_t wait;
        wait_queue_head_t *wait_addr;
  };
  
@@@ -522,7 -526,7 +526,7 @@@ error
        clear_bit(Wworksched, &m->wsched);
  }
  
 -static int p9_pollwake(wait_queue_t *wait, unsigned int mode, int sync, void *key)
 +static int p9_pollwake(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
  {
        struct p9_poll_wait *pwait =
                container_of(wait, struct p9_poll_wait, wait);
@@@ -720,6 -724,20 +724,20 @@@ static int p9_fd_cancelled(struct p9_cl
        return 0;
  }
  
+ static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt)
+ {
+       if (clnt->trans_mod == &p9_tcp_trans) {
+               if (clnt->trans_opts.tcp.port != P9_PORT)
+                       seq_printf(m, "port=%u", clnt->trans_opts.tcp.port);
+       } else if (clnt->trans_mod == &p9_fd_trans) {
+               if (clnt->trans_opts.fd.rfd != ~0)
+                       seq_printf(m, "rfd=%u", clnt->trans_opts.fd.rfd);
+               if (clnt->trans_opts.fd.wfd != ~0)
+                       seq_printf(m, "wfd=%u", clnt->trans_opts.fd.wfd);
+       }
+       return 0;
+ }
  /**
   * parse_opts - parse mount options into p9_fd_opts structure
   * @params: options string passed from mount
@@@ -738,7 -756,7 +756,7 @@@ static int parse_opts(char *params, str
        opts->port = P9_PORT;
        opts->rfd = ~0;
        opts->wfd = ~0;
-       opts->privport = 0;
+       opts->privport = false;
  
        if (!params)
                return 0;
                        opts->wfd = option;
                        break;
                case Opt_privport:
-                       opts->privport = 1;
+                       opts->privport = true;
                        break;
                default:
                        continue;
@@@ -942,6 -960,8 +960,8 @@@ p9_fd_create_tcp(struct p9_client *clie
  
        csocket = NULL;
  
+       client->trans_opts.tcp.port = opts.port;
+       client->trans_opts.tcp.privport = opts.privport;
        sin_server.sin_family = AF_INET;
        sin_server.sin_addr.s_addr = in_aton(addr);
        sin_server.sin_port = htons(opts.port);
@@@ -1020,6 -1040,8 +1040,8 @@@ p9_fd_create(struct p9_client *client, 
        struct p9_fd_opts opts;
  
        parse_opts(args, &opts);
+       client->trans_opts.fd.rfd = opts.rfd;
+       client->trans_opts.fd.wfd = opts.wfd;
  
        if (opts.rfd == ~0 || opts.wfd == ~0) {
                pr_err("Insufficient options for proto=fd\n");
@@@ -1044,6 -1066,7 +1066,7 @@@ static struct p9_trans_module p9_tcp_tr
        .request = p9_fd_request,
        .cancel = p9_fd_cancel,
        .cancelled = p9_fd_cancelled,
+       .show_options = p9_fd_show_options,
        .owner = THIS_MODULE,
  };
  
@@@ -1056,6 -1079,7 +1079,7 @@@ static struct p9_trans_module p9_unix_t
        .request = p9_fd_request,
        .cancel = p9_fd_cancel,
        .cancelled = p9_fd_cancelled,
+       .show_options = p9_fd_show_options,
        .owner = THIS_MODULE,
  };
  
@@@ -1068,6 -1092,7 +1092,7 @@@ static struct p9_trans_module p9_fd_tra
        .request = p9_fd_request,
        .cancel = p9_fd_cancel,
        .cancelled = p9_fd_cancelled,
+       .show_options = p9_fd_show_options,
        .owner = THIS_MODULE,
  };