An error occurred fetching the project authors.
  1. 08 Jul, 2019 1 commit
  2. 24 Apr, 2019 1 commit
    • NeilBrown's avatar
      sunrpc/cache: handle missing listeners better. · 9d69338c
      NeilBrown authored
      If no handler (such as rpc.mountd) has opened
      a cache 'channel', the sunrpc cache responds to
      all lookup requests with -ENOENT.  This is particularly
      important for the auth.unix.gid cache which is
      optional.
      
      If the channel was open briefly and an upcall was written to it,
      this upcall remains pending even when the handler closes the
      channel.  When an upcall is pending, the code currently
      doesn't check if there are still listeners, it only performs
      that check before sending an upcall.
      
      As the cache treads a recently closes channel (closed less than
      30 seconds ago) as "potentially still open", there is a
      reasonable sized window when a request can become pending
      in a closed channel, and thereby block lookups indefinitely.
      
      This can easily be demonstrated by running
        cat /proc/net/rpc/auth.unix.gid/channel
      
      and then trying to mount an NFS filesystem from this host.  It
      will block indefinitely (unless mountd is run with --manage-gids,
      or krb5 is used).
      
      When cache_check() finds that an upcall is pending, it should
      perform the "cache_listeners_exist()" exist test.  If no
      listeners do exist, the request should be negated.
      
      With this change in place, there can still be a 30second wait on
      mount, until the cache gives up waiting for a handler to come
      back, but this is much better than an indefinite wait.
      Signed-off-by: default avatarNeilBrown <neilb@suse.com>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      9d69338c
  3. 05 Apr, 2019 1 commit
    • NeilBrown's avatar
      sunrpc: don't mark uninitialised items as VALID. · d58431ea
      NeilBrown authored
      A recent commit added a call to cache_fresh_locked()
      when an expired item was found.
      The call sets the CACHE_VALID flag, so it is important
      that the item actually is valid.
      There are two ways it could be valid:
      1/ If ->update has been called to fill in relevant content
      2/ if CACHE_NEGATIVE is set, to say that content doesn't exist.
      
      An expired item that is waiting for an update will be neither.
      Setting CACHE_VALID will mean that a subsequent call to cache_put()
      will be likely to dereference uninitialised pointers.
      
      So we must make sure the item is valid, and we already have code to do
      that in try_to_negate_entry().  This takes the hash lock and so cannot
      be used directly, so take out the two lines that we need and use them.
      
      Now cache_fresh_locked() is certain to be called only on
      a valid item.
      
      Cc: stable@kernel.org # 2.6.35
      Fixes: 4ecd55ea ("sunrpc: fix cache_head leak due to queued request")
      Signed-off-by: default avatarNeilBrown <neilb@suse.com>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      d58431ea
  4. 04 Dec, 2018 1 commit
    • Vasily Averin's avatar
      sunrpc: fix cache_head leak due to queued request · 4ecd55ea
      Vasily Averin authored
      After commit d202cce8, an expired cache_head can be removed from the
      cache_detail's hash.
      
      However, the expired cache_head may be waiting for a reply from a
      previously submitted request. Such a cache_head has an increased
      refcounter and therefore it won't be freed after cache_put(freeme).
      
      Because the cache_head was removed from the hash it cannot be found
      during cache_clean() and can be leaked forever, together with stalled
      cache_request and other taken resources.
      
      In our case we noticed it because an entry in the export cache was
      holding a reference on a filesystem.
      
      Fixes d202cce8 ("sunrpc: never return expired entries in sunrpc_cache_lookup")
      Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
      Cc: stable@kernel.org # 2.6.35
      Signed-off-by: default avatarVasily Averin <vvs@virtuozzo.com>
      Reviewed-by: default avatarNeilBrown <neilb@suse.com>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      4ecd55ea
  5. 29 Oct, 2018 3 commits
  6. 03 Oct, 2018 1 commit
  7. 12 Jun, 2018 1 commit
    • Kees Cook's avatar
      treewide: kzalloc() -> kcalloc() · 6396bb22
      Kees Cook authored
      The kzalloc() function has a 2-factor argument form, kcalloc(). This
      patch replaces cases of:
      
              kzalloc(a * b, gfp)
      
      with:
              kcalloc(a * b, gfp)
      
      as well as handling cases of:
      
              kzalloc(a * b * c, gfp)
      
      with:
      
              kzalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kzalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kzalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kzalloc
      + kcalloc
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kzalloc(sizeof(THING) * C2, ...)
      |
        kzalloc(sizeof(TYPE) * C2, ...)
      |
        kzalloc(C1 * C2 * C3, ...)
      |
        kzalloc(C1 * C2, ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kzalloc
      + kcalloc
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      6396bb22
  8. 26 Mar, 2018 1 commit
  9. 19 Mar, 2018 1 commit
    • NeilBrown's avatar
      SUNRPC: cache: ignore timestamp written to 'flush' file. · 3b68e6ee
      NeilBrown authored
      The interface for flushing the sunrpc auth cache was poorly
      designed and has caused problems a number of times.
      
      The design is that you write a timestamp, and all entries
      created before that time are discarded.
      The most obvious problem is that this is not what people
      actually want.  They want to just flush the whole cache.
      The 1-second granularity can be a problem, as can the use
      of wall-clock time.
      
      A current problem is that code will write the current time to
      this file - expecting it to clear everything - and if the
      seconds number ticks over before this timestamp is checked,
      the test "then >= now" fails, and a full flush isn't forced.
      
      So lets just drop the subtleties and always flush the whole
      cache.  The worst this could do is impose an extra cost
      refilling it, but that would require someone to be using
      non-standard tools.
      
      We still report an error if the string written is not a number,
      but we cause any valid number to flush the whole cache.
      Reported-by: default avatar"Wang, Alan 1. (NSB - CN/Hangzhou)" <alan.1.wang@nokia-sbell.com>
      Signed-off-by: default avatarNeilBrown <neilb@suse.com>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      3b68e6ee
  10. 11 Feb, 2018 1 commit
    • Linus Torvalds's avatar
      vfs: do bulk POLL* -> EPOLL* replacement · a9a08845
      Linus Torvalds authored
      This is the mindless scripted replacement of kernel use of POLL*
      variables as described by Al, done by this script:
      
          for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP NVAL MSG; do
              L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'`
              for f in $L; do sed -i "-es/^\([^\"]*\)\(\<POLL$V\>\)/\\1E\\2/" $f; done
          done
      
      with de-mangling cleanups yet to come.
      
      NOTE! On almost all architectures, the EPOLL* constants have the same
      values as the POLL* constants do.  But they keyword here is "almost".
      For various bad reasons they aren't the same, and epoll() doesn't
      actually work quite correctly in some cases due to this on Sparc et al.
      
      The next patch from Al will sort out the final differences, and we
      should be all done.
      Scripted-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      a9a08845
  11. 27 Nov, 2017 2 commits
  12. 08 Feb, 2017 4 commits
  13. 31 Jan, 2017 1 commit
  14. 14 Jan, 2017 1 commit
    • Peter Zijlstra's avatar
      locking/atomic, kref: Add kref_read() · 2c935bc5
      Peter Zijlstra authored
      Since we need to change the implementation, stop exposing internals.
      
      Provide kref_read() to read the current reference count; typically
      used for debug messages.
      
      Kills two anti-patterns:
      
      	atomic_read(&kref->refcount)
      	kref->refcount.counter
      Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: linux-kernel@vger.kernel.org
      Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
      2c935bc5
  15. 24 Dec, 2016 1 commit
  16. 27 Sep, 2016 1 commit
    • Ke Wang's avatar
      sunrpc: queue work on system_power_efficient_wq · 77b00bc0
      Ke Wang authored
      sunrpc uses workqueue to clean cache regulary. There is no real dependency
      of executing work on the cpu which queueing it.
      
      On a idle system, especially for a heterogeneous systems like big.LITTLE,
      it is observed that the big idle cpu was woke up many times just to service
      this work, which against the principle of power saving. It would be better
      if we can schedule it on a cpu which the scheduler believes to be the most
      appropriate one.
      
      After apply this patch, system_wq will be replaced by
      system_power_efficient_wq for sunrpc. This functionality is enabled when
      CONFIG_WQ_POWER_EFFICIENT is selected.
      Signed-off-by: default avatarKe Wang <ke.wang@spreadtrum.com>
      Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
      77b00bc0
  17. 13 Jul, 2016 1 commit
  18. 04 Apr, 2016 1 commit
    • Kirill A. Shutemov's avatar
      mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros · 09cbfeaf
      Kirill A. Shutemov authored
      PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
      ago with promise that one day it will be possible to implement page
      cache with bigger chunks than PAGE_SIZE.
      
      This promise never materialized.  And unlikely will.
      
      We have many places where PAGE_CACHE_SIZE assumed to be equal to
      PAGE_SIZE.  And it's constant source of confusion on whether
      PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
      especially on the border between fs and mm.
      
      Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
      breakage to be doable.
      
      Let's stop pretending that pages in page cache are special.  They are
      not.
      
      The changes are pretty straight-forward:
      
       - <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
      
       - <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
      
       - PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
      
       - page_cache_get() -> get_page();
      
       - page_cache_release() -> put_page();
      
      This patch contains automated changes generated with coccinelle using
      script below.  For some reason, coccinelle doesn't patch header files.
      I've called spatch for them manually.
      
      The only adjustment after coccinelle is revert of changes to
      PAGE_CAHCE_ALIGN definition: we are going to drop it later.
      
      There are few places in the code where coccinelle didn't reach.  I'll
      fix them manually in a separate patch.  Comments and documentation also
      will be addressed with the separate patch.
      
      virtual patch
      
      @@
      expression E;
      @@
      - E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
      + E
      
      @@
      expression E;
      @@
      - E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
      + E
      
      @@
      @@
      - PAGE_CACHE_SHIFT
      + PAGE_SHIFT
      
      @@
      @@
      - PAGE_CACHE_SIZE
      + PAGE_SIZE
      
      @@
      @@
      - PAGE_CACHE_MASK
      + PAGE_MASK
      
      @@
      expression E;
      @@
      - PAGE_CACHE_ALIGN(E)
      + PAGE_ALIGN(E)
      
      @@
      expression E;
      @@
      - page_cache_get(E)
      + get_page(E)
      
      @@
      expression E;
      @@
      - page_cache_release(E)
      + put_page(E)
      Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
      Acked-by: default avatarMichal Hocko <mhocko@suse.com>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      09cbfeaf
  19. 17 Mar, 2016 1 commit
  20. 23 Feb, 2016 1 commit
    • Stefan Hajnoczi's avatar
      sunrpc/cache: fix off-by-one in qword_get() · b7052cd7
      Stefan Hajnoczi authored
      The qword_get() function NUL-terminates its output buffer.  If the input
      string is in hex format \xXXXX... and the same length as the output
      buffer, there is an off-by-one:
      
        int qword_get(char **bpp, char *dest, int bufsize)
        {
            ...
            while (len < bufsize) {
                ...
                *dest++ = (h << 4) | l;
                len++;
            }
            ...
            *dest = '\0';
            return len;
        }
      
      This patch ensures the NUL terminator doesn't fall outside the output
      buffer.
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      b7052cd7
  21. 22 Jan, 2016 1 commit
    • Al Viro's avatar
      wrappers for ->i_mutex access · 5955102c
      Al Viro authored
      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: default avatarAl Viro <viro@zeniv.linux.org.uk>
      5955102c
  22. 23 Oct, 2015 1 commit
    • Neil Brown's avatar
      sunrpc/cache: make cache flushing more reliable. · 77862036
      Neil Brown authored
      The caches used to store sunrpc authentication information can be
      flushed by writing a timestamp to a file in /proc.
      
      This timestamp has a one-second resolution and any entry in cache that
      was last_refreshed *before* that time is treated as expired.
      
      This is problematic as it is not possible to reliably flush the cache
      without interrupting NFS service.
      If the current time is written to the "flush" file, any entry that was
      added since the current second started will still be treated as valid.
      If one second beyond than the current time is written to the file
      then no entries can be valid until the second ticks over.  This will
      mean that no NFS request will be handled for up to 1 second.
      
      To resolve this issue we make two changes:
      
      1/ treat an entry as expired if the timestamp when it was last_refreshed
        is before *or the same as* the expiry time.  This means that current
        code which writes out the current time will now flush the cache
        reliably.
      
      2/ when a new entry in added to the cache -  set the last_refresh timestamp
        to 1 second *beyond* the current flush time, when that not in the
        past.
        This ensures that newly added entries will always be valid.
      
      Now that we have a very reliable way to flush the cache, and also
      since we are using "since-boot" timestamps which are monotonic,
      change cache_purge() to set the smallest future flush_time which
      will work, and leave it there: don't revert to '1'.
      
      Also disable the setting of the 'flush_time' far into the future.
      That has never been useful and is now awkward as it would cause
      last_refresh times to be strange.
      Finally: if a request is made to set the 'flush_time' to the current
      second, assume the intent is to flush the cache and advance it, if
      necessary, to 1 second beyond the current 'flush_time' so that all
      active entries will be deemed to be expired.
      
      As part of this we need to add a 'cache_detail' arg to cache_init()
      and cache_fresh_locked() so they can find the current ->flush_time.
      Signed-off-by: default avatarNeilBrown <neilb@suse.com>
      Reported-by: default avatarOlaf Kirch <okir@suse.com>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      77862036
  23. 13 Aug, 2015 3 commits
  24. 15 Apr, 2015 1 commit
    • Rasmus Villemoes's avatar
      lib/string_helpers.c: change semantics of string_escape_mem · 41416f23
      Rasmus Villemoes authored
      The current semantics of string_escape_mem are inadequate for one of its
      current users, vsnprintf().  If that is to honour its contract, it must
      know how much space would be needed for the entire escaped buffer, and
      string_escape_mem provides no way of obtaining that (short of allocating a
      large enough buffer (~4 times input string) to let it play with, and
      that's definitely a big no-no inside vsnprintf).
      
      So change the semantics for string_escape_mem to be more snprintf-like:
      Return the size of the output that would be generated if the destination
      buffer was big enough, but of course still only write to the part of dst
      it is allowed to, and (contrary to snprintf) don't do '\0'-termination.
      It is then up to the caller to detect whether output was truncated and to
      append a '\0' if desired.  Also, we must output partial escape sequences,
      otherwise a call such as snprintf(buf, 3, "%1pE", "\123") would cause
      printf to write a \0 to buf[2] but leaving buf[0] and buf[1] with whatever
      they previously contained.
      
      This also fixes a bug in the escaped_string() helper function, which used
      to unconditionally pass a length of "end-buf" to string_escape_mem();
      since the latter doesn't check osz for being insanely large, it would
      happily write to dst.  For example, kasprintf(GFP_KERNEL, "something and
      then %pE", ...); is an easy way to trigger an oops.
      
      In test-string_helpers.c, the -ENOMEM test is replaced with testing for
      getting the expected return value even if the buffer is too small.  We
      also ensure that nothing is written (by relying on a NULL pointer deref)
      if the output size is 0 by passing NULL - this has to work for
      kasprintf("%pE") to work.
      
      In net/sunrpc/cache.c, I think qword_add still has the same semantics.
      Someone should definitely double-check this.
      
      In fs/proc/array.c, I made the minimum possible change, but longer-term it
      should stop poking around in seq_file internals.
      
      [andriy.shevchenko@linux.intel.com: simplify qword_add]
      [andriy.shevchenko@linux.intel.com: add missed curly braces]
      Signed-off-by: default avatarRasmus Villemoes <linux@rasmusvillemoes.dk>
      Acked-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      41416f23
  25. 08 Mar, 2015 1 commit
  26. 09 Dec, 2014 1 commit
  27. 08 May, 2014 1 commit
  28. 14 Jan, 2014 1 commit
  29. 12 Dec, 2013 1 commit
  30. 14 Jul, 2013 1 commit
  31. 01 Jul, 2013 2 commits
    • NeilBrown's avatar
      sunrpc: Don't schedule an upcall on a replaced cache entry. · 0bebc633
      NeilBrown authored
      When a cache entry is replaced, the "expiry_time" get set to
      zero by a call to "cache_fresh_locked(..., 0)" at the end of
      "sunrpc_cache_update".
      
      This low expiry time makes cache_check() think that the 'refresh_age'
      is negative, so the 'age' is comparatively large and a refresh is
      triggered.
      However refreshing a replaced entry it pointless, it cannot achieve
      anything useful.
      
      So teach cache_check to ignore a low refresh_age when expiry_time
      is zero.
      Reported-by: default avatarBodo Stroesser <bstroesser@ts.fujitsu.com>
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      0bebc633
    • NeilBrown's avatar
      net/sunrpc: xpt_auth_cache should be ignored when expired. · 7715cde8
      NeilBrown authored
      commit d202cce8
          sunrpc: never return expired entries in sunrpc_cache_lookup
      
      moved the 'entry is expired' test from cache_check to
      sunrpc_cache_lookup, so that it happened early and some races could
      safely be ignored.
      
      However the ip_map (in svcauth_unix.c) has a separate single-item
      cache which allows quick lookup without locking.  An entry in this
      case would not be subject to the expiry test and so could be used
      well after it has expired.
      
      This is not normally a big problem because the first time it is used
      after it is expired an up-call will be scheduled to refresh the entry
      (if it hasn't been scheduled already) and the old entry will then
      be invalidated.  So on the second attempt to use it after it has
      expired, ip_map_cached_get will discard it.
      
      However that is subtle and not ideal, so replace the "!cache_valid"
      test with "cache_is_expired".
      In doing this we drop the test on the "CACHE_VALID" bit.  This is
      unnecessary as the bit is never cleared, and an entry will only
      be cached if the bit is set.
      Reported-by: default avatarBodo Stroesser <bstroesser@ts.fujitsu.com>
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      7715cde8