1. 19 10月, 2021 1 次提交
  2. 15 10月, 2021 1 次提交
  3. 03 6月, 2021 2 次提交
  4. 12 1月, 2021 1 次提交
    • N
      NFS: switch nfsiod to be an UNBOUND workqueue. · 5b26190a
      NeilBrown 提交于
      stable inclusion
      from stable-5.10.4
      commit eb9cc35ae98be96264791dac581eeb6ba95c53ab
      bugzilla: 46903
      
      --------------------------------
      
      [ Upstream commit bf701b76 ]
      
      nfsiod is currently a concurrency-managed workqueue (CMWQ).
      This means that workitems scheduled to nfsiod on a given CPU are queued
      behind all other work items queued on any CMWQ on the same CPU.  This
      can introduce unexpected latency.
      
      Occaionally nfsiod can even cause excessive latency.  If the work item
      to complete a CLOSE request calls the final iput() on an inode, the
      address_space of that inode will be dismantled.  This takes time
      proportional to the number of in-memory pages, which on a large host
      working on large files (e.g..  5TB), can be a large number of pages
      resulting in a noticable number of seconds.
      
      We can avoid these latency problems by switching nfsiod to WQ_UNBOUND.
      This causes each concurrent work item to gets a dedicated thread which
      can be scheduled to an idle CPU.
      
      There is precedent for this as several other filesystems use WQ_UNBOUND
      workqueue for handling various async events.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Fixes: ada609ee ("workqueue: use WQ_MEM_RECLAIM instead of WQ_RESCUER")
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      Signed-off-by: NChen Jun <chenjun102@huawei.com>
      Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
      5b26190a
  5. 14 7月, 2020 2 次提交
  6. 13 7月, 2020 1 次提交
  7. 12 6月, 2020 1 次提交
    • Z
      nfs: set invalid blocks after NFSv4 writes · 3a39e778
      Zheng Bin 提交于
      Use the following command to test nfsv4(size of file1M is 1MB):
      mount -t nfs -o vers=4.0,actimeo=60 127.0.0.1/dir1 /mnt
      cp file1M /mnt
      du -h /mnt/file1M  -->0 within 60s, then 1M
      
      When write is done(cp file1M /mnt), will call this:
      nfs_writeback_done
        nfs4_write_done
          nfs4_write_done_cb
            nfs_writeback_update_inode
              nfs_post_op_update_inode_force_wcc_locked(change, ctime, mtime
      nfs_post_op_update_inode_force_wcc_locked
         nfs_set_cache_invalid
         nfs_refresh_inode_locked
           nfs_update_inode
      
      nfsd write response contains change, ctime, mtime, the flag will be
      clear after nfs_update_inode. Howerver, write response does not contain
      space_used, previous open response contains space_used whose value is 0,
      so inode->i_blocks is still 0.
      
      nfs_getattr  -->called by "du -h"
        do_update |= force_sync || nfs_attribute_cache_expired -->false in 60s
        cache_validity = READ_ONCE(NFS_I(inode)->cache_validity)
        do_update |= cache_validity & (NFS_INO_INVALID_ATTR    -->false
        if (do_update) {
              __nfs_revalidate_inode
        }
      
      Within 60s, does not send getattr request to nfsd, thus "du -h /mnt/file1M"
      is 0.
      
      Add a NFS_INO_INVALID_BLOCKS flag, set it when nfsv4 write is done.
      
      Fixes: 16e14375 ("NFS: More fine grained attribute tracking")
      Signed-off-by: NZheng Bin <zhengbin13@huawei.com>
      Signed-off-by: NAnna Schumaker <Anna.Schumaker@Netapp.com>
      3a39e778
  8. 07 4月, 2020 1 次提交
  9. 16 3月, 2020 1 次提交
  10. 13 2月, 2020 1 次提交
  11. 04 2月, 2020 1 次提交
  12. 15 1月, 2020 1 次提交
    • T
      NFS: Add mount option 'softreval' · c74dfe97
      Trond Myklebust 提交于
      Add a mount option 'softreval' that allows attribute revalidation 'getattr'
      calls to time out, and causes them to fall back to using the cached
      attributes.
      The use case for this option is for ensuring that we can still (slowly)
      traverse paths and use cached information even when the server is down.
      Once the server comes back up again, the getattr calls start succeeding,
      and the caches will revalidate as usual.
      
      The 'softreval' mount option is automatically enabled if you have
      specified 'softerr'.  It can be turned off using the options
      'nosoftreval', or 'hard'.
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      Signed-off-by: NAnna Schumaker <Anna.Schumaker@Netapp.com>
      c74dfe97
  13. 04 11月, 2019 1 次提交
  14. 03 9月, 2019 1 次提交
  15. 19 8月, 2019 1 次提交
  16. 07 7月, 2019 4 次提交
  17. 21 5月, 2019 1 次提交
  18. 02 5月, 2019 1 次提交
  19. 26 4月, 2019 1 次提交
  20. 21 2月, 2019 1 次提交
  21. 20 12月, 2018 2 次提交
    • N
      NFS/NFSD/SUNRPC: replace generic creds with 'struct cred'. · a52458b4
      NeilBrown 提交于
      SUNRPC has two sorts of credentials, both of which appear as
      "struct rpc_cred".
      There are "generic credentials" which are supplied by clients
      such as NFS and passed in 'struct rpc_message' to indicate
      which user should be used to authorize the request, and there
      are low-level credentials such as AUTH_NULL, AUTH_UNIX, AUTH_GSS
      which describe the credential to be sent over the wires.
      
      This patch replaces all the generic credentials by 'struct cred'
      pointers - the credential structure used throughout Linux.
      
      For machine credentials, there is a special 'struct cred *' pointer
      which is statically allocated and recognized where needed as
      having a special meaning.  A look-up of a low-level cred will
      map this to a machine credential.
      Signed-off-by: NNeilBrown <neilb@suse.com>
      Acked-by: NJ. Bruce Fields <bfields@redhat.com>
      Signed-off-by: NAnna Schumaker <Anna.Schumaker@Netapp.com>
      a52458b4
    • N
      NFS: move credential expiry tracking out of SUNRPC into NFS. · ddf529ee
      NeilBrown 提交于
      NFS needs to know when a credential is about to expire so that
      it can modify write-back behaviour to finish the write inside the
      expiry time.
      It currently uses functions in SUNRPC code which make use of a
      fairly complex callback scheme and flags in the generic credientials.
      
      As I am working to discard the generic credentials, this has to change.
      
      This patch moves the logic into NFS, in part by finding and caching
      the low-level credential in the open_context.  We then make direct
      cred-api calls on that.
      
      This makes the code much simpler and removes a dependency on generic
      rpc credentials.
      Signed-off-by: NNeilBrown <neilb@suse.com>
      Signed-off-by: NAnna Schumaker <Anna.Schumaker@Netapp.com>
      ddf529ee
  22. 01 10月, 2018 3 次提交
  23. 06 6月, 2018 1 次提交
    • D
      vfs: change inode times to use struct timespec64 · 95582b00
      Deepa Dinamani 提交于
      struct timespec is not y2038 safe. Transition vfs to use
      y2038 safe struct timespec64 instead.
      
      The change was made with the help of the following cocinelle
      script. This catches about 80% of the changes.
      All the header file and logic changes are included in the
      first 5 rules. The rest are trivial substitutions.
      I avoid changing any of the function signatures or any other
      filesystem specific data structures to keep the patch simple
      for review.
      
      The script can be a little shorter by combining different cases.
      But, this version was sufficient for my usecase.
      
      virtual patch
      
      @ depends on patch @
      identifier now;
      @@
      - struct timespec
      + struct timespec64
        current_time ( ... )
        {
      - struct timespec now = current_kernel_time();
      + struct timespec64 now = current_kernel_time64();
        ...
      - return timespec_trunc(
      + return timespec64_trunc(
        ... );
        }
      
      @ depends on patch @
      identifier xtime;
      @@
       struct \( iattr \| inode \| kstat \) {
       ...
      -       struct timespec xtime;
      +       struct timespec64 xtime;
       ...
       }
      
      @ depends on patch @
      identifier t;
      @@
       struct inode_operations {
       ...
      int (*update_time) (...,
      -       struct timespec t,
      +       struct timespec64 t,
      ...);
       ...
       }
      
      @ depends on patch @
      identifier t;
      identifier fn_update_time =~ "update_time$";
      @@
       fn_update_time (...,
      - struct timespec *t,
      + struct timespec64 *t,
       ...) { ... }
      
      @ depends on patch @
      identifier t;
      @@
      lease_get_mtime( ... ,
      - struct timespec *t
      + struct timespec64 *t
        ) { ... }
      
      @te depends on patch forall@
      identifier ts;
      local idexpression struct inode *inode_node;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn_update_time =~ "update_time$";
      identifier fn;
      expression e, E3;
      local idexpression struct inode *node1;
      local idexpression struct inode *node2;
      local idexpression struct iattr *attr1;
      local idexpression struct iattr *attr2;
      local idexpression struct iattr attr;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      @@
      (
      (
      - struct timespec ts;
      + struct timespec64 ts;
      |
      - struct timespec ts = current_time(inode_node);
      + struct timespec64 ts = current_time(inode_node);
      )
      
      <+... when != ts
      (
      - timespec_equal(&inode_node->i_xtime, &ts)
      + timespec64_equal(&inode_node->i_xtime, &ts)
      |
      - timespec_equal(&ts, &inode_node->i_xtime)
      + timespec64_equal(&ts, &inode_node->i_xtime)
      |
      - timespec_compare(&inode_node->i_xtime, &ts)
      + timespec64_compare(&inode_node->i_xtime, &ts)
      |
      - timespec_compare(&ts, &inode_node->i_xtime)
      + timespec64_compare(&ts, &inode_node->i_xtime)
      |
      ts = current_time(e)
      |
      fn_update_time(..., &ts,...)
      |
      inode_node->i_xtime = ts
      |
      node1->i_xtime = ts
      |
      ts = inode_node->i_xtime
      |
      <+... attr1->ia_xtime ...+> = ts
      |
      ts = attr1->ia_xtime
      |
      ts.tv_sec
      |
      ts.tv_nsec
      |
      btrfs_set_stack_timespec_sec(..., ts.tv_sec)
      |
      btrfs_set_stack_timespec_nsec(..., ts.tv_nsec)
      |
      - ts = timespec64_to_timespec(
      + ts =
      ...
      -)
      |
      - ts = ktime_to_timespec(
      + ts = ktime_to_timespec64(
      ...)
      |
      - ts = E3
      + ts = timespec_to_timespec64(E3)
      |
      - ktime_get_real_ts(&ts)
      + ktime_get_real_ts64(&ts)
      |
      fn(...,
      - ts
      + timespec64_to_timespec(ts)
      ,...)
      )
      ...+>
      (
      <... when != ts
      - return ts;
      + return timespec64_to_timespec(ts);
      ...>
      )
      |
      - timespec_equal(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_equal(&node1->i_xtime2, &node2->i_xtime2)
      |
      - timespec_equal(&node1->i_xtime1, &attr2->ia_xtime2)
      + timespec64_equal(&node1->i_xtime2, &attr2->ia_xtime2)
      |
      - timespec_compare(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_compare(&node1->i_xtime1, &node2->i_xtime2)
      |
      node1->i_xtime1 =
      - timespec_trunc(attr1->ia_xtime1,
      + timespec64_trunc(attr1->ia_xtime1,
      ...)
      |
      - attr1->ia_xtime1 = timespec_trunc(attr2->ia_xtime2,
      + attr1->ia_xtime1 =  timespec64_trunc(attr2->ia_xtime2,
      ...)
      |
      - ktime_get_real_ts(&attr1->ia_xtime1)
      + ktime_get_real_ts64(&attr1->ia_xtime1)
      |
      - ktime_get_real_ts(&attr.ia_xtime1)
      + ktime_get_real_ts64(&attr.ia_xtime1)
      )
      
      @ depends on patch @
      struct inode *node;
      struct iattr *attr;
      identifier fn;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      expression e;
      @@
      (
      - fn(node->i_xtime);
      + fn(timespec64_to_timespec(node->i_xtime));
      |
       fn(...,
      - node->i_xtime);
      + timespec64_to_timespec(node->i_xtime));
      |
      - e = fn(attr->ia_xtime);
      + e = fn(timespec64_to_timespec(attr->ia_xtime));
      )
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      )
      ...+>
      }
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      struct kstat *stat;
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier i_xtime =~ "^i_[acm]time$";
      identifier xtime =~ "^[acm]time$";
      identifier fn, ret;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(stat->xtime);
      ret = fn (...,
      - &stat->xtime);
      + &ts);
      )
      ...+>
      }
      
      @ depends on patch @
      struct inode *node;
      struct inode *node2;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier i_xtime3 =~ "^i_[acm]time$";
      struct iattr *attrp;
      struct iattr *attrp2;
      struct iattr attr ;
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      struct kstat *stat;
      struct kstat stat1;
      struct timespec64 ts;
      identifier xtime =~ "^[acmb]time$";
      expression e;
      @@
      (
      ( node->i_xtime2 \| attrp->ia_xtime2 \| attr.ia_xtime2 \) = node->i_xtime1  ;
      |
       node->i_xtime2 = \( node2->i_xtime1 \| timespec64_trunc(...) \);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       stat->xtime = node2->i_xtime1;
      |
       stat1.xtime = node2->i_xtime1;
      |
      ( node->i_xtime2 \| attrp->ia_xtime2 \) = attrp->ia_xtime1  ;
      |
      ( attrp->ia_xtime1 \| attr.ia_xtime1 \) = attrp2->ia_xtime2;
      |
      - e = node->i_xtime1;
      + e = timespec64_to_timespec( node->i_xtime1 );
      |
      - e = attrp->ia_xtime1;
      + e = timespec64_to_timespec( attrp->ia_xtime1 );
      |
      node->i_xtime1 = current_time(...);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
       node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
      - node->i_xtime1 = e;
      + node->i_xtime1 = timespec_to_timespec64(e);
      )
      Signed-off-by: NDeepa Dinamani <deepa.kernel@gmail.com>
      Cc: <anton@tuxera.com>
      Cc: <balbi@kernel.org>
      Cc: <bfields@fieldses.org>
      Cc: <darrick.wong@oracle.com>
      Cc: <dhowells@redhat.com>
      Cc: <dsterba@suse.com>
      Cc: <dwmw2@infradead.org>
      Cc: <hch@lst.de>
      Cc: <hirofumi@mail.parknet.co.jp>
      Cc: <hubcap@omnibond.com>
      Cc: <jack@suse.com>
      Cc: <jaegeuk@kernel.org>
      Cc: <jaharkes@cs.cmu.edu>
      Cc: <jslaby@suse.com>
      Cc: <keescook@chromium.org>
      Cc: <mark@fasheh.com>
      Cc: <miklos@szeredi.hu>
      Cc: <nico@linaro.org>
      Cc: <reiserfs-devel@vger.kernel.org>
      Cc: <richard@nod.at>
      Cc: <sage@redhat.com>
      Cc: <sfrench@samba.org>
      Cc: <swhiteho@redhat.com>
      Cc: <tj@kernel.org>
      Cc: <trond.myklebust@primarydata.com>
      Cc: <tytso@mit.edu>
      Cc: <viro@zeniv.linux.org.uk>
      95582b00
  24. 05 6月, 2018 6 次提交
  25. 01 6月, 2018 2 次提交
  26. 26 5月, 2018 1 次提交