Merge branch 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 Jul 2021 18:41:14 +0000 (11:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 Jul 2021 18:41:14 +0000 (11:41 -0700)
Pull vfs name lookup updates from Al Viro:
 "Small namei.c patch series, mostly to simplify the rules for nameidata
  state. It's actually from the previous cycle - but I didn't post it
  for review in time...

  Changes visible outside of fs/namei.c: file_open_root() calling
  conventions change, some freed bits in LOOKUP_... space"

* 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  namei: make sure nd->depth is always valid
  teach set_nameidata() to handle setting the root as well
  take LOOKUP_{ROOT,ROOT_GRABBED,JUMPED} out of LOOKUP_... space
  switch file_open_root() to struct path

1  2 
Documentation/filesystems/path-lookup.rst
Documentation/filesystems/porting.rst
arch/um/drivers/mconsole_kern.c
fs/coredump.c
fs/namei.c
fs/nfs/nfstrace.h
fs/open.c
fs/proc/proc_sysctl.c
include/linux/fs.h
kernel/usermode_driver.c

@@@ -448,17 -448,15 +448,17 @@@ described.  If it finds a ``LAST_NORM`
  filesystem to revalidate the result if it is that sort of filesystem.
  If that doesn't get a good result, it calls "``lookup_slow()``" which
  takes ``i_rwsem``, rechecks the cache, and then asks the filesystem
 -to find a definitive answer.  Each of these will call
 -``follow_managed()`` (as described below) to handle any mount points.
 -
 -In the absence of symbolic links, ``walk_component()`` creates a new
 -``struct path`` containing a counted reference to the new dentry and a
 -reference to the new ``vfsmount`` which is only counted if it is
 -different from the previous ``vfsmount``.  It then calls
 -``path_to_nameidata()`` to install the new ``struct path`` in the
 -``struct nameidata`` and drop the unneeded references.
 +to find a definitive answer.
 +
 +As the last step of walk_component(), step_into() will be called either
 +directly from walk_component() or from handle_dots().  It calls
 +handle_mounts(), to check and handle mount points, in which a new
 +``struct path`` is created containing a counted reference to the new dentry and
 +a reference to the new ``vfsmount`` which is only counted if it is
 +different from the previous ``vfsmount``. Then if there is
 +a symbolic link, step_into() calls pick_link() to deal with it,
 +otherwise it installs the new ``struct path`` in the ``struct nameidata``, and
 +drops the unneeded references.
  
  This "hand-over-hand" sequencing of getting a reference to the new
  dentry before dropping the reference to the previous dentry may
@@@ -472,8 -470,8 +472,8 @@@ Handling the final componen
  ``nd->last_type`` to refer to the final component of the path.  It does
  not call ``walk_component()`` that last time.  Handling that final
  component remains for the caller to sort out. Those callers are
 -``path_lookupat()``, ``path_parentat()``, ``path_mountpoint()`` and
 -``path_openat()`` each of which handles the differing requirements of
 +path_lookupat(), path_parentat() and
 +path_openat() each of which handles the differing requirements of
  different system calls.
  
  ``path_parentat()`` is clearly the simplest - it just wraps a little bit
@@@ -488,18 -486,20 +488,18 @@@ perform their operation
  object is wanted such as by ``stat()`` or ``chmod()``.  It essentially just
  calls ``walk_component()`` on the final component through a call to
  ``lookup_last()``.  ``path_lookupat()`` returns just the final dentry.
 -
 -``path_mountpoint()`` handles the special case of unmounting which must
 -not try to revalidate the mounted filesystem.  It effectively
 -contains, through a call to ``mountpoint_last()``, an alternate
 -implementation of ``lookup_slow()`` which skips that step.  This is
 -important when unmounting a filesystem that is inaccessible, such as
 +It is worth noting that when flag ``LOOKUP_MOUNTPOINT`` is set,
 +path_lookupat() will unset LOOKUP_JUMPED in nameidata so that in the
 +subsequent path traversal d_weak_revalidate() won't be called.
 +This is important when unmounting a filesystem that is inaccessible, such as
  one provided by a dead NFS server.
  
  Finally ``path_openat()`` is used for the ``open()`` system call; it
 -contains, in support functions starting with "``do_last()``", all the
 +contains, in support functions starting with "open_last_lookups()", all the
  complexity needed to handle the different subtleties of O_CREAT (with
  or without O_EXCL), final "``/``" characters, and trailing symbolic
  links.  We will revisit this in the final part of this series, which
 -focuses on those symbolic links.  "``do_last()``" will sometimes, but
 +focuses on those symbolic links.  "open_last_lookups()" will sometimes, but
  not always, take ``i_rwsem``, depending on what it finds.
  
  Each of these, or the functions which call them, need to be alert to
@@@ -535,7 -535,8 +535,7 @@@ covered in greater detail in autofs.tx
  tree, but a few notes specifically related to path lookup are in order
  here.
  
 -The Linux VFS has a concept of "managed" dentries which is reflected
 -in function names such as "``follow_managed()``".  There are three
 +The Linux VFS has a concept of "managed" dentries.  There are three
  potentially interesting things about these dentries corresponding
  to three different flags that might be set in ``dentry->d_flags``:
  
@@@ -651,10 -652,10 +651,10 @@@ RCU-walk finds it cannot stop gracefull
  restarts from the top with REF-walk.
  
  This pattern of "try RCU-walk, if that fails try REF-walk" can be
 -clearly seen in functions like ``filename_lookup()``,
 -``filename_parentat()``, ``filename_mountpoint()``,
 -``do_filp_open()``, and ``do_file_open_root()``.  These five
 -correspond roughly to the four ``path_*()`` functions we met earlier,
 +clearly seen in functions like filename_lookup(),
 +filename_parentat(),
 +do_filp_open(), and do_file_open_root().  These four
 +correspond roughly to the three ``path_*()`` functions we met earlier,
  each of which calls ``link_path_walk()``.  The ``path_*()`` functions are
  called using different mode flags until a mode is found which works.
  They are first called with ``LOOKUP_RCU`` set to request "RCU-walk".  If
@@@ -992,8 -993,8 +992,8 @@@ is 4096.  There are a number of reason
  kernel spend too much time on just one path is one of them.  With
  symbolic links you can effectively generate much longer paths so some
  sort of limit is needed for the same reason.  Linux imposes a limit of
 -at most 40 symlinks in any one path lookup.  It previously imposed a
 -further limit of eight on the maximum depth of recursion, but that was
 +at most 40 (MAXSYMLINKS) symlinks in any one path lookup.  It previously imposed
 +further limit of eight on the maximum depth of recursion, but that was
  raised to 40 when a separate stack was implemented, so there is now
  just the one limit.
  
@@@ -1060,26 -1061,42 +1060,26 @@@ filesystem cannot successfully get a re
  must return ``-ECHILD`` and ``unlazy_walk()`` will be called to return to
  REF-walk mode in which the filesystem is allowed to sleep.
  
 -The place for all this to happen is the ``i_op->follow_link()`` inode
 -method.  In the present mainline code this is never actually called in
 -RCU-walk mode as the rewrite is not quite complete.  It is likely that
 -in a future release this method will be passed an ``inode`` pointer when
 -called in RCU-walk mode so it both (1) knows to be careful, and (2) has the
 -validated pointer.  Much like the ``i_op->permission()`` method we
 -looked at previously, ``->follow_link()`` would need to be careful that
 +The place for all this to happen is the ``i_op->get_link()`` inode
 +method. This is called both in RCU-walk and REF-walk. In RCU-walk the
 +``dentry*`` argument is NULL, ``->get_link()`` can return -ECHILD to drop out of
 +RCU-walk.  Much like the ``i_op->permission()`` method we
 +looked at previously, ``->get_link()`` would need to be careful that
  all the data structures it references are safe to be accessed while
 -holding no counted reference, only the RCU lock.  Though getting a
 -reference with ``->follow_link()`` is not yet done in RCU-walk mode, the
 -code is ready to release the reference when that does happen.
 -
 -This need to drop the reference to a symlink adds significant
 -complexity.  It requires a reference to the inode so that the
 -``i_op->put_link()`` inode operation can be called.  In REF-walk, that
 -reference is kept implicitly through a reference to the dentry, so
 -keeping the ``struct path`` of the symlink is easiest.  For RCU-walk,
 -the pointer to the inode is kept separately.  To allow switching from
 -RCU-walk back to REF-walk in the middle of processing nested symlinks
 -we also need the seq number for the dentry so we can confirm that
 -switching back was safe.
 -
 -Finally, when providing a reference to a symlink, the filesystem also
 -provides an opaque "cookie" that must be passed to ``->put_link()`` so that it
 -knows what to free.  This might be the allocated memory area, or a
 -pointer to the ``struct page`` in the page cache, or something else
 -completely.  Only the filesystem knows what it is.
 +holding no counted reference, only the RCU lock. A callback
 +``struct delayed_called`` will be passed to ``->get_link()``:
 +file systems can set their own put_link function and argument through
 +set_delayed_call(). Later on, when VFS wants to put link, it will call
 +do_delayed_call() to invoke that callback function with the argument.
  
  In order for the reference to each symlink to be dropped when the walk completes,
  whether in RCU-walk or REF-walk, the symlink stack needs to contain,
  along with the path remnants:
  
 -- the ``struct path`` to provide a reference to the inode in REF-walk
 -- the ``struct inode *`` to provide a reference to the inode in RCU-walk
 +- the ``struct path`` to provide a reference to the previous path
 +- the ``const char *`` to provide a reference to the to previous name
  - the ``seq`` to allow the path to be safely switched from RCU-walk to REF-walk
 -- the ``cookie`` that tells ``->put_path()`` what to put.
 +- the ``struct delayed_call`` for later invocation.
  
  This means that each entry in the symlink stack needs to hold five
  pointers and an integer instead of just one pointer (the path
@@@ -1103,10 -1120,12 +1103,10 @@@ doesn't need to notice.  Getting this `
  stack is very straightforward; pushing and popping the references is
  a little more complex.
  
 -When a symlink is found, ``walk_component()`` returns the value ``1``
 -(``0`` is returned for any other sort of success, and a negative number
 -is, as usual, an error indicator).  This causes ``get_link()`` to be
 -called; it then gets the link from the filesystem.  Providing that
 -operation is successful, the old path ``name`` is placed on the stack,
 -and the new value is used as the ``name`` for a while.  When the end of
 +When a symlink is found, walk_component() calls pick_link() via step_into()
 +which returns the link from the filesystem.
 +Providing that operation is successful, the old path ``name`` is placed on the
 +stack, and the new value is used as the ``name`` for a while.  When the end of
  the path is found (i.e. ``*name`` is ``'\0'``) the old ``name`` is restored
  off the stack and path walking continues.
  
@@@ -1123,23 -1142,23 +1123,23 @@@ stack in ``walk_component()`` immediate
  old symlink as it walks that last component.  So it is quite
  convenient for ``walk_component()`` to release the old symlink and pop
  the references just before pushing the reference information for the
 -new symlink.  It is guided in this by two flags; ``WALK_GET``, which
 -gives it permission to follow a symlink if it finds one, and
 -``WALK_PUT``, which tells it to release the current symlink after it has been
 -followed.  ``WALK_PUT`` is tested first, leading to a call to
 -``put_link()``.  ``WALK_GET`` is tested subsequently (by
 -``should_follow_link()``) leading to a call to ``pick_link()`` which sets
 -up the stack frame.
 +new symlink.  It is guided in this by three flags: ``WALK_NOFOLLOW`` which
 +forbids it from following a symlink if it finds one, ``WALK_MORE``
 +which indicates that it is yet too early to release the
 +current symlink, and ``WALK_TRAILING`` which indicates that it is on the final
 +component of the lookup, so we will check userspace flag ``LOOKUP_FOLLOW`` to
 +decide whether follow it when it is a symlink and call ``may_follow_link()`` to
 +check if we have privilege to follow it.
  
  Symlinks with no final component
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  A pair of special-case symlinks deserve a little further explanation.
  Both result in a new ``struct path`` (with mount and dentry) being set
 -up in the ``nameidata``, and result in ``get_link()`` returning ``NULL``.
 +up in the ``nameidata``, and result in pick_link() returning ``NULL``.
  
  The more obvious case is a symlink to "``/``".  All symlinks starting
 -with "``/``" are detected in ``get_link()`` which resets the ``nameidata``
 +with "``/``" are detected in pick_link() which resets the ``nameidata``
  to point to the effective filesystem root.  If the symlink only
  contains "``/``" then there is nothing more to do, no components at all,
  so ``NULL`` is returned to indicate that the symlink can be released and
@@@ -1156,11 -1175,12 +1156,11 @@@ something that looks like a symlink.  I
  target file, not just the name of it.  When you ``readlink`` these
  objects you get a name that might refer to the same file - unless it
  has been unlinked or mounted over.  When ``walk_component()`` follows
 -one of these, the ``->follow_link()`` method in "procfs" doesn't return
 -a string name, but instead calls ``nd_jump_link()`` which updates the
 -``nameidata`` in place to point to that target.  ``->follow_link()`` then
 -returns ``NULL``.  Again there is no final component and ``get_link()``
 -reports this by leaving the ``last_type`` field of ``nameidata`` as
 -``LAST_BIND``.
 +one of these, the ``->get_link()`` method in "procfs" doesn't return
 +a string name, but instead calls nd_jump_link() which updates the
 +``nameidata`` in place to point to that target.  ``->get_link()`` then
 +returns ``NULL``.  Again there is no final component and pick_link()
 +returns ``NULL``.
  
  Following the symlink in the final component
  --------------------------------------------
@@@ -1177,38 -1197,42 +1177,38 @@@ potentially need to call ``link_path_wa
  successive symlinks until one is found that doesn't point to another
  symlink.
  
 -This case is handled by the relevant caller of ``link_path_walk()``, such as
 -``path_lookupat()`` using a loop that calls ``link_path_walk()``, and then
 -handles the final component.  If the final component is a symlink
 -that needs to be followed, then ``trailing_symlink()`` is called to set
 -things up properly and the loop repeats, calling ``link_path_walk()``
 -again.  This could loop as many as 40 times if the last component of
 -each symlink is another symlink.
 -
 -The various functions that examine the final component and possibly
 -report that it is a symlink are ``lookup_last()``, ``mountpoint_last()``
 -and ``do_last()``, each of which use the same convention as
 -``walk_component()`` of returning ``1`` if a symlink was found that needs
 -to be followed.
 -
 -Of these, ``do_last()`` is the most interesting as it is used for
 -opening a file.  Part of ``do_last()`` runs with ``i_rwsem`` held and this
 -part is in a separate function: ``lookup_open()``.
 -
 -Explaining ``do_last()`` completely is beyond the scope of this article,
 -but a few highlights should help those interested in exploring the
 -code.
 -
 -1. Rather than just finding the target file, ``do_last()`` needs to open
 +This case is handled by relevant callers of link_path_walk(), such as
 +path_lookupat(), path_openat() using a loop that calls link_path_walk(),
 +and then handles the final component by calling open_last_lookups() or
 +lookup_last(). If it is a symlink that needs to be followed,
 +open_last_lookups() or lookup_last() will set things up properly and
 +return the path so that the loop repeats, calling
 +link_path_walk() again.  This could loop as many as 40 times if the last
 +component of each symlink is another symlink.
 +
 +Of the various functions that examine the final component, 
 +open_last_lookups() is the most interesting as it works in tandem
 +with do_open() for opening a file.  Part of open_last_lookups() runs
 +with ``i_rwsem`` held and this part is in a separate function: lookup_open().
 +
 +Explaining open_last_lookups() and do_open() completely is beyond the scope
 +of this article, but a few highlights should help those interested in exploring
 +the code.
 +
 +1. Rather than just finding the target file, do_open() is used after
 +   open_last_lookup() to open
     it.  If the file was found in the dcache, then ``vfs_open()`` is used for
     this.  If not, then ``lookup_open()`` will either call ``atomic_open()`` (if
     the filesystem provides it) to combine the final lookup with the open, or
 -   will perform the separate ``lookup_real()`` and ``vfs_create()`` steps
 +   will perform the separate ``i_op->lookup()`` and ``i_op->create()`` steps
     directly.  In the later case the actual "open" of this newly found or
 -   created file will be performed by ``vfs_open()``, just as if the name
 +   created file will be performed by vfs_open(), just as if the name
     were found in the dcache.
  
 -2. ``vfs_open()`` can fail with ``-EOPENSTALE`` if the cached information
 -   wasn't quite current enough.  Rather than restarting the lookup from
 -   the top with ``LOOKUP_REVAL`` set, ``lookup_open()`` is called instead,
 -   giving the filesystem a chance to resolve small inconsistencies.
 -   If that doesn't work, only then is the lookup restarted from the top.
 +2. vfs_open() can fail with ``-EOPENSTALE`` if the cached information
 +   wasn't quite current enough.  If it's in RCU-walk ``-ECHILD`` will be returned
 +   otherwise ``-ESTALE`` is returned.  When ``-ESTALE`` is returned, the caller may
 +   retry with ``LOOKUP_REVAL`` flag set.
  
  3. An open with O_CREAT **does** follow a symlink in the final component,
     unlike other creation system calls (like ``mkdir``).  So the sequence::
  
     will create a file called ``/tmp/bar``.  This is not permitted if
     ``O_EXCL`` is set but otherwise is handled for an O_CREAT open much
 -   like for a non-creating open: ``should_follow_link()`` returns ``1``, and
 -   so does ``do_last()`` so that ``trailing_symlink()`` gets called and the
 +   like for a non-creating open: lookup_last() or open_last_lookup()
 +   returns a non ``NULL`` value, and link_path_walk() gets called and the
     open process continues on the symlink that was found.
  
  Updating the access time
@@@ -1297,18 -1321,18 +1297,18 @@@ to lookup: RCU-walk, REF-walk, and REF-
  yet.  This is primarily used to tell the audit subsystem the full
  context of a particular access being audited.
  
- ``LOOKUP_ROOT`` indicates that the ``root`` field in the ``nameidata`` was
+ ``ND_ROOT_PRESET`` indicates that the ``root`` field in the ``nameidata`` was
  provided by the caller, so it shouldn't be released when it is no
  longer needed.
  
- ``LOOKUP_JUMPED`` means that the current dentry was chosen not because
+ ``ND_JUMPED`` means that the current dentry was chosen not because
  it had the right name but for some other reason.  This happens when
  following "``..``", following a symlink to ``/``, crossing a mount point
  or accessing a "``/proc/$PID/fd/$FD``" symlink (also known as a "magic
  link"). In this case the filesystem has not been asked to revalidate the
  name (with ``d_revalidate()``).  In such cases the inode may still need
  to be revalidated, so ``d_op->d_weak_revalidate()`` is called if
- ``LOOKUP_JUMPED`` is set when the look completes - which may be at the
+ ``ND_JUMPED`` is set when the look completes - which may be at the
  final component or, when creating, unlinking, or renaming, at the penultimate component.
  
  Resolution-restriction flags
@@@ -895,7 -895,7 +895,16 @@@ whereas previously it could be paired w
  
  **mandatory**
  
 +iov_iter_copy_from_user_atomic() is gone; use copy_page_from_iter_atomic().
 +The difference is copy_page_from_iter_atomic() advances the iterator and
 +you don't need iov_iter_advance() after it.  However, if you decide to use
 +only a part of obtained data, you should do iov_iter_revert().
++
++---
++
++**mandatory**
++
+ Calling conventions for file_open_root() changed; now it takes struct path *
+ instead of passing mount and dentry separately.  For callers that used to
+ pass <mnt, mnt->mnt_root> pair (i.e. the root of given mount), a new helper
+ is provided - file_open_root_mnt().  In-tree users adjusted.
@@@ -12,7 -12,6 +12,7 @@@
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <linux/notifier.h>
 +#include <linux/panic_notifier.h>
  #include <linux/reboot.h>
  #include <linux/sched/debug.h>
  #include <linux/proc_fs.h>
@@@ -141,7 -140,7 +141,7 @@@ void mconsole_proc(struct mc_request *r
                mconsole_reply(req, "Proc not available", 1, 0);
                goto out;
        }
-       file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0);
+       file = file_open_root_mnt(mnt, ptr, O_RDONLY, 0);
        if (IS_ERR(file)) {
                mconsole_reply(req, "Failed to open file", 1, 0);
                printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
diff --combined fs/coredump.c
@@@ -519,7 -519,7 +519,7 @@@ static bool dump_interrupted(void
         * but then we need to teach dump_write() to restart and clear
         * TIF_SIGPENDING.
         */
 -      return signal_pending(current);
 +      return fatal_signal_pending(current) || freezing(current);
  }
  
  static void wait_for_dump_helpers(struct file *file)
@@@ -755,8 -755,8 +755,8 @@@ void do_coredump(const kernel_siginfo_
                        task_lock(&init_task);
                        get_fs_root(init_task.fs, &root);
                        task_unlock(&init_task);
-                       cprm.file = file_open_root(root.dentry, root.mnt,
-                               cn.corename, open_flags, 0600);
+                       cprm.file = file_open_root(&root, cn.corename,
+                                                  open_flags, 0600);
                        path_put(&root);
                } else {
                        cprm.file = filp_open(cn.corename, open_flags, 0600);
                }
                file_start_write(cprm.file);
                core_dumped = binfmt->core_dump(&cprm);
 +              /*
 +               * Ensures that file size is big enough to contain the current
 +               * file postion. This prevents gdb from complaining about
 +               * a truncated file if the last "write" to the file was
 +               * dump_skip.
 +               */
 +              if (cprm.to_skip) {
 +                      cprm.to_skip--;
 +                      dump_emit(&cprm, "", 1);
 +              }
                file_end_write(cprm.file);
        }
        if (ispipe && core_pipe_limit)
@@@ -845,7 -835,7 +845,7 @@@ fail
   * do on a core-file: use only these functions to write out all the
   * necessary info.
   */
 -int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
 +static int __dump_emit(struct coredump_params *cprm, const void *addr, int nr)
  {
        struct file *file = cprm->file;
        loff_t pos = file->f_pos;
  
        return 1;
  }
 -EXPORT_SYMBOL(dump_emit);
  
 -int dump_skip(struct coredump_params *cprm, size_t nr)
 +static int __dump_skip(struct coredump_params *cprm, size_t nr)
  {
        static char zeroes[PAGE_SIZE];
        struct file *file = cprm->file;
                return 1;
        } else {
                while (nr > PAGE_SIZE) {
 -                      if (!dump_emit(cprm, zeroes, PAGE_SIZE))
 +                      if (!__dump_emit(cprm, zeroes, PAGE_SIZE))
                                return 0;
                        nr -= PAGE_SIZE;
                }
 -              return dump_emit(cprm, zeroes, nr);
 +              return __dump_emit(cprm, zeroes, nr);
        }
  }
 +
 +int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
 +{
 +      if (cprm->to_skip) {
 +              if (!__dump_skip(cprm, cprm->to_skip))
 +                      return 0;
 +              cprm->to_skip = 0;
 +      }
 +      return __dump_emit(cprm, addr, nr);
 +}
 +EXPORT_SYMBOL(dump_emit);
 +
 +void dump_skip_to(struct coredump_params *cprm, unsigned long pos)
 +{
 +      cprm->to_skip = pos - cprm->pos;
 +}
 +EXPORT_SYMBOL(dump_skip_to);
 +
 +void dump_skip(struct coredump_params *cprm, size_t nr)
 +{
 +      cprm->to_skip += nr;
 +}
  EXPORT_SYMBOL(dump_skip);
  
  #ifdef CONFIG_ELF_CORE
@@@ -933,11 -902,11 +933,11 @@@ int dump_user_range(struct coredump_par
                        stop = !dump_emit(cprm, kaddr, PAGE_SIZE);
                        kunmap_local(kaddr);
                        put_page(page);
 +                      if (stop)
 +                              return 0;
                } else {
 -                      stop = !dump_skip(cprm, PAGE_SIZE);
 +                      dump_skip(cprm, PAGE_SIZE);
                }
 -              if (stop)
 -                      return 0;
        }
        return 1;
  }
  
  int dump_align(struct coredump_params *cprm, int align)
  {
 -      unsigned mod = cprm->pos & (align - 1);
 +      unsigned mod = (cprm->pos + cprm->to_skip) & (align - 1);
        if (align & (align - 1))
                return 0;
 -      return mod ? dump_skip(cprm, align - mod) : 1;
 +      if (mod)
 +              cprm->to_skip += align - mod;
 +      return 1;
  }
  EXPORT_SYMBOL(dump_align);
  
  /*
 - * Ensures that file size is big enough to contain the current file
 - * postion. This prevents gdb from complaining about a truncated file
 - * if the last "write" to the file was dump_skip.
 - */
 -void dump_truncate(struct coredump_params *cprm)
 -{
 -      struct file *file = cprm->file;
 -      loff_t offset;
 -
 -      if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
 -              offset = file->f_op->llseek(file, 0, SEEK_CUR);
 -              if (i_size_read(file->f_mapping->host) < offset)
 -                      do_truncate(file_mnt_user_ns(file), file->f_path.dentry,
 -                                  offset, 0, file);
 -      }
 -}
 -EXPORT_SYMBOL(dump_truncate);
 -
 -/*
   * The purpose of always_dump_vma() is to make sure that special kernel mappings
   * that are useful for post-mortem analysis are included in every core dump.
   * In that way we ensure that the core dump is fully interpretable later
diff --combined fs/namei.c
@@@ -554,7 -554,7 +554,7 @@@ struct nameidata 
        struct qstr     last;
        struct path     root;
        struct inode    *inode; /* path.dentry.d_inode */
-       unsigned int    flags;
+       unsigned int    flags, state;
        unsigned        seq, m_seq, r_seq;
        int             last_type;
        unsigned        depth;
        umode_t         dir_mode;
  } __randomize_layout;
  
- static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
+ #define ND_ROOT_PRESET 1
+ #define ND_ROOT_GRABBED 2
+ #define ND_JUMPED 4
+ static void __set_nameidata(struct nameidata *p, int dfd, struct filename *name)
  {
        struct nameidata *old = current->nameidata;
        p->stack = p->internal;
+       p->depth = 0;
        p->dfd = dfd;
        p->name = name;
        p->path.mnt = NULL;
        current->nameidata = p;
  }
  
+ static inline void set_nameidata(struct nameidata *p, int dfd, struct filename *name,
+                         const struct path *root)
+ {
+       __set_nameidata(p, dfd, name);
+       p->state = 0;
+       if (unlikely(root)) {
+               p->state = ND_ROOT_PRESET;
+               p->root = *root;
+       }
+ }
  static void restore_nameidata(void)
  {
        struct nameidata *now = current->nameidata, *old = now->saved;
@@@ -645,9 -661,9 +661,9 @@@ static void terminate_walk(struct namei
                path_put(&nd->path);
                for (i = 0; i < nd->depth; i++)
                        path_put(&nd->stack[i].link);
-               if (nd->flags & LOOKUP_ROOT_GRABBED) {
+               if (nd->state & ND_ROOT_GRABBED) {
                        path_put(&nd->root);
-                       nd->flags &= ~LOOKUP_ROOT_GRABBED;
+                       nd->state &= ~ND_ROOT_GRABBED;
                }
        } else {
                nd->flags &= ~LOOKUP_RCU;
@@@ -710,9 -726,9 +726,9 @@@ static bool legitimize_root(struct name
        if (!nd->root.mnt && (nd->flags & LOOKUP_IS_SCOPED))
                return false;
        /* Nothing to do if nd->root is zero or is managed by the VFS user. */
-       if (!nd->root.mnt || (nd->flags & LOOKUP_ROOT))
+       if (!nd->root.mnt || (nd->state & ND_ROOT_PRESET))
                return true;
-       nd->flags |= LOOKUP_ROOT_GRABBED;
+       nd->state |= ND_ROOT_GRABBED;
        return legitimize_path(nd, &nd->root, nd->root_seq);
  }
  
@@@ -849,8 -865,9 +865,9 @@@ static int complete_walk(struct nameida
                 * We don't want to zero nd->root for scoped-lookups or
                 * externally-managed nd->root.
                 */
-               if (!(nd->flags & (LOOKUP_ROOT | LOOKUP_IS_SCOPED)))
-                       nd->root.mnt = NULL;
+               if (!(nd->state & ND_ROOT_PRESET))
+                       if (!(nd->flags & LOOKUP_IS_SCOPED))
+                               nd->root.mnt = NULL;
                nd->flags &= ~LOOKUP_CACHED;
                if (!try_to_unlazy(nd))
                        return -ECHILD;
                        return -EXDEV;
        }
  
-       if (likely(!(nd->flags & LOOKUP_JUMPED)))
+       if (likely(!(nd->state & ND_JUMPED)))
                return 0;
  
        if (likely(!(dentry->d_flags & DCACHE_OP_WEAK_REVALIDATE)))
@@@ -915,7 -932,7 +932,7 @@@ static int set_root(struct nameidata *n
                } while (read_seqcount_retry(&fs->seq, seq));
        } else {
                get_fs_root(fs, &nd->root);
-               nd->flags |= LOOKUP_ROOT_GRABBED;
+               nd->state |= ND_ROOT_GRABBED;
        }
        return 0;
  }
@@@ -948,7 -965,7 +965,7 @@@ static int nd_jump_root(struct nameidat
                path_get(&nd->path);
                nd->inode = nd->path.dentry->d_inode;
        }
-       nd->flags |= LOOKUP_JUMPED;
+       nd->state |= ND_JUMPED;
        return 0;
  }
  
@@@ -976,7 -993,7 +993,7 @@@ int nd_jump_link(struct path *path
        path_put(&nd->path);
        nd->path = *path;
        nd->inode = nd->path.dentry->d_inode;
-       nd->flags |= LOOKUP_JUMPED;
+       nd->state |= ND_JUMPED;
        return 0;
  
  err:
@@@ -1126,7 -1143,8 +1143,7 @@@ int may_linkat(struct user_namespace *m
   *                      should be allowed, or not, on files that already
   *                      exist.
   * @mnt_userns:       user namespace of the mount the inode was found from
 - * @dir_mode: mode bits of directory
 - * @dir_uid: owner of directory
 + * @nd: nameidata pathwalk data
   * @inode: the inode of the file to open
   *
   * Block an O_CREAT open of a FIFO (or a regular file) when:
@@@ -1423,7 -1441,7 +1440,7 @@@ static bool __follow_mount_rcu(struct n
                        if (mounted) {
                                path->mnt = &mounted->mnt;
                                dentry = path->dentry = mounted->mnt.mnt_root;
-                               nd->flags |= LOOKUP_JUMPED;
+                               nd->state |= ND_JUMPED;
                                *seqp = read_seqcount_begin(&dentry->d_seq);
                                *inode = dentry->d_inode;
                                /*
@@@ -1468,7 -1486,7 +1485,7 @@@ static inline int handle_mounts(struct 
                if (unlikely(nd->flags & LOOKUP_NO_XDEV))
                        ret = -EXDEV;
                else
-                       nd->flags |= LOOKUP_JUMPED;
+                       nd->state |= ND_JUMPED;
        }
        if (unlikely(ret)) {
                dput(path->dentry);
@@@ -2219,7 -2237,7 +2236,7 @@@ static int link_path_walk(const char *n
                        case 2:
                                if (name[1] == '.') {
                                        type = LAST_DOTDOT;
-                                       nd->flags |= LOOKUP_JUMPED;
+                                       nd->state |= ND_JUMPED;
                                }
                                break;
                        case 1:
                }
                if (likely(type == LAST_NORM)) {
                        struct dentry *parent = nd->path.dentry;
-                       nd->flags &= ~LOOKUP_JUMPED;
+                       nd->state &= ~ND_JUMPED;
                        if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
                                struct qstr this = { { .hash_len = hash_len }, .name = name };
                                err = parent->d_op->d_hash(parent, &this);
@@@ -2301,14 -2319,14 +2318,14 @@@ static const char *path_init(struct nam
        if (flags & LOOKUP_RCU)
                rcu_read_lock();
  
-       nd->flags = flags | LOOKUP_JUMPED;
-       nd->depth = 0;
+       nd->flags = flags;
+       nd->state |= ND_JUMPED;
  
        nd->m_seq = __read_seqcount_begin(&mount_lock.seqcount);
        nd->r_seq = __read_seqcount_begin(&rename_lock.seqcount);
        smp_rmb();
  
-       if (flags & LOOKUP_ROOT) {
+       if (nd->state & ND_ROOT_PRESET) {
                struct dentry *root = nd->root.dentry;
                struct inode *inode = root->d_inode;
                if (*s && unlikely(!d_can_lookup(root)))
                        nd->root_seq = nd->seq;
                } else {
                        path_get(&nd->root);
-                       nd->flags |= LOOKUP_ROOT_GRABBED;
+                       nd->state |= ND_ROOT_GRABBED;
                }
        }
        return s;
@@@ -2422,7 -2440,7 +2439,7 @@@ static int path_lookupat(struct nameida
                ;
        if (!err && unlikely(nd->flags & LOOKUP_MOUNTPOINT)) {
                err = handle_lookup_down(nd);
-               nd->flags &= ~LOOKUP_JUMPED; // no d_weak_revalidate(), please...
+               nd->state &= ~ND_JUMPED; // no d_weak_revalidate(), please...
        }
        if (!err)
                err = complete_walk(nd);
@@@ -2446,11 -2464,7 +2463,7 @@@ int filename_lookup(int dfd, struct fil
        struct nameidata nd;
        if (IS_ERR(name))
                return PTR_ERR(name);
-       if (unlikely(root)) {
-               nd.root = *root;
-               flags |= LOOKUP_ROOT;
-       }
-       set_nameidata(&nd, dfd, name);
+       set_nameidata(&nd, dfd, name, root);
        retval = path_lookupat(&nd, flags | LOOKUP_RCU, path);
        if (unlikely(retval == -ECHILD))
                retval = path_lookupat(&nd, flags, path);
@@@ -2491,7 -2505,7 +2504,7 @@@ static struct filename *filename_parent
  
        if (IS_ERR(name))
                return name;
-       set_nameidata(&nd, dfd, name);
+       set_nameidata(&nd, dfd, name, NULL);
        retval = path_parentat(&nd, flags | LOOKUP_RCU, parent);
        if (unlikely(retval == -ECHILD))
                retval = path_parentat(&nd, flags, parent);
@@@ -2824,14 -2838,16 +2837,14 @@@ static int may_delete(struct user_names
  static inline int may_create(struct user_namespace *mnt_userns,
                             struct inode *dir, struct dentry *child)
  {
 -      struct user_namespace *s_user_ns;
        audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
        if (child->d_inode)
                return -EEXIST;
        if (IS_DEADDIR(dir))
                return -ENOENT;
 -      s_user_ns = dir->i_sb->s_user_ns;
 -      if (!kuid_has_mapping(s_user_ns, fsuid_into_mnt(mnt_userns)) ||
 -          !kgid_has_mapping(s_user_ns, fsgid_into_mnt(mnt_userns)))
 +      if (!fsuidgid_has_mapping(dir->i_sb, mnt_userns))
                return -EOVERFLOW;
 +
        return inode_permission(mnt_userns, dir, MAY_WRITE | MAY_EXEC);
  }
  
@@@ -3033,11 -3049,14 +3046,11 @@@ static int may_o_create(struct user_nam
                        const struct path *dir, struct dentry *dentry,
                        umode_t mode)
  {
 -      struct user_namespace *s_user_ns;
        int error = security_path_mknod(dir, dentry, mode, 0);
        if (error)
                return error;
  
 -      s_user_ns = dir->dentry->d_sb->s_user_ns;
 -      if (!kuid_has_mapping(s_user_ns, fsuid_into_mnt(mnt_userns)) ||
 -          !kgid_has_mapping(s_user_ns, fsgid_into_mnt(mnt_userns)))
 +      if (!fsuidgid_has_mapping(dir->dentry->d_sb, mnt_userns))
                return -EOVERFLOW;
  
        error = inode_permission(mnt_userns, dir->dentry->d_inode,
@@@ -3377,7 -3396,7 +3390,7 @@@ static int do_open(struct nameidata *nd
   * @mnt_userns:       user namespace of the mount the inode was found from
   * @dentry:   pointer to dentry of the base directory
   * @mode:     mode of the new tmpfile
 - * @open_flags:       flags
 + * @open_flag       flags
   *
   * Create a temporary file.
   *
@@@ -3517,7 -3536,7 +3530,7 @@@ struct file *do_filp_open(int dfd, stru
        int flags = op->lookup_flags;
        struct file *filp;
  
-       set_nameidata(&nd, dfd, pathname);
+       set_nameidata(&nd, dfd, pathname, NULL);
        filp = path_openat(&nd, op, flags | LOOKUP_RCU);
        if (unlikely(filp == ERR_PTR(-ECHILD)))
                filp = path_openat(&nd, op, flags);
        return filp;
  }
  
- struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
+ struct file *do_file_open_root(const struct path *root,
                const char *name, const struct open_flags *op)
  {
        struct nameidata nd;
        struct file *file;
        struct filename *filename;
-       int flags = op->lookup_flags | LOOKUP_ROOT;
-       nd.root.mnt = mnt;
-       nd.root.dentry = dentry;
+       int flags = op->lookup_flags;
  
-       if (d_is_symlink(dentry) && op->intent & LOOKUP_OPEN)
+       if (d_is_symlink(root->dentry) && op->intent & LOOKUP_OPEN)
                return ERR_PTR(-ELOOP);
  
        filename = getname_kernel(name);
        if (IS_ERR(filename))
                return ERR_CAST(filename);
  
-       set_nameidata(&nd, -1, filename);
+       set_nameidata(&nd, -1, filename, root);
        file = path_openat(&nd, op, flags | LOOKUP_RCU);
        if (unlikely(file == ERR_PTR(-ECHILD)))
                file = path_openat(&nd, op, flags);
@@@ -4402,7 -4418,14 +4412,7 @@@ SYSCALL_DEFINE2(link, const char __use
  
  /**
   * vfs_rename - rename a filesystem object
 - * @old_mnt_userns:   old user namespace of the mount the inode was found from
 - * @old_dir:          parent of source
 - * @old_dentry:               source
 - * @new_mnt_userns:   new user namespace of the mount the inode was found from
 - * @new_dir:          parent of destination
 - * @new_dentry:               destination
 - * @delegated_inode:  returns an inode needing a delegation break
 - * @flags:            rename flags
 + * @rd:               pointer to &struct renamedata info
   *
   * The caller must hold multiple mutexes--see lock_rename()).
   *
diff --combined fs/nfs/nfstrace.h
@@@ -45,11 -45,6 +45,11 @@@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_CTIME
  TRACE_DEFINE_ENUM(NFS_INO_INVALID_MTIME);
  TRACE_DEFINE_ENUM(NFS_INO_INVALID_SIZE);
  TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER);
 +TRACE_DEFINE_ENUM(NFS_INO_DATA_INVAL_DEFER);
 +TRACE_DEFINE_ENUM(NFS_INO_INVALID_BLOCKS);
 +TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR);
 +TRACE_DEFINE_ENUM(NFS_INO_INVALID_NLINK);
 +TRACE_DEFINE_ENUM(NFS_INO_INVALID_MODE);
  
  #define nfs_show_cache_validity(v) \
        __print_flags(v, "|", \
                        { NFS_INO_INVALID_MTIME, "INVALID_MTIME" }, \
                        { NFS_INO_INVALID_SIZE, "INVALID_SIZE" }, \
                        { NFS_INO_INVALID_OTHER, "INVALID_OTHER" }, \
 -                      { NFS_INO_INVALID_XATTR, "INVALID_XATTR" })
 +                      { NFS_INO_DATA_INVAL_DEFER, "DATA_INVAL_DEFER" }, \
 +                      { NFS_INO_INVALID_BLOCKS, "INVALID_BLOCKS" }, \
 +                      { NFS_INO_INVALID_XATTR, "INVALID_XATTR" }, \
 +                      { NFS_INO_INVALID_NLINK, "INVALID_NLINK" }, \
 +                      { NFS_INO_INVALID_MODE, "INVALID_MODE" })
  
  TRACE_DEFINE_ENUM(NFS_INO_ADVISE_RDPLUS);
  TRACE_DEFINE_ENUM(NFS_INO_STALE);
@@@ -280,8 -271,6 +280,6 @@@ TRACE_DEFINE_ENUM(LOOKUP_OPEN)
  TRACE_DEFINE_ENUM(LOOKUP_CREATE);
  TRACE_DEFINE_ENUM(LOOKUP_EXCL);
  TRACE_DEFINE_ENUM(LOOKUP_RENAME_TARGET);
- TRACE_DEFINE_ENUM(LOOKUP_JUMPED);
- TRACE_DEFINE_ENUM(LOOKUP_ROOT);
  TRACE_DEFINE_ENUM(LOOKUP_EMPTY);
  TRACE_DEFINE_ENUM(LOOKUP_DOWN);
  
                        { LOOKUP_CREATE, "CREATE" }, \
                        { LOOKUP_EXCL, "EXCL" }, \
                        { LOOKUP_RENAME_TARGET, "RENAME_TARGET" }, \
-                       { LOOKUP_JUMPED, "JUMPED" }, \
-                       { LOOKUP_ROOT, "ROOT" }, \
                        { LOOKUP_EMPTY, "EMPTY" }, \
                        { LOOKUP_DOWN, "DOWN" })
  
@@@ -430,6 -417,10 +426,6 @@@ TRACE_DEFINE_ENUM(O_CLOEXEC)
                { O_NOATIME, "O_NOATIME" }, \
                { O_CLOEXEC, "O_CLOEXEC" })
  
 -TRACE_DEFINE_ENUM(FMODE_READ);
 -TRACE_DEFINE_ENUM(FMODE_WRITE);
 -TRACE_DEFINE_ENUM(FMODE_EXEC);
 -
  #define show_fmode_flags(mode) \
        __print_flags(mode, "|", \
                { ((__force unsigned long)FMODE_READ), "READ" }, \
@@@ -1397,7 -1388,7 +1393,7 @@@ TRACE_DEFINE_ENUM(NFSERR_JUKEBOX)
                        { NFSERR_BADTYPE, "BADTYPE" }, \
                        { NFSERR_JUKEBOX, "JUKEBOX" })
  
 -TRACE_EVENT(nfs_xdr_status,
 +DECLARE_EVENT_CLASS(nfs_xdr_event,
                TP_PROTO(
                        const struct xdr_stream *xdr,
                        int error
                        __entry->version = task->tk_client->cl_vers;
                        __entry->error = error;
                        __assign_str(program,
 -                                   task->tk_client->cl_program->name)
 -                      __assign_str(procedure, task->tk_msg.rpc_proc->p_name)
 +                                   task->tk_client->cl_program->name);
 +                      __assign_str(procedure, task->tk_msg.rpc_proc->p_name);
                ),
  
                TP_printk(
                        nfs_show_status(__entry->error)
                )
  );
 +#define DEFINE_NFS_XDR_EVENT(name) \
 +      DEFINE_EVENT(nfs_xdr_event, name, \
 +                      TP_PROTO( \
 +                              const struct xdr_stream *xdr, \
 +                              int error \
 +                      ), \
 +                      TP_ARGS(xdr, error))
 +DEFINE_NFS_XDR_EVENT(nfs_xdr_status);
 +DEFINE_NFS_XDR_EVENT(nfs_xdr_bad_filehandle);
  
  #endif /* _TRACE_NFS_H */
  
diff --combined fs/open.c
+++ b/fs/open.c
@@@ -852,17 -852,8 +852,17 @@@ static int do_dentry_open(struct file *
         * XXX: Huge page cache doesn't support writing yet. Drop all page
         * cache for this file before processing writes.
         */
 -      if ((f->f_mode & FMODE_WRITE) && filemap_nr_thps(inode->i_mapping))
 -              truncate_pagecache(inode, 0);
 +      if (f->f_mode & FMODE_WRITE) {
 +              /*
 +               * Paired with smp_mb() in collapse_file() to ensure nr_thps
 +               * is up to date and the update to i_writecount by
 +               * get_write_access() is visible. Ensures subsequent insertion
 +               * of THPs into the page cache will fail.
 +               */
 +              smp_mb();
 +              if (filemap_nr_thps(inode->i_mapping))
 +                      truncate_pagecache(inode, 0);
 +      }
  
        return 0;
  
@@@ -1011,20 -1002,12 +1011,20 @@@ inline struct open_how build_open_how(i
  
  inline int build_open_flags(const struct open_how *how, struct open_flags *op)
  {
 -      int flags = how->flags;
 +      u64 flags = how->flags;
 +      u64 strip = FMODE_NONOTIFY | O_CLOEXEC;
        int lookup_flags = 0;
        int acc_mode = ACC_MODE(flags);
  
 -      /* Must never be set by userspace */
 -      flags &= ~(FMODE_NONOTIFY | O_CLOEXEC);
 +      BUILD_BUG_ON_MSG(upper_32_bits(VALID_OPEN_FLAGS),
 +                       "struct open_flags doesn't yet handle flags > 32 bits");
 +
 +      /*
 +       * Strip flags that either shouldn't be set by userspace like
 +       * FMODE_NONOTIFY or that aren't relevant in determining struct
 +       * open_flags like O_CLOEXEC.
 +       */
 +      flags &= ~strip;
  
        /*
         * Older syscalls implicitly clear all of the invalid flags or argument
@@@ -1173,7 -1156,7 +1173,7 @@@ struct file *filp_open(const char *file
  }
  EXPORT_SYMBOL(filp_open);
  
- struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
+ struct file *file_open_root(const struct path *root,
                            const char *filename, int flags, umode_t mode)
  {
        struct open_flags op;
        int err = build_open_flags(&how, &op);
        if (err)
                return ERR_PTR(err);
-       return do_file_open_root(dentry, mnt, filename, &op);
+       return do_file_open_root(root, filename, &op);
  }
  EXPORT_SYMBOL(file_open_root);
  
diff --combined fs/proc/proc_sysctl.c
@@@ -94,9 -94,14 +94,9 @@@ static void sysctl_print_dir(struct ctl
  
  static int namecmp(const char *name1, int len1, const char *name2, int len2)
  {
 -      int minlen;
        int cmp;
  
 -      minlen = len1;
 -      if (minlen > len2)
 -              minlen = len2;
 -
 -      cmp = memcmp(name1, name2, minlen);
 +      cmp = memcmp(name1, name2, min(len1, len2));
        if (cmp == 0)
                cmp = len1 - len2;
        return cmp;
@@@ -1103,11 -1108,6 +1103,11 @@@ static int sysctl_check_table_array(con
                        err |= sysctl_err(path, table, "array not allowed");
        }
  
 +      if (table->proc_handler == proc_dou8vec_minmax) {
 +              if (table->maxlen != sizeof(u8))
 +                      err |= sysctl_err(path, table, "array not allowed");
 +      }
 +
        return err;
  }
  
@@@ -1123,7 -1123,6 +1123,7 @@@ static int sysctl_check_table(const cha
                    (table->proc_handler == proc_douintvec) ||
                    (table->proc_handler == proc_douintvec_minmax) ||
                    (table->proc_handler == proc_dointvec_minmax) ||
 +                  (table->proc_handler == proc_dou8vec_minmax) ||
                    (table->proc_handler == proc_dointvec_jiffies) ||
                    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
                    (table->proc_handler == proc_dointvec_ms_jiffies) ||
@@@ -1563,7 -1562,7 +1563,7 @@@ err_register_leaves
  }
  
  /**
 - * register_sysctl_table_path - register a sysctl table hierarchy
 + * register_sysctl_paths - register a sysctl table hierarchy
   * @path: The path to the directory the sysctl table is in.
   * @table: the top-level table structure
   *
@@@ -1807,7 -1806,7 +1807,7 @@@ static int process_sysctl_arg(char *par
                panic("%s: Failed to allocate path for %s\n", __func__, param);
        strreplace(path, '.', '/');
  
-       file = file_open_root((*proc_mnt)->mnt_root, *proc_mnt, path, O_WRONLY, 0);
+       file = file_open_root_mnt(*proc_mnt, path, O_WRONLY, 0);
        if (IS_ERR(file)) {
                err = PTR_ERR(file);
                if (err == -ENOENT)
diff --combined include/linux/fs.h
@@@ -70,7 -70,6 +70,7 @@@ struct fsverity_info
  struct fsverity_operations;
  struct fs_context;
  struct fs_parameter_spec;
 +struct fileattr;
  
  extern void __init inode_init(void);
  extern void __init inode_init_early(void);
@@@ -145,7 -144,7 +145,7 @@@ typedef int (dio_iodone_t)(struct kioc
  /* Expect random access pattern */
  #define FMODE_RANDOM          ((__force fmode_t)0x1000)
  
 -/* File is huge (eg. /dev/kmem): treat loff_t as unsigned */
 +/* File is huge (eg. /dev/mem): treat loff_t as unsigned */
  #define FMODE_UNSIGNED_OFFSET ((__force fmode_t)0x2000)
  
  /* File is opened with O_PATH; almost nothing can be done with it */
@@@ -442,6 -441,7 +442,6 @@@ int pagecache_write_end(struct file *, 
   * @i_mmap: Tree of private and shared mappings.
   * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable.
   * @nrpages: Number of page entries, protected by the i_pages lock.
 - * @nrexceptional: Shadow or DAX entries, protected by the i_pages lock.
   * @writeback_index: Writeback starts here.
   * @a_ops: Methods.
   * @flags: Error bits and flags (AS_*).
@@@ -462,6 -462,7 +462,6 @@@ struct address_space 
        struct rb_root_cached   i_mmap;
        struct rw_semaphore     i_mmap_rwsem;
        unsigned long           nrpages;
 -      unsigned long           nrexceptional;
        pgoff_t                 writeback_index;
        const struct address_space_operations *a_ops;
        unsigned long           flags;
@@@ -890,22 -891,18 +890,22 @@@ struct fown_struct 
        int signum;             /* posix.1b rt signal to be delivered on IO */
  };
  
 -/*
 - * Track a single file's readahead state
 +/**
 + * struct file_ra_state - Track a file's readahead state.
 + * @start: Where the most recent readahead started.
 + * @size: Number of pages read in the most recent readahead.
 + * @async_size: Start next readahead when this many pages are left.
 + * @ra_pages: Maximum size of a readahead request.
 + * @mmap_miss: How many mmap accesses missed in the page cache.
 + * @prev_pos: The last byte in the most recent read request.
   */
  struct file_ra_state {
 -      pgoff_t start;                  /* where readahead started */
 -      unsigned int size;              /* # of readahead pages */
 -      unsigned int async_size;        /* do asynchronous readahead when
 -                                         there are only # of pages ahead */
 -
 -      unsigned int ra_pages;          /* Maximum readahead window */
 -      unsigned int mmap_miss;         /* Cache miss stat for mmap accesses */
 -      loff_t prev_pos;                /* Cache last read() position */
 +      pgoff_t start;
 +      unsigned int size;
 +      unsigned int async_size;
 +      unsigned int ra_pages;
 +      unsigned int mmap_miss;
 +      loff_t prev_pos;
  };
  
  /*
@@@ -1577,172 -1574,52 +1577,172 @@@ static inline void i_gid_write(struct i
        inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid);
  }
  
 +/**
 + * kuid_into_mnt - map a kuid down into a mnt_userns
 + * @mnt_userns: user namespace of the relevant mount
 + * @kuid: kuid to be mapped
 + *
 + * Return: @kuid mapped according to @mnt_userns.
 + * If @kuid has no mapping INVALID_UID is returned.
 + */
  static inline kuid_t kuid_into_mnt(struct user_namespace *mnt_userns,
                                   kuid_t kuid)
  {
        return make_kuid(mnt_userns, __kuid_val(kuid));
  }
  
 +/**
 + * kgid_into_mnt - map a kgid down into a mnt_userns
 + * @mnt_userns: user namespace of the relevant mount
 + * @kgid: kgid to be mapped
 + *
 + * Return: @kgid mapped according to @mnt_userns.
 + * If @kgid has no mapping INVALID_GID is returned.
 + */
  static inline kgid_t kgid_into_mnt(struct user_namespace *mnt_userns,
                                   kgid_t kgid)
  {
        return make_kgid(mnt_userns, __kgid_val(kgid));
  }
  
 +/**
 + * i_uid_into_mnt - map an inode's i_uid down into a mnt_userns
 + * @mnt_userns: user namespace of the mount the inode was found from
 + * @inode: inode to map
 + *
 + * Return: the inode's i_uid mapped down according to @mnt_userns.
 + * If the inode's i_uid has no mapping INVALID_UID is returned.
 + */
  static inline kuid_t i_uid_into_mnt(struct user_namespace *mnt_userns,
                                    const struct inode *inode)
  {
        return kuid_into_mnt(mnt_userns, inode->i_uid);
  }
  
 +/**
 + * i_gid_into_mnt - map an inode's i_gid down into a mnt_userns
 + * @mnt_userns: user namespace of the mount the inode was found from
 + * @inode: inode to map
 + *
 + * Return: the inode's i_gid mapped down according to @mnt_userns.
 + * If the inode's i_gid has no mapping INVALID_GID is returned.
 + */
  static inline kgid_t i_gid_into_mnt(struct user_namespace *mnt_userns,
                                    const struct inode *inode)
  {
        return kgid_into_mnt(mnt_userns, inode->i_gid);
  }
  
 +/**
 + * kuid_from_mnt - map a kuid up into a mnt_userns
 + * @mnt_userns: user namespace of the relevant mount
 + * @kuid: kuid to be mapped
 + *
 + * Return: @kuid mapped up according to @mnt_userns.
 + * If @kuid has no mapping INVALID_UID is returned.
 + */
  static inline kuid_t kuid_from_mnt(struct user_namespace *mnt_userns,
                                   kuid_t kuid)
  {
        return KUIDT_INIT(from_kuid(mnt_userns, kuid));
  }
  
 +/**
 + * kgid_from_mnt - map a kgid up into a mnt_userns
 + * @mnt_userns: user namespace of the relevant mount
 + * @kgid: kgid to be mapped
 + *
 + * Return: @kgid mapped up according to @mnt_userns.
 + * If @kgid has no mapping INVALID_GID is returned.
 + */
  static inline kgid_t kgid_from_mnt(struct user_namespace *mnt_userns,
                                   kgid_t kgid)
  {
        return KGIDT_INIT(from_kgid(mnt_userns, kgid));
  }
  
 -static inline kuid_t fsuid_into_mnt(struct user_namespace *mnt_userns)
 +/**
 + * mapped_fsuid - return caller's fsuid mapped up into a mnt_userns
 + * @mnt_userns: user namespace of the relevant mount
 + *
 + * Use this helper to initialize a new vfs or filesystem object based on
 + * the caller's fsuid. A common example is initializing the i_uid field of
 + * a newly allocated inode triggered by a creation event such as mkdir or
 + * O_CREAT. Other examples include the allocation of quotas for a specific
 + * user.
 + *
 + * Return: the caller's current fsuid mapped up according to @mnt_userns.
 + */
 +static inline kuid_t mapped_fsuid(struct user_namespace *mnt_userns)
  {
        return kuid_from_mnt(mnt_userns, current_fsuid());
  }
  
 -static inline kgid_t fsgid_into_mnt(struct user_namespace *mnt_userns)
 +/**
 + * mapped_fsgid - return caller's fsgid mapped up into a mnt_userns
 + * @mnt_userns: user namespace of the relevant mount
 + *
 + * Use this helper to initialize a new vfs or filesystem object based on
 + * the caller's fsgid. A common example is initializing the i_gid field of
 + * a newly allocated inode triggered by a creation event such as mkdir or
 + * O_CREAT. Other examples include the allocation of quotas for a specific
 + * user.
 + *
 + * Return: the caller's current fsgid mapped up according to @mnt_userns.
 + */
 +static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns)
  {
        return kgid_from_mnt(mnt_userns, current_fsgid());
  }
  
 +/**
 + * inode_fsuid_set - initialize inode's i_uid field with callers fsuid
 + * @inode: inode to initialize
 + * @mnt_userns: user namespace of the mount the inode was found from
 + *
 + * Initialize the i_uid field of @inode. If the inode was found/created via
 + * an idmapped mount map the caller's fsuid according to @mnt_users.
 + */
 +static inline void inode_fsuid_set(struct inode *inode,
 +                                 struct user_namespace *mnt_userns)
 +{
 +      inode->i_uid = mapped_fsuid(mnt_userns);
 +}
 +
 +/**
 + * inode_fsgid_set - initialize inode's i_gid field with callers fsgid
 + * @inode: inode to initialize
 + * @mnt_userns: user namespace of the mount the inode was found from
 + *
 + * Initialize the i_gid field of @inode. If the inode was found/created via
 + * an idmapped mount map the caller's fsgid according to @mnt_users.
 + */
 +static inline void inode_fsgid_set(struct inode *inode,
 +                                 struct user_namespace *mnt_userns)
 +{
 +      inode->i_gid = mapped_fsgid(mnt_userns);
 +}
 +
 +/**
 + * fsuidgid_has_mapping() - check whether caller's fsuid/fsgid is mapped
 + * @sb: the superblock we want a mapping in
 + * @mnt_userns: user namespace of the relevant mount
 + *
 + * Check whether the caller's fsuid and fsgid have a valid mapping in the
 + * s_user_ns of the superblock @sb. If the caller is on an idmapped mount map
 + * the caller's fsuid and fsgid according to the @mnt_userns first.
 + *
 + * Return: true if fsuid and fsgid is mapped, false if not.
 + */
 +static inline bool fsuidgid_has_mapping(struct super_block *sb,
 +                                      struct user_namespace *mnt_userns)
 +{
 +      struct user_namespace *s_user_ns = sb->s_user_ns;
 +
 +      return kuid_has_mapping(s_user_ns, mapped_fsuid(mnt_userns)) &&
 +             kgid_has_mapping(s_user_ns, mapped_fsgid(mnt_userns));
 +}
 +
  extern struct timespec64 current_time(struct inode *inode);
  
  /*
@@@ -1862,7 -1739,7 +1862,7 @@@ static inline void sb_start_pagefault(s
        __sb_start_write(sb, SB_FREEZE_PAGEFAULT);
  }
  
 -/*
 +/**
   * sb_start_intwrite - get write access to a superblock for internal fs purposes
   * @sb: the super we write to
   *
@@@ -1905,17 -1782,6 +1905,17 @@@ int vfs_rmdir(struct user_namespace *, 
  int vfs_unlink(struct user_namespace *, struct inode *, struct dentry *,
               struct inode **);
  
 +/**
 + * struct renamedata - contains all information required for renaming
 + * @old_mnt_userns:    old user namespace of the mount the inode was found from
 + * @old_dir:           parent of source
 + * @old_dentry:                source
 + * @new_mnt_userns:    new user namespace of the mount the inode was found from
 + * @new_dir:           parent of destination
 + * @new_dentry:                destination
 + * @delegated_inode:   returns an inode needing a delegation break
 + * @flags:             rename flags
 + */
  struct renamedata {
        struct user_namespace *old_mnt_userns;
        struct inode *old_dir;
@@@ -2097,9 -1963,6 +2097,9 @@@ struct inode_operations 
                        struct dentry *, umode_t);
        int (*set_acl)(struct user_namespace *, struct inode *,
                       struct posix_acl *, int);
 +      int (*fileattr_set)(struct user_namespace *mnt_userns,
 +                          struct dentry *dentry, struct fileattr *fa);
 +      int (*fileattr_get)(struct dentry *dentry, struct fileattr *fa);
  } ____cacheline_aligned;
  
  static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio,
@@@ -2171,6 -2034,7 +2171,6 @@@ struct super_operations 
        ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
        struct dquot **(*get_dquots)(struct inode *);
  #endif
 -      int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
        long (*nr_cached_objects)(struct super_block *,
                                  struct shrink_control *);
        long (*free_cached_objects)(struct super_block *,
@@@ -2768,8 -2632,14 +2768,14 @@@ extern long do_sys_open(int dfd, const 
                        umode_t mode);
  extern struct file *file_open_name(struct filename *, int, umode_t);
  extern struct file *filp_open(const char *, int, umode_t);
- extern struct file *file_open_root(struct dentry *, struct vfsmount *,
+ extern struct file *file_open_root(const struct path *,
                                   const char *, int, umode_t);
+ static inline struct file *file_open_root_mnt(struct vfsmount *mnt,
+                                  const char *name, int flags, umode_t mode)
+ {
+       return file_open_root(&(struct path){.mnt = mnt, .dentry = mnt->mnt_root},
+                             name, flags, mode);
+ }
  extern struct file * dentry_open(const struct path *, int, const struct cred *);
  extern struct file * open_with_fake_path(const struct path *, int,
                                         struct inode*, const struct cred *);
@@@ -2875,8 -2745,6 +2881,8 @@@ static inline int filemap_fdatawait(str
  
  extern bool filemap_range_has_page(struct address_space *, loff_t lstart,
                                  loff_t lend);
 +extern bool filemap_range_needs_writeback(struct address_space *,
 +                                        loff_t lstart, loff_t lend);
  extern int filemap_write_and_wait_range(struct address_space *mapping,
                                        loff_t lstart, loff_t lend);
  extern int __filemap_fdatawrite_range(struct address_space *mapping,
@@@ -3022,11 -2890,6 +3028,11 @@@ static inline bool execute_ok(struct in
        return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
  }
  
 +static inline bool inode_wrong_type(const struct inode *inode, umode_t mode)
 +{
 +      return (inode->i_mode ^ mode) & S_IFMT;
 +}
 +
  static inline void file_start_write(struct file *file)
  {
        if (!S_ISREG(file_inode(file)->i_mode))
@@@ -3304,7 -3167,7 +3310,7 @@@ static inline ssize_t blockdev_direct_I
  
  void inode_dio_wait(struct inode *inode);
  
 -/*
 +/**
   * inode_dio_begin - signal start of a direct I/O requests
   * @inode: inode the direct I/O happens on
   *
@@@ -3316,7 -3179,7 +3322,7 @@@ static inline void inode_dio_begin(stru
        atomic_inc(&inode->i_dio_count);
  }
  
 -/*
 +/**
   * inode_dio_end - signal finish of a direct I/O requests
   * @inode: inode the direct I/O happens on
   *
@@@ -3416,14 -3279,18 +3422,14 @@@ extern int simple_rename(struct user_na
  extern void simple_recursive_removal(struct dentry *,
                                void (*callback)(struct dentry *));
  extern int noop_fsync(struct file *, loff_t, loff_t, int);
 -extern int noop_set_page_dirty(struct page *page);
  extern void noop_invalidatepage(struct page *page, unsigned int offset,
                unsigned int length);
  extern ssize_t noop_direct_IO(struct kiocb *iocb, struct iov_iter *iter);
  extern int simple_empty(struct dentry *);
 -extern int simple_readpage(struct file *file, struct page *page);
  extern int simple_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata);
 -extern int simple_write_end(struct file *file, struct address_space *mapping,
 -                      loff_t pos, unsigned len, unsigned copied,
 -                      struct page *page, void *fsdata);
 +extern const struct address_space_operations ram_aops;
  extern int always_delete_dentry(const struct dentry *);
  extern struct inode *alloc_anon_inode(struct super_block *);
  extern int simple_nosetlease(struct file *, long, struct file_lock **, void **);
@@@ -3706,6 -3573,18 +3712,6 @@@ extern int vfs_fadvise(struct file *fil
  extern int generic_fadvise(struct file *file, loff_t offset, loff_t len,
                           int advice);
  
 -int vfs_ioc_setflags_prepare(struct inode *inode, unsigned int oldflags,
 -                           unsigned int flags);
 -
 -int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa,
 -                           struct fsxattr *fa);
 -
 -static inline void simple_fill_fsxattr(struct fsxattr *fa, __u32 xflags)
 -{
 -      memset(fa, 0, sizeof(*fa));
 -      fa->fsx_xflags = xflags;
 -}
 -
  /*
   * Flush file data before changing attributes.  Caller must hold any locks
   * required to prevent further writes to this file until we're done setting
diff --combined kernel/usermode_driver.c
@@@ -26,7 -26,7 +26,7 @@@ static struct vfsmount *blob_to_mnt(con
        if (IS_ERR(mnt))
                return mnt;
  
-       file = file_open_root(mnt->mnt_root, mnt, name, O_CREAT | O_WRONLY, 0700);
+       file = file_open_root_mnt(mnt, name, O_CREAT | O_WRONLY, 0700);
        if (IS_ERR(file)) {
                mntput(mnt);
                return ERR_CAST(file);
@@@ -139,22 -139,13 +139,22 @@@ static void umd_cleanup(struct subproce
        struct umd_info *umd_info = info->data;
  
        /* cleanup if umh_setup() was successful but exec failed */
 -      if (info->retval) {
 -              fput(umd_info->pipe_to_umh);
 -              fput(umd_info->pipe_from_umh);
 -              put_pid(umd_info->tgid);
 -              umd_info->tgid = NULL;
 -      }
 +      if (info->retval)
 +              umd_cleanup_helper(umd_info);
 +}
 +
 +/**
 + * umd_cleanup_helper - release the resources which were allocated in umd_setup
 + * @info: information about usermode driver
 + */
 +void umd_cleanup_helper(struct umd_info *info)
 +{
 +      fput(info->pipe_to_umh);
 +      fput(info->pipe_from_umh);
 +      put_pid(info->tgid);
 +      info->tgid = NULL;
  }
 +EXPORT_SYMBOL_GPL(umd_cleanup_helper);
  
  /**
   * fork_usermode_driver - fork a usermode driver