1. 29 5月, 2016 3 次提交
    • G
      <linux/hash.h>: Add support for architecture-specific functions · 468a9428
      George Spelvin 提交于
      This is just the infrastructure; there are no users yet.
      
      This is modelled on CONFIG_ARCH_RANDOM; a CONFIG_ symbol declares
      the existence of <asm/hash.h>.
      
      That file may define its own versions of various functions, and define
      HAVE_* symbols (no CONFIG_ prefix!) to suppress the generic ones.
      
      Included is a self-test (in lib/test_hash.c) that verifies the basics.
      It is NOT in general required that the arch-specific functions compute
      the same thing as the generic, but if a HAVE_* symbol is defined with
      the value 1, then equality is tested.
      Signed-off-by: NGeorge Spelvin <linux@sciencehorizons.net>
      Cc: Geert Uytterhoeven <geert@linux-m68k.org>
      Cc: Greg Ungerer <gerg@linux-m68k.org>
      Cc: Andreas Schwab <schwab@linux-m68k.org>
      Cc: Philippe De Muyter <phdm@macq.eu>
      Cc: linux-m68k@lists.linux-m68k.org
      Cc: Alistair Francis <alistai@xilinx.com>
      Cc: Michal Simek <michal.simek@xilinx.com>
      Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
      Cc: uclinux-h8-devel@lists.sourceforge.jp
      468a9428
    • G
      fs/namei.c: Improve dcache hash function · 2a18da7a
      George Spelvin 提交于
      Patch 0fed3ac8 improved the hash mixing, but the function is slower
      than necessary; there's a 7-instruction dependency chain (10 on x86)
      each loop iteration.
      
      Word-at-a-time access is a very tight loop (which is good, because
      link_path_walk() is one of the hottest code paths in the entire kernel),
      and the hash mixing function must not have a longer latency to avoid
      slowing it down.
      
      There do not appear to be any published fast hash functions that:
      1) Operate on the input a word at a time, and
      2) Don't need to know the length of the input beforehand, and
      3) Have a single iterated mixing function, not needing conditional
         branches or unrolling to distinguish different loop iterations.
      
      One of the algorithms which comes closest is Yann Collet's xxHash, but
      that's two dependent multiplies per word, which is too much.
      
      The key insights in this design are:
      
      1) Barring expensive ops like multiplies, to diffuse one input bit
         across 64 bits of hash state takes at least log2(64) = 6 sequentially
         dependent instructions.  That is more cycles than we'd like.
      2) An operation like "hash ^= hash << 13" requires a second temporary
         register anyway, and on a 2-operand machine like x86, it's three
         instructions.
      3) A better use of a second register is to hold a two-word hash state.
         With careful design, no temporaries are needed at all, so it doesn't
         increase register pressure.  And this gets rid of register copying
         on 2-operand machines, so the code is smaller and faster.
      4) Using two words of state weakens the requirement for one-round mixing;
         we now have two rounds of mixing before cancellation is possible.
      5) A two-word hash state also allows operations on both halves to be
         done in parallel, so on a superscalar processor we get more mixing
         in fewer cycles.
      
      I ended up using a mixing function inspired by the ChaCha and Speck
      round functions.  It is 6 simple instructions and 3 cycles per iteration
      (assuming multiply by 9 can be done by an "lea" instruction):
      
      		x ^= *input++;
      	y ^= x;	x = ROL(x, K1);
      	x += y;	y = ROL(y, K2);
      	y *= 9;
      
      Not only is this reversible, two consecutive rounds are reversible:
      if you are given the initial and final states, but not the intermediate
      state, it is possible to compute both input words.  This means that at
      least 3 words of input are required to create a collision.
      
      (It also has the property, used by hash_name() to avoid a branch, that
      it hashes all-zero to all-zero.)
      
      The rotate constants K1 and K2 were found by experiment.  The search took
      a sample of random initial states (I used 1023) and considered the effect
      of flipping each of the 64 input bits on each of the 128 output bits two
      rounds later.  Each of the 8192 pairs can be considered a biased coin, and
      adding up the Shannon entropy of all of them produces a score.
      
      The best-scoring shifts also did well in other tests (flipping bits in y,
      trying 3 or 4 rounds of mixing, flipping all 64*63/2 pairs of input bits),
      so the choice was made with the additional constraint that the sum of the
      shifts is odd and not too close to the word size.
      
      The final state is then folded into a 32-bit hash value by a less carefully
      optimized multiply-based scheme.  This also has to be fast, as pathname
      components tend to be short (the most common case is one iteration!), but
      there's some room for latency, as there is a fair bit of intervening logic
      before the hash value is used for anything.
      
      (Performance verified with "bonnie++ -s 0 -n 1536:-2" on tmpfs.  I need
      a better benchmark; the numbers seem to show a slight dip in performance
      between 4.6.0 and this patch, but they're too noisy to quote.)
      
      Special thanks to Bruce fields for diligent testing which uncovered a
      nasty fencepost error in an earlier version of this patch.
      
      [checkpatch.pl formatting complaints noted and respectfully disagreed with.]
      Signed-off-by: NGeorge Spelvin <linux@sciencehorizons.net>
      Tested-by: NJ. Bruce Fields <bfields@redhat.com>
      2a18da7a
    • G
      fs/namei.c: Add hashlen_string() function · fcfd2fbf
      George Spelvin 提交于
      We'd like to make more use of the highly-optimized dcache hash functions
      throughout the kernel, rather than have every subsystem create its own,
      and a function that hashes basic null-terminated strings is required
      for that.
      
      (The name is to emphasize that it returns both hash and length.)
      
      It's actually useful in the dcache itself, specifically d_alloc_name().
      Other uses in the next patch.
      
      full_name_hash() is also tweaked to make it more generally useful:
      1) Take a "char *" rather than "unsigned char *" argument, to
         be consistent with hash_name().
      2) Handle zero-length inputs.  If we want more callers, we don't want
         to make them worry about corner cases.
      Signed-off-by: NGeorge Spelvin <linux@sciencehorizons.net>
      fcfd2fbf
  2. 17 5月, 2016 1 次提交
  3. 11 5月, 2016 2 次提交
    • M
      vfs: add lookup_hash() helper · 3c9fe8cd
      Miklos Szeredi 提交于
      Overlayfs needs lookup without inode_permission() and already has the name
      hash (in form of dentry->d_name on overlayfs dentry).  It also doesn't
      support filesystems with d_op->d_hash() so basically it only needs
      the actual hashed lookup from lookup_one_len_unlocked()
      
      So add a new helper that does unlocked lookup of a hashed name.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      3c9fe8cd
    • M
      vfs: rename: check backing inode being equal · 9409e22a
      Miklos Szeredi 提交于
      If a file is renamed to a hardlink of itself POSIX specifies that rename(2)
      should do nothing and return success.
      
      This condition is checked in vfs_rename().  However it won't detect hard
      links on overlayfs where these are given separate inodes on the overlayfs
      layer.
      
      Overlayfs itself detects this condition and returns success without doing
      anything, but then vfs_rename() will proceed as if this was a successful
      rename (detach_mounts(), d_move()).
      
      The correct thing to do is to detect this condition before even calling
      into overlayfs.  This patch does this by calling vfs_select_inode() to get
      the underlying inodes.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      Cc: <stable@vger.kernel.org> # v4.2+
      9409e22a
  4. 01 5月, 2016 1 次提交
    • A
      atomic_open(): fix the handling of create_error · 10c64cea
      Al Viro 提交于
      * if we have a hashed negative dentry and either CREAT|EXCL on
      r/o filesystem, or CREAT|TRUNC on r/o filesystem, or CREAT|EXCL
      with failing may_o_create(), we should fail with EROFS or the
      error may_o_create() has returned, but not ENOENT.  Which is what
      the current code ends up returning.
      
      * if we have CREAT|TRUNC hitting a regular file on a read-only
      filesystem, we can't fail with EROFS here.  At the very least,
      not until we'd done follow_managed() - we might have a writable
      file (or a device, for that matter) bound on top of that one.
      Moreover, the code downstream will see that O_TRUNC and attempt
      to grab the write access (*after* following possible mount), so
      if we really should fail with EROFS, it will happen.  No need
      to do that inside atomic_open().
      
      The real logics is much simpler than what the current code is
      trying to do - if we decided to go for simple lookup, ended
      up with a negative dentry *and* had create_error set, fail with
      create_error.  No matter whether we'd got that negative dentry
      from lookup_real() or had found it in dcache.
      
      Cc: stable@vger.kernel.org # v3.6+
      Acked-by: NMiklos Szeredi <mszeredi@redhat.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      10c64cea
  5. 31 3月, 2016 1 次提交
  6. 14 3月, 2016 7 次提交
  7. 06 3月, 2016 2 次提交
  8. 28 2月, 2016 4 次提交
  9. 23 1月, 2016 1 次提交
    • A
      wrappers for ->i_mutex access · 5955102c
      Al Viro 提交于
      parallel to mutex_{lock,unlock,trylock,is_locked,lock_nested},
      inode_foo(inode) being mutex_foo(&inode->i_mutex).
      
      Please, use those for access to ->i_mutex; over the coming cycle
      ->i_mutex will become rwsem, with ->lookup() done with it held
      only shared.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      5955102c
  10. 09 1月, 2016 1 次提交
    • N
      nfsd: don't hold i_mutex over userspace upcalls · bbddca8e
      NeilBrown 提交于
      We need information about exports when crossing mountpoints during
      lookup or NFSv4 readdir.  If we don't already have that information
      cached, we may have to ask (and wait for) rpc.mountd.
      
      In both cases we currently hold the i_mutex on the parent of the
      directory we're asking rpc.mountd about.  We've seen situations where
      rpc.mountd performs some operation on that directory that tries to take
      the i_mutex again, resulting in deadlock.
      
      With some care, we may be able to avoid that in rpc.mountd.  But it
      seems better just to avoid holding a mutex while waiting on userspace.
      
      It appears that lookup_one_len is pretty much the only operation that
      needs the i_mutex.  So we could just drop the i_mutex elsewhere and do
      something like
      
      	mutex_lock()
      	lookup_one_len()
      	mutex_unlock()
      
      In many cases though the lookup would have been cached and not required
      the i_mutex, so it's more efficient to create a lookup_one_len() variant
      that only takes the i_mutex when necessary.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Signed-off-by: NJ. Bruce Fields <bfields@redhat.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      bbddca8e
  11. 04 1月, 2016 1 次提交
  12. 31 12月, 2015 1 次提交
  13. 09 12月, 2015 3 次提交
    • A
      teach page_get_link() to work in RCU mode · d3883d4f
      Al Viro 提交于
      more or less along the lines of Neil's patchset, sans the insanity
      around kmap().
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      d3883d4f
    • A
      replace ->follow_link() with new method that could stay in RCU mode · 6b255391
      Al Viro 提交于
      new method: ->get_link(); replacement of ->follow_link().  The differences
      are:
      	* inode and dentry are passed separately
      	* might be called both in RCU and non-RCU mode;
      the former is indicated by passing it a NULL dentry.
      	* when called that way it isn't allowed to block
      and should return ERR_PTR(-ECHILD) if it needs to be called
      in non-RCU mode.
      
      It's a flagday change - the old method is gone, all in-tree instances
      converted.  Conversion isn't hard; said that, so far very few instances
      do not immediately bail out when called in RCU mode.  That'll change
      in the next commits.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      6b255391
    • A
      don't put symlink bodies in pagecache into highmem · 21fc61c7
      Al Viro 提交于
      kmap() in page_follow_link_light() needed to go - allowing to hold
      an arbitrary number of kmaps for long is a great way to deadlocking
      the system.
      
      new helper (inode_nohighmem(inode)) needs to be used for pagecache
      symlinks inodes; done for all in-tree cases.  page_follow_link_light()
      instrumented to yell about anything missed.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      21fc61c7
  14. 07 12月, 2015 7 次提交
  15. 07 11月, 2015 1 次提交
  16. 28 10月, 2015 1 次提交
    • D
      namei: permit linking with CAP_FOWNER in userns · f2ca3796
      Dirk Steinmetz 提交于
      Attempting to hardlink to an unsafe file (e.g. a setuid binary) from
      within an unprivileged user namespace fails, even if CAP_FOWNER is held
      within the namespace. This may cause various failures, such as a gentoo
      installation within a lxc container failing to build and install specific
      packages.
      
      This change permits hardlinking of files owned by mapped uids, if
      CAP_FOWNER is held for that namespace. Furthermore, it improves consistency
      by using the existing inode_owner_or_capable(), which is aware of
      namespaced capabilities as of 23adbe12 ("fs,userns: Change
      inode_capable to capable_wrt_inode_uidgid").
      Signed-off-by: NDirk Steinmetz <public@rsjtdrjgfuzkfg.com>
      
      This is hitting us in Ubuntu during some dpkg upgrades in containers.
      When upgrading a file dpkg creates a hard link to the old file to back
      it up before overwriting it. When packages upgrade suid files owned by a
      non-root user the link isn't permitted, and the package upgrade fails.
      This patch fixes our problem.
      Tested-by: NSeth Forshee <seth.forshee@canonical.com>
      Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
      f2ca3796
  17. 11 10月, 2015 1 次提交
    • T
      namei: results of d_is_negative() should be checked after dentry revalidation · daf3761c
      Trond Myklebust 提交于
      Leandro Awa writes:
       "After switching to version 4.1.6, our parallelized and distributed
        workflows now fail consistently with errors of the form:
      
        T34: ./regex.c:39:22: error: config.h: No such file or directory
      
        From our 'git bisect' testing, the following commit appears to be the
        possible cause of the behavior we've been seeing: commit 766c4cbf"
      
      Al Viro says:
       "What happens is that 766c4cbf got the things subtly wrong.
      
        We used to treat d_is_negative() after lookup_fast() as "fall with
        ENOENT".  That was wrong - checking ->d_flags outside of ->d_seq
        protection is unreliable and failing with hard error on what should've
        fallen back to non-RCU pathname resolution is a bug.
      
        Unfortunately, we'd pulled the test too far up and ran afoul of
        another kind of staleness.  The dentry might have been absolutely
        stable from the RCU point of view (and we might be on UP, etc), but
        stale from the remote fs point of view.  If ->d_revalidate() returns
        "it's actually stale", dentry gets thrown away and the original code
        wouldn't even have looked at its ->d_flags.
      
        What we need is to check ->d_flags where 766c4cbf does (prior to
        ->d_seq validation) but only use the result in cases where we do not
        discard this dentry outright"
      Reported-by: NLeandro Awa <lawa@nvidia.com>
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=104911
      Fixes: 766c4cbf ("namei: d_is_negative() should be checked...")
      Tested-by: NLeandro Awa <lawa@nvidia.com>
      Cc: stable@vger.kernel.org # v4.1+
      Signed-off-by: NTrond Myklebust <trond.myklebust@primarydata.com>
      Acked-by: NAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      daf3761c
  18. 29 9月, 2015 1 次提交
  19. 11 9月, 2015 1 次提交