Merge branch 'hash' of git://ftp.sciencehorizons.net/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 23:15:25 +0000 (16:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 23:15:25 +0000 (16:15 -0700)
Pull string hash improvements from George Spelvin:
 "This series does several related things:

   - Makes the dcache hash (fs/namei.c) useful for general kernel use.

     (Thanks to Bruce for noticing the zero-length corner case)

   - Converts the string hashes in <linux/sunrpc/svcauth.h> to use the
     above.

   - Avoids 64-bit multiplies in hash_64() on 32-bit platforms.  Two
     32-bit multiplies will do well enough.

   - Rids the world of the bad hash multipliers in hash_32.

     This finishes the job started in commit 689de1d6ca95 ("Minimal
     fix-up of bad hashing behavior of hash_64()")

     The vast majority of Linux architectures have hardware support for
     32x32-bit multiply and so derive no benefit from "simplified"
     multipliers.

     The few processors that do not (68000, h8/300 and some models of
     Microblaze) have arch-specific implementations added.  Those
     patches are last in the series.

   - Overhauls the dcache hash mixing.

     The patch in commit 0fed3ac866ea ("namei: Improve hash mixing if
     CONFIG_DCACHE_WORD_ACCESS") was an off-the-cuff suggestion.
     Replaced with a much more careful design that's simultaneously
     faster and better.  (My own invention, as there was noting suitable
     in the literature I could find.  Comments welcome!)

   - Modify the hash_name() loop to skip the initial HASH_MIX().  This
     would let us salt the hash if we ever wanted to.

   - Sort out partial_name_hash().

     The hash function is declared as using a long state, even though
     it's truncated to 32 bits at the end and the extra internal state
     contributes nothing to the result.  And some callers do odd things:

      - fs/hfs/string.c only allocates 32 bits of state
      - fs/hfsplus/unicode.c uses it to hash 16-bit unicode symbols not bytes

   - Modify bytemask_from_count to handle inputs of 1..sizeof(long)
     rather than 0..sizeof(long)-1.  This would simplify users other
     than full_name_hash"

  Special thanks to Bruce Fields for testing and finding bugs in v1.  (I
  learned some humbling lessons about "obviously correct" code.)

  On the arch-specific front, the m68k assembly has been tested in a
  standalone test harness, I've been in contact with the Microblaze
  maintainers who mostly don't care, as the hardware multiplier is never
  omitted in real-world applications, and I haven't heard anything from
  the H8/300 world"

* 'hash' of git://ftp.sciencehorizons.net/linux:
  h8300: Add <asm/hash.h>
  microblaze: Add <asm/hash.h>
  m68k: Add <asm/hash.h>
  <linux/hash.h>: Add support for architecture-specific functions
  fs/namei.c: Improve dcache hash function
  Eliminate bad hash multipliers from hash_32() and  hash_64()
  Change hash_64() return value to 32 bits
  <linux/sunrpc/svcauth.h>: Define hash_str() in terms of hashlen_string()
  fs/namei.c: Add hashlen_string() function
  Pull out string hash to <linux/stringhash.h>

1  2 
arch/Kconfig
arch/h8300/Kconfig
arch/m68k/Kconfig.cpu
arch/microblaze/Kconfig
fs/dcache.c
fs/namei.c
include/linux/dcache.h
lib/Kconfig.debug
lib/Makefile

diff --combined arch/Kconfig
@@@ -187,11 -187,7 +187,11 @@@ config HAVE_OPTPROBE
  config HAVE_KPROBES_ON_FTRACE
        bool
  
 +config HAVE_NMI
 +      bool
 +
  config HAVE_NMI_WATCHDOG
 +      depends on HAVE_NMI
        bool
  #
  # An arch should select this if it provides all these things:
@@@ -521,11 -517,6 +521,11 @@@ config HAVE_ARCH_MMAP_RND_BIT
          - ARCH_MMAP_RND_BITS_MIN
          - ARCH_MMAP_RND_BITS_MAX
  
 +config HAVE_EXIT_THREAD
 +      bool
 +      help
 +        An architecture implements exit_thread.
 +
  config ARCH_MMAP_RND_BITS_MIN
        int
  
@@@ -598,6 -589,14 +598,14 @@@ config HAVE_STACK_VALIDATIO
          Architecture supports the 'objtool check' host tool command, which
          performs compile-time stack metadata validation.
  
+ config HAVE_ARCH_HASH
+       bool
+       default n
+       help
+         If this is set, the architecture provides an <asm/hash.h>
+         file which provides platform-specific implementations of some
+         functions in <linux/hash.h> or fs/namei.c.
  #
  # ABI hall of shame
  #
@@@ -647,7 -646,4 +655,7 @@@ config COMPAT_OLD_SIGACTIO
  config ARCH_NO_COHERENT_DMA_MMAP
        bool
  
 +config CPU_NO_EFFICIENT_FFS
 +      def_bool n
 +
  source "kernel/gcov/Kconfig"
diff --combined arch/h8300/Kconfig
@@@ -20,7 -20,7 +20,8 @@@ config H830
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZO
        select HAVE_ARCH_KGDB
+       select HAVE_ARCH_HASH
 +      select CPU_NO_EFFICIENT_FFS
  
  config RWSEM_GENERIC_SPINLOCK
        def_bool y
diff --combined arch/m68k/Kconfig.cpu
@@@ -22,11 -22,11 +22,11 @@@ config M68KCLASSI
  
  config COLDFIRE
        bool "Coldfire CPU family support"
 -      select ARCH_REQUIRE_GPIOLIB
        select ARCH_HAVE_CUSTOM_GPIO_H
        select CPU_HAS_NO_BITFIELDS
        select CPU_HAS_NO_MULDIV64
        select GENERIC_CSUM
 +      select GPIOLIB
        select HAVE_CLK
  
  endchoice
@@@ -40,7 -40,7 +40,8 @@@ config M6800
        select CPU_HAS_NO_MULDIV64
        select CPU_HAS_NO_UNALIGNED
        select GENERIC_CSUM
 +      select CPU_NO_EFFICIENT_FFS
+       select HAVE_ARCH_HASH
        help
          The Freescale (was Motorola) 68000 CPU is the first generation of
          the well known M68K family of processors. The CPU core as well as
@@@ -52,7 -52,6 +53,7 @@@ config MCPU3
        bool
        select CPU_HAS_NO_BITFIELDS
        select CPU_HAS_NO_UNALIGNED
 +      select CPU_NO_EFFICIENT_FFS
        help
          The Freescale (was then Motorola) CPU32 is a CPU core that is
          based on the 68020 processor. For the most part it is used in
@@@ -132,7 -131,6 +133,7 @@@ config M520
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5206 processor support.
  
@@@ -141,7 -139,6 +142,7 @@@ config M5206
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5206e processor support.
  
@@@ -167,7 -164,6 +168,7 @@@ config M524
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5249 processor support.
  
@@@ -176,7 -172,6 +177,7 @@@ config M525
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Freescale (Motorola) Coldfire 5251/5253 processor support.
  
@@@ -195,7 -190,6 +196,7 @@@ config M527
        depends on !MMU
        select COLDFIRE_SW_A7
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5272 processor support.
  
@@@ -224,7 -218,6 +225,7 @@@ config M530
        select COLDFIRE_SW_A7
        select HAVE_CACHE_CB
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5307 processor support.
  
@@@ -250,7 -243,6 +251,7 @@@ config M540
        select COLDFIRE_SW_A7
        select HAVE_CACHE_CB
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Motorola ColdFire 5407 processor support.
  
@@@ -260,7 -252,6 +261,7 @@@ config M547
        select MMU_COLDFIRE if MMU
        select HAVE_CACHE_CB
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
  
@@@ -270,7 -261,6 +271,7 @@@ config M548
        select M54xx
        select HAVE_CACHE_CB
        select HAVE_MBAR
 +      select CPU_NO_EFFICIENT_FFS
        help
          Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
  
diff --combined arch/microblaze/Kconfig
@@@ -16,6 -16,7 +16,7 @@@ config MICROBLAZ
        select GENERIC_IRQ_SHOW
        select GENERIC_PCI_IOMAP
        select GENERIC_SCHED_CLOCK
+       select HAVE_ARCH_HASH
        select HAVE_ARCH_KGDB
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_API_DEBUG
@@@ -32,7 -33,6 +33,7 @@@
        select OF_EARLY_FLATTREE
        select TRACING_SUPPORT
        select VIRT_TO_BUS
 +      select CPU_NO_EFFICIENT_FFS
  
  config SWAP
        def_bool n
diff --combined fs/dcache.c
@@@ -111,17 -111,6 +111,17 @@@ static inline struct hlist_bl_head *d_h
        return dentry_hashtable + hash_32(hash, d_hash_shift);
  }
  
 +#define IN_LOOKUP_SHIFT 10
 +static struct hlist_bl_head in_lookup_hashtable[1 << IN_LOOKUP_SHIFT];
 +
 +static inline struct hlist_bl_head *in_lookup_hash(const struct dentry *parent,
 +                                      unsigned int hash)
 +{
 +      hash += (unsigned long) parent / L1_CACHE_BYTES;
 +      return in_lookup_hashtable + hash_32(hash, IN_LOOKUP_SHIFT);
 +}
 +
 +
  /* Statistics gathering. */
  struct dentry_stat_t dentry_stat = {
        .age_limit = 45,
@@@ -772,8 -761,6 +772,8 @@@ repeat
        /* Slow case: now with the dentry lock held */
        rcu_read_unlock();
  
 +      WARN_ON(d_in_lookup(dentry));
 +
        /* Unreachable? Get rid of it */
        if (unlikely(d_unhashed(dentry)))
                goto kill_it;
@@@ -1571,11 -1558,7 +1571,11 @@@ struct dentry *__d_alloc(struct super_b
         * be overwriting an internal NUL character
         */
        dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
 -      if (name->len > DNAME_INLINE_LEN-1) {
 +      if (unlikely(!name)) {
 +              static const struct qstr anon = QSTR_INIT("/", 1);
 +              name = &anon;
 +              dname = dentry->d_iname;
 +      } else if (name->len > DNAME_INLINE_LEN-1) {
                size_t size = offsetof(struct external_name, name[1]);
                struct external_name *p = kmalloc(size + name->len,
                                                  GFP_KERNEL_ACCOUNT);
@@@ -1670,8 -1653,7 +1670,7 @@@ struct dentry *d_alloc_name(struct dent
        struct qstr q;
  
        q.name = name;
-       q.len = strlen(name);
-       q.hash = full_name_hash(q.name, q.len);
+       q.hash_len = hashlen_string(name);
        return d_alloc(parent, &q);
  }
  EXPORT_SYMBOL(d_alloc_name);
@@@ -1763,7 -1745,6 +1762,7 @@@ type_determined
  static void __d_instantiate(struct dentry *dentry, struct inode *inode)
  {
        unsigned add_flags = d_flags_for_inode(inode);
 +      WARN_ON(d_in_lookup(dentry));
  
        spin_lock(&dentry->d_lock);
        hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
@@@ -1793,11 -1774,11 +1792,11 @@@ void d_instantiate(struct dentry *entry
  {
        BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
        if (inode) {
 +              security_d_instantiate(entry, inode);
                spin_lock(&inode->i_lock);
                __d_instantiate(entry, inode);
                spin_unlock(&inode->i_lock);
        }
 -      security_d_instantiate(entry, inode);
  }
  EXPORT_SYMBOL(d_instantiate);
  
@@@ -1814,7 -1795,6 +1813,7 @@@ int d_instantiate_no_diralias(struct de
  {
        BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
  
 +      security_d_instantiate(entry, inode);
        spin_lock(&inode->i_lock);
        if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) {
                spin_unlock(&inode->i_lock);
        }
        __d_instantiate(entry, inode);
        spin_unlock(&inode->i_lock);
 -      security_d_instantiate(entry, inode);
  
        return 0;
  }
@@@ -1833,7 -1814,9 +1832,7 @@@ struct dentry *d_make_root(struct inod
        struct dentry *res = NULL;
  
        if (root_inode) {
 -              static const struct qstr name = QSTR_INIT("/", 1);
 -
 -              res = __d_alloc(root_inode->i_sb, &name);
 +              res = __d_alloc(root_inode->i_sb, NULL);
                if (res)
                        d_instantiate(res, root_inode);
                else
@@@ -1874,6 -1857,7 +1873,6 @@@ EXPORT_SYMBOL(d_find_any_alias)
  
  static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
  {
 -      static const struct qstr anonstring = QSTR_INIT("/", 1);
        struct dentry *tmp;
        struct dentry *res;
        unsigned add_flags;
        if (res)
                goto out_iput;
  
 -      tmp = __d_alloc(inode->i_sb, &anonstring);
 +      tmp = __d_alloc(inode->i_sb, NULL);
        if (!tmp) {
                res = ERR_PTR(-ENOMEM);
                goto out_iput;
        }
  
 +      security_d_instantiate(tmp, inode);
        spin_lock(&inode->i_lock);
        res = __d_find_any_alias(inode);
        if (res) {
        hlist_bl_unlock(&tmp->d_sb->s_anon);
        spin_unlock(&tmp->d_lock);
        spin_unlock(&inode->i_lock);
 -      security_d_instantiate(tmp, inode);
  
        return tmp;
  
   out_iput:
 -      if (res && !IS_ERR(res))
 -              security_d_instantiate(res, inode);
        iput(inode);
        return res;
  }
@@@ -1988,36 -1974,28 +1987,36 @@@ EXPORT_SYMBOL(d_obtain_root)
  struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
                        struct qstr *name)
  {
 -      struct dentry *found;
 -      struct dentry *new;
 +      struct dentry *found, *res;
  
        /*
         * First check if a dentry matching the name already exists,
         * if not go ahead and create it now.
         */
        found = d_hash_and_lookup(dentry->d_parent, name);
 -      if (!found) {
 -              new = d_alloc(dentry->d_parent, name);
 -              if (!new) {
 -                      found = ERR_PTR(-ENOMEM);
 -              } else {
 -                      found = d_splice_alias(inode, new);
 -                      if (found) {
 -                              dput(new);
 -                              return found;
 -                      }
 -                      return new;
 +      if (found) {
 +              iput(inode);
 +              return found;
 +      }
 +      if (d_in_lookup(dentry)) {
 +              found = d_alloc_parallel(dentry->d_parent, name,
 +                                      dentry->d_wait);
 +              if (IS_ERR(found) || !d_in_lookup(found)) {
 +                      iput(inode);
 +                      return found;
                }
 +      } else {
 +              found = d_alloc(dentry->d_parent, name);
 +              if (!found) {
 +                      iput(inode);
 +                      return ERR_PTR(-ENOMEM);
 +              } 
 +      }
 +      res = d_splice_alias(inode, found);
 +      if (res) {
 +              dput(found);
 +              return res;
        }
 -      iput(inode);
        return found;
  }
  EXPORT_SYMBOL(d_add_ci);
@@@ -2384,194 -2362,17 +2383,194 @@@ void d_rehash(struct dentry * entry
  }
  EXPORT_SYMBOL(d_rehash);
  
 +static inline unsigned start_dir_add(struct inode *dir)
 +{
 +
 +      for (;;) {
 +              unsigned n = dir->i_dir_seq;
 +              if (!(n & 1) && cmpxchg(&dir->i_dir_seq, n, n + 1) == n)
 +                      return n;
 +              cpu_relax();
 +      }
 +}
 +
 +static inline void end_dir_add(struct inode *dir, unsigned n)
 +{
 +      smp_store_release(&dir->i_dir_seq, n + 2);
 +}
 +
 +static void d_wait_lookup(struct dentry *dentry)
 +{
 +      if (d_in_lookup(dentry)) {
 +              DECLARE_WAITQUEUE(wait, current);
 +              add_wait_queue(dentry->d_wait, &wait);
 +              do {
 +                      set_current_state(TASK_UNINTERRUPTIBLE);
 +                      spin_unlock(&dentry->d_lock);
 +                      schedule();
 +                      spin_lock(&dentry->d_lock);
 +              } while (d_in_lookup(dentry));
 +      }
 +}
 +
 +struct dentry *d_alloc_parallel(struct dentry *parent,
 +                              const struct qstr *name,
 +                              wait_queue_head_t *wq)
 +{
 +      unsigned int len = name->len;
 +      unsigned int hash = name->hash;
 +      const unsigned char *str = name->name;
 +      struct hlist_bl_head *b = in_lookup_hash(parent, hash);
 +      struct hlist_bl_node *node;
 +      struct dentry *new = d_alloc(parent, name);
 +      struct dentry *dentry;
 +      unsigned seq, r_seq, d_seq;
 +
 +      if (unlikely(!new))
 +              return ERR_PTR(-ENOMEM);
 +
 +retry:
 +      rcu_read_lock();
 +      seq = smp_load_acquire(&parent->d_inode->i_dir_seq) & ~1;
 +      r_seq = read_seqbegin(&rename_lock);
 +      dentry = __d_lookup_rcu(parent, name, &d_seq);
 +      if (unlikely(dentry)) {
 +              if (!lockref_get_not_dead(&dentry->d_lockref)) {
 +                      rcu_read_unlock();
 +                      goto retry;
 +              }
 +              if (read_seqcount_retry(&dentry->d_seq, d_seq)) {
 +                      rcu_read_unlock();
 +                      dput(dentry);
 +                      goto retry;
 +              }
 +              rcu_read_unlock();
 +              dput(new);
 +              return dentry;
 +      }
 +      if (unlikely(read_seqretry(&rename_lock, r_seq))) {
 +              rcu_read_unlock();
 +              goto retry;
 +      }
 +      hlist_bl_lock(b);
 +      if (unlikely(parent->d_inode->i_dir_seq != seq)) {
 +              hlist_bl_unlock(b);
 +              rcu_read_unlock();
 +              goto retry;
 +      }
 +      rcu_read_unlock();
 +      /*
 +       * No changes for the parent since the beginning of d_lookup().
 +       * Since all removals from the chain happen with hlist_bl_lock(),
 +       * any potential in-lookup matches are going to stay here until
 +       * we unlock the chain.  All fields are stable in everything
 +       * we encounter.
 +       */
 +      hlist_bl_for_each_entry(dentry, node, b, d_u.d_in_lookup_hash) {
 +              if (dentry->d_name.hash != hash)
 +                      continue;
 +              if (dentry->d_parent != parent)
 +                      continue;
 +              if (d_unhashed(dentry))
 +                      continue;
 +              if (parent->d_flags & DCACHE_OP_COMPARE) {
 +                      int tlen = dentry->d_name.len;
 +                      const char *tname = dentry->d_name.name;
 +                      if (parent->d_op->d_compare(parent, dentry, tlen, tname, name))
 +                              continue;
 +              } else {
 +                      if (dentry->d_name.len != len)
 +                              continue;
 +                      if (dentry_cmp(dentry, str, len))
 +                              continue;
 +              }
 +              dget(dentry);
 +              hlist_bl_unlock(b);
 +              /* somebody is doing lookup for it right now; wait for it */
 +              spin_lock(&dentry->d_lock);
 +              d_wait_lookup(dentry);
 +              /*
 +               * it's not in-lookup anymore; in principle we should repeat
 +               * everything from dcache lookup, but it's likely to be what
 +               * d_lookup() would've found anyway.  If it is, just return it;
 +               * otherwise we really have to repeat the whole thing.
 +               */
 +              if (unlikely(dentry->d_name.hash != hash))
 +                      goto mismatch;
 +              if (unlikely(dentry->d_parent != parent))
 +                      goto mismatch;
 +              if (unlikely(d_unhashed(dentry)))
 +                      goto mismatch;
 +              if (parent->d_flags & DCACHE_OP_COMPARE) {
 +                      int tlen = dentry->d_name.len;
 +                      const char *tname = dentry->d_name.name;
 +                      if (parent->d_op->d_compare(parent, dentry, tlen, tname, name))
 +                              goto mismatch;
 +              } else {
 +                      if (unlikely(dentry->d_name.len != len))
 +                              goto mismatch;
 +                      if (unlikely(dentry_cmp(dentry, str, len)))
 +                              goto mismatch;
 +              }
 +              /* OK, it *is* a hashed match; return it */
 +              spin_unlock(&dentry->d_lock);
 +              dput(new);
 +              return dentry;
 +      }
 +      /* we can't take ->d_lock here; it's OK, though. */
 +      new->d_flags |= DCACHE_PAR_LOOKUP;
 +      new->d_wait = wq;
 +      hlist_bl_add_head_rcu(&new->d_u.d_in_lookup_hash, b);
 +      hlist_bl_unlock(b);
 +      return new;
 +mismatch:
 +      spin_unlock(&dentry->d_lock);
 +      dput(dentry);
 +      goto retry;
 +}
 +EXPORT_SYMBOL(d_alloc_parallel);
 +
 +void __d_lookup_done(struct dentry *dentry)
 +{
 +      struct hlist_bl_head *b = in_lookup_hash(dentry->d_parent,
 +                                               dentry->d_name.hash);
 +      hlist_bl_lock(b);
 +      dentry->d_flags &= ~DCACHE_PAR_LOOKUP;
 +      __hlist_bl_del(&dentry->d_u.d_in_lookup_hash);
 +      wake_up_all(dentry->d_wait);
 +      dentry->d_wait = NULL;
 +      hlist_bl_unlock(b);
 +      INIT_HLIST_NODE(&dentry->d_u.d_alias);
 +      INIT_LIST_HEAD(&dentry->d_lru);
 +}
 +EXPORT_SYMBOL(__d_lookup_done);
  
  /* inode->i_lock held if inode is non-NULL */
  
  static inline void __d_add(struct dentry *dentry, struct inode *inode)
  {
 +      struct inode *dir = NULL;
 +      unsigned n;
 +      spin_lock(&dentry->d_lock);
 +      if (unlikely(d_in_lookup(dentry))) {
 +              dir = dentry->d_parent->d_inode;
 +              n = start_dir_add(dir);
 +              __d_lookup_done(dentry);
 +      }
        if (inode) {
 -              __d_instantiate(dentry, inode);
 -              spin_unlock(&inode->i_lock);
 +              unsigned add_flags = d_flags_for_inode(inode);
 +              hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
 +              raw_write_seqcount_begin(&dentry->d_seq);
 +              __d_set_inode_and_type(dentry, inode, add_flags);
 +              raw_write_seqcount_end(&dentry->d_seq);
 +              __fsnotify_d_instantiate(dentry);
        }
 -      security_d_instantiate(dentry, inode);
 -      d_rehash(dentry);
 +      _d_rehash(dentry);
 +      if (dir)
 +              end_dir_add(dir, n);
 +      spin_unlock(&dentry->d_lock);
 +      if (inode)
 +              spin_unlock(&inode->i_lock);
  }
  
  /**
  
  void d_add(struct dentry *entry, struct inode *inode)
  {
 -      if (inode)
 +      if (inode) {
 +              security_d_instantiate(entry, inode);
                spin_lock(&inode->i_lock);
 +      }
        __d_add(entry, inode);
  }
  EXPORT_SYMBOL(d_add);
@@@ -2798,8 -2597,6 +2797,8 @@@ static void dentry_unlock_for_move(stru
  static void __d_move(struct dentry *dentry, struct dentry *target,
                     bool exchange)
  {
 +      struct inode *dir = NULL;
 +      unsigned n;
        if (!dentry->d_inode)
                printk(KERN_WARNING "VFS: moving negative dcache entry\n");
  
        BUG_ON(d_ancestor(target, dentry));
  
        dentry_lock_for_move(dentry, target);
 +      if (unlikely(d_in_lookup(target))) {
 +              dir = target->d_parent->d_inode;
 +              n = start_dir_add(dir);
 +              __d_lookup_done(target);
 +      }
  
        write_seqcount_begin(&dentry->d_seq);
        write_seqcount_begin_nested(&target->d_seq, DENTRY_D_LOCK_NESTED);
        write_seqcount_end(&target->d_seq);
        write_seqcount_end(&dentry->d_seq);
  
 +      if (dir)
 +              end_dir_add(dir, n);
        dentry_unlock_for_move(dentry, target);
  }
  
@@@ -2933,8 -2723,7 +2932,8 @@@ struct dentry *d_ancestor(struct dentr
  static int __d_unalias(struct inode *inode,
                struct dentry *dentry, struct dentry *alias)
  {
 -      struct mutex *m1 = NULL, *m2 = NULL;
 +      struct mutex *m1 = NULL;
 +      struct rw_semaphore *m2 = NULL;
        int ret = -ESTALE;
  
        /* If alias and dentry share a parent, then no extra locks required */
        if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
                goto out_err;
        m1 = &dentry->d_sb->s_vfs_rename_mutex;
 -      if (!inode_trylock(alias->d_parent->d_inode))
 +      if (!inode_trylock_shared(alias->d_parent->d_inode))
                goto out_err;
 -      m2 = &alias->d_parent->d_inode->i_mutex;
 +      m2 = &alias->d_parent->d_inode->i_rwsem;
  out_unalias:
        __d_move(alias, dentry, false);
        ret = 0;
  out_err:
        if (m2)
 -              mutex_unlock(m2);
 +              up_read(m2);
        if (m1)
                mutex_unlock(m1);
        return ret;
@@@ -2992,7 -2781,6 +2991,7 @@@ struct dentry *d_splice_alias(struct in
        if (!inode)
                goto out;
  
 +      security_d_instantiate(dentry, inode);
        spin_lock(&inode->i_lock);
        if (S_ISDIR(inode->i_mode)) {
                struct dentry *new = __d_find_any_alias(inode);
                        } else {
                                __d_move(new, dentry, false);
                                write_sequnlock(&rename_lock);
 -                              security_d_instantiate(new, inode);
                        }
                        iput(inode);
                        return new;
diff --combined fs/namei.c
@@@ -35,6 -35,7 +35,7 @@@
  #include <linux/fs_struct.h>
  #include <linux/posix_acl.h>
  #include <linux/hash.h>
+ #include <linux/bitops.h>
  #include <asm/uaccess.h>
  
  #include "internal.h"
@@@ -265,7 -266,7 +266,7 @@@ static int check_acl(struct inode *inod
                if (!acl)
                        return -EAGAIN;
                /* no ->get_acl() calls in RCU mode... */
 -              if (acl == ACL_NOT_CACHED)
 +              if (is_uncached_acl(acl))
                        return -ECHILD;
                return posix_acl_permission(inode, acl, mask & ~MAY_NOT_BLOCK);
        }
@@@ -1603,42 -1604,32 +1604,42 @@@ static struct dentry *lookup_slow(cons
                                  struct dentry *dir,
                                  unsigned int flags)
  {
 -      struct dentry *dentry;
 -      inode_lock(dir->d_inode);
 -      dentry = d_lookup(dir, name);
 -      if (unlikely(dentry)) {
 +      struct dentry *dentry = ERR_PTR(-ENOENT), *old;
 +      struct inode *inode = dir->d_inode;
 +      DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
 +
 +      inode_lock_shared(inode);
 +      /* Don't go there if it's already dead */
 +      if (unlikely(IS_DEADDIR(inode)))
 +              goto out;
 +again:
 +      dentry = d_alloc_parallel(dir, name, &wq);
 +      if (IS_ERR(dentry))
 +              goto out;
 +      if (unlikely(!d_in_lookup(dentry))) {
                if ((dentry->d_flags & DCACHE_OP_REVALIDATE) &&
                    !(flags & LOOKUP_NO_REVAL)) {
                        int error = d_revalidate(dentry, flags);
                        if (unlikely(error <= 0)) {
 -                              if (!error)
 +                              if (!error) {
                                        d_invalidate(dentry);
 +                                      dput(dentry);
 +                                      goto again;
 +                              }
                                dput(dentry);
                                dentry = ERR_PTR(error);
                        }
                }
 -              if (dentry) {
 -                      inode_unlock(dir->d_inode);
 -                      return dentry;
 +      } else {
 +              old = inode->i_op->lookup(inode, dentry, flags);
 +              d_lookup_done(dentry);
 +              if (unlikely(old)) {
 +                      dput(dentry);
 +                      dentry = old;
                }
        }
 -      dentry = d_alloc(dir, name);
 -      if (unlikely(!dentry)) {
 -              inode_unlock(dir->d_inode);
 -              return ERR_PTR(-ENOMEM);
 -      }
 -      dentry = lookup_real(dir->d_inode, dentry, flags);
 -      inode_unlock(dir->d_inode);
 +out:
 +      inode_unlock_shared(inode);
        return dentry;
  }
  
@@@ -1797,74 -1788,144 +1798,144 @@@ static int walk_component(struct nameid
  
  #include <asm/word-at-a-time.h>
  
- #ifdef CONFIG_64BIT
+ #ifdef HASH_MIX
  
- static inline unsigned int fold_hash(unsigned long hash)
- {
-       return hash_64(hash, 32);
- }
+ /* Architecture provides HASH_MIX and fold_hash() in <asm/hash.h> */
  
+ #elif defined(CONFIG_64BIT)
  /*
-  * This is George Marsaglia's XORSHIFT generator.
-  * It implements a maximum-period LFSR in only a few
-  * instructions.  It also has the property (required
-  * by hash_name()) that mix_hash(0) = 0.
+  * Register pressure in the mixing function is an issue, particularly
+  * on 32-bit x86, but almost any function requires one state value and
+  * one temporary.  Instead, use a function designed for two state values
+  * and no temporaries.
+  *
+  * This function cannot create a collision in only two iterations, so
+  * we have two iterations to achieve avalanche.  In those two iterations,
+  * we have six layers of mixing, which is enough to spread one bit's
+  * influence out to 2^6 = 64 state bits.
+  *
+  * Rotate constants are scored by considering either 64 one-bit input
+  * deltas or 64*63/2 = 2016 two-bit input deltas, and finding the
+  * probability of that delta causing a change to each of the 128 output
+  * bits, using a sample of random initial states.
+  *
+  * The Shannon entropy of the computed probabilities is then summed
+  * to produce a score.  Ideally, any input change has a 50% chance of
+  * toggling any given output bit.
+  *
+  * Mixing scores (in bits) for (12,45):
+  * Input delta: 1-bit      2-bit
+  * 1 round:     713.3    42542.6
+  * 2 rounds:   2753.7   140389.8
+  * 3 rounds:   5954.1   233458.2
+  * 4 rounds:   7862.6   256672.2
+  * Perfect:    8192     258048
+  *            (64*128) (64*63/2 * 128)
   */
- static inline unsigned long mix_hash(unsigned long hash)
+ #define HASH_MIX(x, y, a)     \
+       (       x ^= (a),       \
+       y ^= x, x = rol64(x,12),\
+       x += y, y = rol64(y,45),\
+       y *= 9                  )
+ /*
+  * Fold two longs into one 32-bit hash value.  This must be fast, but
+  * latency isn't quite as critical, as there is a fair bit of additional
+  * work done before the hash value is used.
+  */
+ static inline unsigned int fold_hash(unsigned long x, unsigned long y)
  {
-       hash ^= hash << 13;
-       hash ^= hash >> 7;
-       hash ^= hash << 17;
-       return hash;
+       y ^= x * GOLDEN_RATIO_64;
+       y *= GOLDEN_RATIO_64;
+       return y >> 32;
  }
  
  #else /* 32-bit case */
  
- #define fold_hash(x) (x)
+ /*
+  * Mixing scores (in bits) for (7,20):
+  * Input delta: 1-bit      2-bit
+  * 1 round:     330.3     9201.6
+  * 2 rounds:   1246.4    25475.4
+  * 3 rounds:   1907.1    31295.1
+  * 4 rounds:   2042.3    31718.6
+  * Perfect:    2048      31744
+  *            (32*64)   (32*31/2 * 64)
+  */
+ #define HASH_MIX(x, y, a)     \
+       (       x ^= (a),       \
+       y ^= x, x = rol32(x, 7),\
+       x += y, y = rol32(y,20),\
+       y *= 9                  )
  
- static inline unsigned long mix_hash(unsigned long hash)
+ static inline unsigned int fold_hash(unsigned long x, unsigned long y)
  {
-       hash ^= hash << 13;
-       hash ^= hash >> 17;
-       hash ^= hash << 5;
-       return hash;
+       /* Use arch-optimized multiply if one exists */
+       return __hash_32(y ^ __hash_32(x));
  }
  
  #endif
  
- unsigned int full_name_hash(const unsigned char *name, unsigned int len)
+ /*
+  * Return the hash of a string of known length.  This is carfully
+  * designed to match hash_name(), which is the more critical function.
+  * In particular, we must end by hashing a final word containing 0..7
+  * payload bytes, to match the way that hash_name() iterates until it
+  * finds the delimiter after the name.
+  */
+ unsigned int full_name_hash(const char *name, unsigned int len)
  {
-       unsigned long a, hash = 0;
+       unsigned long a, x = 0, y = 0;
  
        for (;;) {
+               if (!len)
+                       goto done;
                a = load_unaligned_zeropad(name);
                if (len < sizeof(unsigned long))
                        break;
-               hash = mix_hash(hash + a);
+               HASH_MIX(x, y, a);
                name += sizeof(unsigned long);
                len -= sizeof(unsigned long);
-               if (!len)
-                       goto done;
        }
-       hash += a & bytemask_from_count(len);
+       x ^= a & bytemask_from_count(len);
  done:
-       return fold_hash(hash);
+       return fold_hash(x, y);
  }
  EXPORT_SYMBOL(full_name_hash);
  
+ /* Return the "hash_len" (hash and length) of a null-terminated string */
+ u64 hashlen_string(const char *name)
+ {
+       unsigned long a = 0, x = 0, y = 0, adata, mask, len;
+       const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
+       len = -sizeof(unsigned long);
+       do {
+               HASH_MIX(x, y, a);
+               len += sizeof(unsigned long);
+               a = load_unaligned_zeropad(name+len);
+       } while (!has_zero(a, &adata, &constants));
+       adata = prep_zero_mask(a, adata, &constants);
+       mask = create_zero_mask(adata);
+       x ^= a & zero_bytemask(mask);
+       return hashlen_create(fold_hash(x, y), len + find_zero(mask));
+ }
+ EXPORT_SYMBOL(hashlen_string);
  /*
   * Calculate the length and hash of the path component, and
   * return the "hash_len" as the result.
   */
  static inline u64 hash_name(const char *name)
  {
-       unsigned long a, b, adata, bdata, mask, hash, len;
+       unsigned long a = 0, b, x = 0, y = 0, adata, bdata, mask, len;
        const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
  
-       hash = a = 0;
        len = -sizeof(unsigned long);
        do {
-               hash = mix_hash(hash + a);
+               HASH_MIX(x, y, a);
                len += sizeof(unsigned long);
                a = load_unaligned_zeropad(name+len);
                b = a ^ REPEAT_BYTE('/');
  
        adata = prep_zero_mask(a, adata, &constants);
        bdata = prep_zero_mask(b, bdata, &constants);
        mask = create_zero_mask(adata | bdata);
+       x ^= a & zero_bytemask(mask);
  
-       hash += a & zero_bytemask(mask);
-       len += find_zero(mask);
-       return hashlen_create(fold_hash(hash), len);
+       return hashlen_create(fold_hash(x, y), len + find_zero(mask));
  }
  
- #else
+ #else /* !CONFIG_DCACHE_WORD_ACCESS: Slow, byte-at-a-time version */
  
- unsigned int full_name_hash(const unsigned char *name, unsigned int len)
+ /* Return the hash of a string of known length */
+ unsigned int full_name_hash(const char *name, unsigned int len)
  {
        unsigned long hash = init_name_hash();
        while (len--)
-               hash = partial_name_hash(*name++, hash);
+               hash = partial_name_hash((unsigned char)*name++, hash);
        return end_name_hash(hash);
  }
  EXPORT_SYMBOL(full_name_hash);
  
+ /* Return the "hash_len" (hash and length) of a null-terminated string */
+ u64 hash_string(const char *name)
+ {
+       unsigned long hash = init_name_hash();
+       unsigned long len = 0, c;
+       c = (unsigned char)*name;
+       do {
+               len++;
+               hash = partial_name_hash(c, hash);
+               c = (unsigned char)name[len];
+       } while (c);
+       return hashlen_create(end_name_hash(hash), len);
+ }
+ EXPORT_SYMBOL(hash_string);
  /*
   * We know there's a real path component here of at least
   * one character.
@@@ -1934,7 -2010,7 +2020,7 @@@ static int link_path_walk(const char *n
                int type;
  
                err = may_lookup(nd);
-               if (err)
+               if (err)
                        return err;
  
                hash_len = hash_name(name);
@@@ -2707,7 -2783,7 +2793,7 @@@ struct dentry *lock_rename(struct dentr
                return NULL;
        }
  
 -      mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
 +      mutex_lock(&p1->d_sb->s_vfs_rename_mutex);
  
        p = d_ancestor(p2, p1);
        if (p) {
@@@ -2734,7 -2810,7 +2820,7 @@@ void unlock_rename(struct dentry *p1, s
        inode_unlock(p1->d_inode);
        if (p1 != p2) {
                inode_unlock(p2->d_inode);
 -              mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
 +              mutex_unlock(&p1->d_sb->s_vfs_rename_mutex);
        }
  }
  EXPORT_SYMBOL(unlock_rename);
@@@ -2837,7 -2913,7 +2923,7 @@@ static inline int open_to_namei_flags(i
        return flag;
  }
  
 -static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode)
 +static int may_o_create(const struct path *dir, struct dentry *dentry, umode_t mode)
  {
        int error = security_path_mknod(dir, dentry, mode, 0);
        if (error)
  static int atomic_open(struct nameidata *nd, struct dentry *dentry,
                        struct path *path, struct file *file,
                        const struct open_flags *op,
 -                      bool got_write, bool need_lookup,
 +                      int open_flag, umode_t mode,
                        int *opened)
  {
 +      struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
        struct inode *dir =  nd->path.dentry->d_inode;
 -      unsigned open_flag = open_to_namei_flags(op->open_flag);
 -      umode_t mode;
        int error;
 -      int acc_mode;
 -      int create_error = 0;
 -      struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
 -      bool excl;
 -
 -      BUG_ON(dentry->d_inode);
 -
 -      /* Don't create child dentry for a dead directory. */
 -      if (unlikely(IS_DEADDIR(dir))) {
 -              error = -ENOENT;
 -              goto out;
 -      }
  
 -      mode = op->mode;
 -      if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
 -              mode &= ~current_umask();
 -
 -      excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT);
 -      if (excl)
 +      if (!(~open_flag & (O_EXCL | O_CREAT))) /* both O_EXCL and O_CREAT */
                open_flag &= ~O_TRUNC;
  
 -      /*
 -       * Checking write permission is tricky, bacuse we don't know if we are
 -       * going to actually need it: O_CREAT opens should work as long as the
 -       * file exists.  But checking existence breaks atomicity.  The trick is
 -       * to check access and if not granted clear O_CREAT from the flags.
 -       *
 -       * Another problem is returing the "right" error value (e.g. for an
 -       * O_EXCL open we want to return EEXIST not EROFS).
 -       */
 -      if (((open_flag & (O_CREAT | O_TRUNC)) ||
 -          (open_flag & O_ACCMODE) != O_RDONLY) && unlikely(!got_write)) {
 -              if (!(open_flag & O_CREAT)) {
 -                      /*
 -                       * No O_CREATE -> atomicity not a requirement -> fall
 -                       * back to lookup + open
 -                       */
 -                      goto no_open;
 -              } else if (open_flag & (O_EXCL | O_TRUNC)) {
 -                      /* Fall back and fail with the right error */
 -                      create_error = -EROFS;
 -                      goto no_open;
 -              } else {
 -                      /* No side effects, safe to clear O_CREAT */
 -                      create_error = -EROFS;
 -                      open_flag &= ~O_CREAT;
 -              }
 -      }
 -
 -      if (open_flag & O_CREAT) {
 -              error = may_o_create(&nd->path, dentry, mode);
 -              if (error) {
 -                      create_error = error;
 -                      if (open_flag & O_EXCL)
 -                              goto no_open;
 -                      open_flag &= ~O_CREAT;
 -              }
 -      }
 -
        if (nd->flags & LOOKUP_DIRECTORY)
                open_flag |= O_DIRECTORY;
  
        file->f_path.dentry = DENTRY_NOT_SET;
        file->f_path.mnt = nd->path.mnt;
 -      error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
 -                                    opened);
 -      if (error < 0) {
 -              if (create_error && error == -ENOENT)
 -                      error = create_error;
 -              goto out;
 -      }
 -
 -      if (error) {    /* returned 1, that is */
 +      error = dir->i_op->atomic_open(dir, dentry, file,
 +                                     open_to_namei_flags(open_flag),
 +                                     mode, opened);
 +      d_lookup_done(dentry);
 +      if (!error) {
 +              /*
 +               * We didn't have the inode before the open, so check open
 +               * permission here.
 +               */
 +              int acc_mode = op->acc_mode;
 +              if (*opened & FILE_CREATED) {
 +                      WARN_ON(!(open_flag & O_CREAT));
 +                      fsnotify_create(dir, dentry);
 +                      acc_mode = 0;
 +              }
 +              error = may_open(&file->f_path, acc_mode, open_flag);
 +              if (WARN_ON(error > 0))
 +                      error = -EINVAL;
 +      } else if (error > 0) {
                if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
                        error = -EIO;
 -                      goto out;
 -              }
 -              if (file->f_path.dentry) {
 -                      dput(dentry);
 -                      dentry = file->f_path.dentry;
 -              }
 -              if (*opened & FILE_CREATED)
 -                      fsnotify_create(dir, dentry);
 -              if (!dentry->d_inode) {
 -                      WARN_ON(*opened & FILE_CREATED);
 -                      if (create_error) {
 -                              error = create_error;
 -                              goto out;
 -                      }
                } else {
 -                      if (excl && !(*opened & FILE_CREATED)) {
 -                              error = -EEXIST;
 -                              goto out;
 +                      if (file->f_path.dentry) {
 +                              dput(dentry);
 +                              dentry = file->f_path.dentry;
                        }
 +                      if (*opened & FILE_CREATED)
 +                              fsnotify_create(dir, dentry);
 +                      path->dentry = dentry;
 +                      path->mnt = nd->path.mnt;
 +                      return 1;
                }
 -              goto looked_up;
 -      }
 -
 -      /*
 -       * We didn't have the inode before the open, so check open permission
 -       * here.
 -       */
 -      acc_mode = op->acc_mode;
 -      if (*opened & FILE_CREATED) {
 -              WARN_ON(!(open_flag & O_CREAT));
 -              fsnotify_create(dir, dentry);
 -              acc_mode = 0;
        }
 -      error = may_open(&file->f_path, acc_mode, open_flag);
 -      if (error)
 -              fput(file);
 -
 -out:
        dput(dentry);
        return error;
 -
 -no_open:
 -      if (need_lookup) {
 -              dentry = lookup_real(dir, dentry, nd->flags);
 -              if (IS_ERR(dentry))
 -                      return PTR_ERR(dentry);
 -      }
 -      if (create_error && !dentry->d_inode) {
 -              error = create_error;
 -              goto out;
 -      }
 -looked_up:
 -      path->dentry = dentry;
 -      path->mnt = nd->path.mnt;
 -      return 1;
  }
  
  /*
@@@ -2943,118 -3106,62 +3029,118 @@@ static int lookup_open(struct nameidat
  {
        struct dentry *dir = nd->path.dentry;
        struct inode *dir_inode = dir->d_inode;
 +      int open_flag = op->open_flag;
        struct dentry *dentry;
 -      int error;
 -      bool need_lookup = false;
 +      int error, create_error = 0;
 +      umode_t mode = op->mode;
 +      DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
 +
 +      if (unlikely(IS_DEADDIR(dir_inode)))
 +              return -ENOENT;
  
        *opened &= ~FILE_CREATED;
 -      dentry = lookup_dcache(&nd->last, dir, nd->flags);
 -      if (IS_ERR(dentry))
 -              return PTR_ERR(dentry);
 +      dentry = d_lookup(dir, &nd->last);
 +      for (;;) {
 +              if (!dentry) {
 +                      dentry = d_alloc_parallel(dir, &nd->last, &wq);
 +                      if (IS_ERR(dentry))
 +                              return PTR_ERR(dentry);
 +              }
 +              if (d_in_lookup(dentry))
 +                      break;
  
 -      if (!dentry) {
 -              dentry = d_alloc(dir, &nd->last);
 -              if (unlikely(!dentry))
 -                      return -ENOMEM;
 -              need_lookup = true;
 -      } else if (dentry->d_inode) {
 +              if (!(dentry->d_flags & DCACHE_OP_REVALIDATE))
 +                      break;
 +
 +              error = d_revalidate(dentry, nd->flags);
 +              if (likely(error > 0))
 +                      break;
 +              if (error)
 +                      goto out_dput;
 +              d_invalidate(dentry);
 +              dput(dentry);
 +              dentry = NULL;
 +      }
 +      if (dentry->d_inode) {
                /* Cached positive dentry: will open in f_op->open */
                goto out_no_open;
        }
  
 -      if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) {
 -              return atomic_open(nd, dentry, path, file, op, got_write,
 -                                 need_lookup, opened);
 +      /*
 +       * Checking write permission is tricky, bacuse we don't know if we are
 +       * going to actually need it: O_CREAT opens should work as long as the
 +       * file exists.  But checking existence breaks atomicity.  The trick is
 +       * to check access and if not granted clear O_CREAT from the flags.
 +       *
 +       * Another problem is returing the "right" error value (e.g. for an
 +       * O_EXCL open we want to return EEXIST not EROFS).
 +       */
 +      if (open_flag & O_CREAT) {
 +              if (!IS_POSIXACL(dir->d_inode))
 +                      mode &= ~current_umask();
 +              if (unlikely(!got_write)) {
 +                      create_error = -EROFS;
 +                      open_flag &= ~O_CREAT;
 +                      if (open_flag & (O_EXCL | O_TRUNC))
 +                              goto no_open;
 +                      /* No side effects, safe to clear O_CREAT */
 +              } else {
 +                      create_error = may_o_create(&nd->path, dentry, mode);
 +                      if (create_error) {
 +                              open_flag &= ~O_CREAT;
 +                              if (open_flag & O_EXCL)
 +                                      goto no_open;
 +                      }
 +              }
 +      } else if ((open_flag & (O_TRUNC|O_WRONLY|O_RDWR)) &&
 +                 unlikely(!got_write)) {
 +              /*
 +               * No O_CREATE -> atomicity not a requirement -> fall
 +               * back to lookup + open
 +               */
 +              goto no_open;
        }
  
 -      if (need_lookup) {
 -              BUG_ON(dentry->d_inode);
 +      if (dir_inode->i_op->atomic_open) {
 +              error = atomic_open(nd, dentry, path, file, op, open_flag,
 +                                  mode, opened);
 +              if (unlikely(error == -ENOENT) && create_error)
 +                      error = create_error;
 +              return error;
 +      }
  
 -              dentry = lookup_real(dir_inode, dentry, nd->flags);
 -              if (IS_ERR(dentry))
 -                      return PTR_ERR(dentry);
 +no_open:
 +      if (d_in_lookup(dentry)) {
 +              struct dentry *res = dir_inode->i_op->lookup(dir_inode, dentry,
 +                                                           nd->flags);
 +              d_lookup_done(dentry);
 +              if (unlikely(res)) {
 +                      if (IS_ERR(res)) {
 +                              error = PTR_ERR(res);
 +                              goto out_dput;
 +                      }
 +                      dput(dentry);
 +                      dentry = res;
 +              }
        }
  
        /* Negative dentry, just create the file */
 -      if (!dentry->d_inode && (op->open_flag & O_CREAT)) {
 -              umode_t mode = op->mode;
 -              if (!IS_POSIXACL(dir->d_inode))
 -                      mode &= ~current_umask();
 -              /*
 -               * This write is needed to ensure that a
 -               * rw->ro transition does not occur between
 -               * the time when the file is created and when
 -               * a permanent write count is taken through
 -               * the 'struct file' in finish_open().
 -               */
 -              if (!got_write) {
 -                      error = -EROFS;
 -                      goto out_dput;
 -              }
 +      if (!dentry->d_inode && (open_flag & O_CREAT)) {
                *opened |= FILE_CREATED;
 -              error = security_path_mknod(&nd->path, dentry, mode, 0);
 -              if (error)
 +              audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
 +              if (!dir_inode->i_op->create) {
 +                      error = -EACCES;
                        goto out_dput;
 -              error = vfs_create(dir->d_inode, dentry, mode,
 -                                 nd->flags & LOOKUP_EXCL);
 +              }
 +              error = dir_inode->i_op->create(dir_inode, dentry, mode,
 +                                              open_flag & O_EXCL);
                if (error)
                        goto out_dput;
 +              fsnotify_create(dir_inode, dentry);
 +      }
 +      if (unlikely(create_error) && !dentry->d_inode) {
 +              error = create_error;
 +              goto out_dput;
        }
  out_no_open:
        path->dentry = dentry;
@@@ -3126,7 -3233,7 +3212,7 @@@ static int do_last(struct nameidata *nd
        }
  
  retry_lookup:
 -      if (op->open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
 +      if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
                error = mnt_want_write(nd->path.mnt);
                if (!error)
                        got_write = true;
                 * dropping this one anyway.
                 */
        }
 -      inode_lock(dir->d_inode);
 +      if (open_flag & O_CREAT)
 +              inode_lock(dir->d_inode);
 +      else
 +              inode_lock_shared(dir->d_inode);
        error = lookup_open(nd, &path, file, op, got_write, opened);
 -      inode_unlock(dir->d_inode);
 +      if (open_flag & O_CREAT)
 +              inode_unlock(dir->d_inode);
 +      else
 +              inode_unlock_shared(dir->d_inode);
  
        if (error <= 0) {
                if (error)
@@@ -3224,6 -3325,10 +3310,6 @@@ finish_open
                return error;
        }
        audit_inode(nd->name, nd->path.dentry, 0);
 -      if (unlikely(d_is_symlink(nd->path.dentry)) && !(open_flag & O_PATH)) {
 -              error = -ELOOP;
 -              goto out;
 -      }
        error = -EISDIR;
        if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
                goto out;
                got_write = true;
        }
  finish_open_created:
 -      if (likely(!(open_flag & O_PATH))) {
 -              error = may_open(&nd->path, acc_mode, open_flag);
 -              if (error)
 -                      goto out;
 -      }
 +      error = may_open(&nd->path, acc_mode, open_flag);
 +      if (error)
 +              goto out;
        BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
        error = vfs_open(&nd->path, file, current_cred());
        if (!error) {
        }
  opened:
        error = open_check_o_direct(file);
 -      if (error)
 -              goto exit_fput;
 -      error = ima_file_check(file, op->acc_mode, *opened);
 -      if (error)
 -              goto exit_fput;
 -
 -      if (will_truncate) {
 +      if (!error)
 +              error = ima_file_check(file, op->acc_mode, *opened);
 +      if (!error && will_truncate)
                error = handle_truncate(file);
 -              if (error)
 -                      goto exit_fput;
 -      }
  out:
 +      if (unlikely(error) && (*opened & FILE_OPENED))
 +              fput(file);
        if (unlikely(error > 0)) {
                WARN_ON(1);
                error = -EINVAL;
        path_put(&save_parent);
        return error;
  
 -exit_fput:
 -      fput(file);
 -      goto out;
 -
  stale_open:
        /* If no saved parent or already retried then can't retry */
        if (!save_parent.dentry || retried)
        return error;
  }
  
 +static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file)
 +{
 +      struct path path;
 +      int error = path_lookupat(nd, flags, &path);
 +      if (!error) {
 +              audit_inode(nd->name, path.dentry, 0);
 +              error = vfs_open(&path, file, current_cred());
 +              path_put(&path);
 +      }
 +      return error;
 +}
 +
  static struct file *path_openat(struct nameidata *nd,
                        const struct open_flags *op, unsigned flags)
  {
                goto out2;
        }
  
 +      if (unlikely(file->f_flags & O_PATH)) {
 +              error = do_o_path(nd, flags, file);
 +              if (!error)
 +                      opened |= FILE_OPENED;
 +              goto out2;
 +      }
 +
        s = path_init(nd, flags);
        if (IS_ERR(s)) {
                put_filp(file);
@@@ -3627,8 -3724,6 +3713,8 @@@ retry
        switch (mode & S_IFMT) {
                case 0: case S_IFREG:
                        error = vfs_create(path.dentry->d_inode,dentry,mode,true);
 +                      if (!error)
 +                              ima_post_path_mknod(dentry);
                        break;
                case S_IFCHR: case S_IFBLK:
                        error = vfs_mknod(path.dentry->d_inode,dentry,mode,
@@@ -4542,6 -4637,7 +4628,6 @@@ int readlink_copy(char __user *buffer, 
  out:
        return len;
  }
 -EXPORT_SYMBOL(readlink_copy);
  
  /*
   * A helper for ->readlink().  This should be used *ONLY* for symlinks that
diff --combined include/linux/dcache.h
@@@ -10,6 -10,7 +10,7 @@@
  #include <linux/cache.h>
  #include <linux/rcupdate.h>
  #include <linux/lockref.h>
+ #include <linux/stringhash.h>
  
  struct path;
  struct vfsmount;
@@@ -52,9 -53,6 +53,6 @@@ struct qstr 
  };
  
  #define QSTR_INIT(n,l) { { { .len = l } }, .name = n }
- #define hashlen_hash(hashlen) ((u32) (hashlen))
- #define hashlen_len(hashlen)  ((u32)((hashlen) >> 32))
- #define hashlen_create(hash,len) (((u64)(len)<<32)|(u32)(hash))
  
  struct dentry_stat_t {
        long nr_dentry;
  };
  extern struct dentry_stat_t dentry_stat;
  
- /* Name hashing routines. Initial hash value */
- /* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
- #define init_name_hash()              0
- /* partial hash update function. Assume roughly 4 bits per character */
- static inline unsigned long
- partial_name_hash(unsigned long c, unsigned long prevhash)
- {
-       return (prevhash + (c << 4) + (c >> 4)) * 11;
- }
- /*
-  * Finally: cut down the number of bits to a int value (and try to avoid
-  * losing bits)
-  */
- static inline unsigned long end_name_hash(unsigned long hash)
- {
-       return (unsigned int) hash;
- }
- /* Compute the hash for a name string. */
- extern unsigned int full_name_hash(const unsigned char *, unsigned int);
  /*
   * Try to keep struct dentry aligned on 64 byte cachelines (this will
   * give reasonable cacheline footprint with larger lines without the
@@@ -123,10 -98,7 +98,10 @@@ struct dentry 
        unsigned long d_time;           /* used by d_revalidate */
        void *d_fsdata;                 /* fs-specific data */
  
 -      struct list_head d_lru;         /* LRU list */
 +      union {
 +              struct list_head d_lru;         /* LRU list */
 +              wait_queue_head_t *d_wait;      /* in-lookup ones only */
 +      };
        struct list_head d_child;       /* child of parent list */
        struct list_head d_subdirs;     /* our children */
        /*
         */
        union {
                struct hlist_node d_alias;      /* inode alias list */
 +              struct hlist_bl_node d_in_lookup_hash;  /* only for in-lookup ones */
                struct rcu_head d_rcu;
        } d_u;
  };
@@@ -236,8 -207,6 +211,8 @@@ struct dentry_operations 
  #define DCACHE_ENCRYPTED_WITH_KEY     0x04000000 /* dir is encrypted with a valid key */
  #define DCACHE_OP_REAL                        0x08000000
  
 +#define DCACHE_PAR_LOOKUP             0x10000000 /* being looked up (with parent locked shared) */
 +
  extern seqlock_t rename_lock;
  
  /*
@@@ -254,8 -223,6 +229,8 @@@ extern void d_set_d_op(struct dentry *d
  /* allocate/de-allocate */
  extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
  extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);
 +extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *,
 +                                      wait_queue_head_t *);
  extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
  extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
  extern struct dentry * d_exact_alias(struct dentry *, struct inode *);
@@@ -375,22 -342,6 +350,22 @@@ static inline void dont_mount(struct de
        spin_unlock(&dentry->d_lock);
  }
  
 +extern void __d_lookup_done(struct dentry *);
 +
 +static inline int d_in_lookup(struct dentry *dentry)
 +{
 +      return dentry->d_flags & DCACHE_PAR_LOOKUP;
 +}
 +
 +static inline void d_lookup_done(struct dentry *dentry)
 +{
 +      if (unlikely(d_in_lookup(dentry))) {
 +              spin_lock(&dentry->d_lock);
 +              __d_lookup_done(dentry);
 +              spin_unlock(&dentry->d_lock);
 +      }
 +}
 +
  extern void dput(struct dentry *);
  
  static inline bool d_managed(const struct dentry *dentry)
diff --combined lib/Kconfig.debug
@@@ -257,7 -257,6 +257,7 @@@ config PAGE_OWNE
  
  config DEBUG_FS
        bool "Debug Filesystem"
 +      select SRCU
        help
          debugfs is a virtual file system that kernel developers use to put
          debugging files into.  Enable this option to be able to read and
@@@ -1290,39 -1289,6 +1290,39 @@@ config TORTURE_TES
        tristate
        default n
  
 +config RCU_PERF_TEST
 +      tristate "performance tests for RCU"
 +      depends on DEBUG_KERNEL
 +      select TORTURE_TEST
 +      select SRCU
 +      select TASKS_RCU
 +      default n
 +      help
 +        This option provides a kernel module that runs performance
 +        tests on the RCU infrastructure.  The kernel module may be built
 +        after the fact on the running kernel to be tested, if desired.
 +
 +        Say Y here if you want RCU performance tests to be built into
 +        the kernel.
 +        Say M if you want the RCU performance tests to build as a module.
 +        Say N if you are unsure.
 +
 +config RCU_PERF_TEST_RUNNABLE
 +      bool "performance tests for RCU runnable by default"
 +      depends on RCU_PERF_TEST = y
 +      default n
 +      help
 +        This option provides a way to build the RCU performance tests
 +        directly into the kernel without them starting up at boot time.
 +        You can use /sys/module to manually override this setting.
 +        This /proc file is available only when the RCU performance
 +        tests have been built into the kernel.
 +
 +        Say Y here if you want the RCU performance tests to start during
 +        boot (you probably don't).
 +        Say N here if you want the RCU performance tests to start only
 +        after being manually enabled via /sys/module.
 +
  config RCU_TORTURE_TEST
        tristate "torture tests for RCU"
        depends on DEBUG_KERNEL
@@@ -1849,6 -1815,17 +1849,17 @@@ config TEST_RHASHTABL
  
          If unsure, say N.
  
+ config TEST_HASH
+       tristate "Perform selftest on hash functions"
+       default n
+       help
+         Enable this option to test the kernel's integer (<linux/hash,h>)
+         and string (<linux/stringhash.h>) hash functions on boot
+         (or module load).
+         This is intended to help people writing architecture-specific
+         optimized versions.  If unsure, say N.
  endmenu # runtime tests
  
  config PROVIDE_OHCI1394_DMA_INIT
diff --combined lib/Makefile
@@@ -23,9 -23,9 +23,9 @@@ lib-y := ctype.o string.o vsprintf.o cm
         rbtree.o radix-tree.o dump_stack.o timerqueue.o\
         idr.o int_sqrt.o extable.o \
         sha1.o md5.o irq_regs.o argv_split.o \
 -       proportions.o flex_proportions.o ratelimit.o show_mem.o \
 +       flex_proportions.o ratelimit.o show_mem.o \
         is_single_threaded.o plist.o decompress.o kobject_uevent.o \
 -       earlycpio.o seq_buf.o nmi_backtrace.o
 +       earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o
  
  obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
  lib-$(CONFIG_MMU) += ioremap.o
@@@ -48,6 -48,7 +48,7 @@@ obj-$(CONFIG_TEST_HEXDUMP) += test_hexd
  obj-y += kstrtox.o
  obj-$(CONFIG_TEST_BPF) += test_bpf.o
  obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
+ obj-$(CONFIG_TEST_HASH) += test_hash.o
  obj-$(CONFIG_TEST_KASAN) += test_kasan.o
  obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
  obj-$(CONFIG_TEST_LKM) += test_module.o
@@@ -178,7 -179,6 +179,7 @@@ obj-$(CONFIG_GENERIC_STRNLEN_USER) += s
  obj-$(CONFIG_GENERIC_NET_UTILS) += net_utils.o
  
  obj-$(CONFIG_SG_SPLIT) += sg_split.o
 +obj-$(CONFIG_SG_POOL) += sg_pool.o
  obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
  obj-$(CONFIG_IRQ_POLL) += irq_poll.o