]> Git Repo - linux.git/commitdiff
Merge tag 'nfs-for-6.14-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
authorLinus Torvalds <[email protected]>
Tue, 28 Jan 2025 22:23:46 +0000 (14:23 -0800)
committerLinus Torvalds <[email protected]>
Tue, 28 Jan 2025 22:23:46 +0000 (14:23 -0800)
Pull NFS client updates from Anna Schumaker:
 "New Features:
   - Enable using direct IO with localio
   - Added localio related tracepoints

  Bugfixes:
   - Sunrpc fixes for working with a very large cl_tasks list
   - Fix a possible buffer overflow in nfs_sysfs_link_rpc_client()
   - Fixes for handling reconnections with localio
   - Fix how the NFS_FSCACHE kconfig option interacts with NETFS_SUPPORT
   - Fix COPY_NOTIFY xdr_buf size calculations
   - pNFS/Flexfiles fix for retrying requesting a layout segment for
     reads
   - Sunrpc fix for retrying on EKEYEXPIRED error when the TGT is
     expired

  Cleanups:
   - Various other nfs & nfsd localio cleanups
   - Prepratory patches for async copy improvements that are under
     development
   - Make OFFLOAD_CANCEL, LAYOUTSTATS, and LAYOUTERR moveable to other
     xprts
   - Add netns inum and srcaddr to debugfs rpc_xprt info"

* tag 'nfs-for-6.14-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (28 commits)
  SUNRPC: do not retry on EKEYEXPIRED when user TGT ticket expired
  sunrpc: add netns inum and srcaddr to debugfs rpc_xprt info
  pnfs/flexfiles: retry getting layout segment for reads
  NFSv4.2: make LAYOUTSTATS and LAYOUTERROR MOVEABLE
  NFSv4.2: mark OFFLOAD_CANCEL MOVEABLE
  NFSv4.2: fix COPY_NOTIFY xdr buf size calculation
  NFS: Rename struct nfs4_offloadcancel_data
  NFS: Fix typo in OFFLOAD_CANCEL comment
  NFS: CB_OFFLOAD can return NFS4ERR_DELAY
  nfs: Make NFS_FSCACHE select NETFS_SUPPORT instead of depending on it
  nfs: fix incorrect error handling in LOCALIO
  nfs: probe for LOCALIO when v3 client reconnects to server
  nfs: probe for LOCALIO when v4 client reconnects to server
  nfs/localio: remove redundant code and simplify LOCALIO enablement
  nfs_common: add nfs_localio trace events
  nfs_common: track all open nfsd_files per LOCALIO nfs_client
  nfs_common: rename nfslocalio nfs_uuid_lock to nfs_uuids_lock
  nfsd: nfsd_file_acquire_local no longer returns GC'd nfsd_file
  nfsd: rename nfsd_serv_ prefixed methods and variables with nfsd_net_
  nfsd: update percpu_ref to manage references on nfsd_net
  ...

1  2 
fs/nfsd/filecache.c
fs/nfsd/netns.h
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
include/linux/nfs_xdr.h

diff --combined fs/nfsd/filecache.c
index dc5c9d8e8202d5ca8fa72bc8f3912c62c485e076,2adf95e2b3792e7a6faba970ce78a48128aa0f79..0e552d873eaaa2ce0656b3521d2cd333b2226929
@@@ -39,6 -39,7 +39,7 @@@
  #include <linux/fsnotify.h>
  #include <linux/seq_file.h>
  #include <linux/rhashtable.h>
+ #include <linux/nfslocalio.h>
  
  #include "vfs.h"
  #include "nfsd.h"
@@@ -391,7 -392,7 +392,7 @@@ nfsd_file_put(struct nfsd_file *nf
  }
  
  /**
-  * nfsd_file_put_local - put nfsd_file reference and arm nfsd_serv_put in caller
+  * nfsd_file_put_local - put nfsd_file reference and arm nfsd_net_put in caller
   * @nf: nfsd_file of which to put the reference
   *
   * First save the associated net to return to caller, then put
@@@ -833,6 -834,14 +834,14 @@@ __nfsd_file_cache_purge(struct net *net
        struct nfsd_file *nf;
        LIST_HEAD(dispose);
  
+ #if IS_ENABLED(CONFIG_NFS_LOCALIO)
+       if (net) {
+               struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+               nfs_localio_invalidate_clients(&nn->local_clients,
+                                              &nn->local_clients_lock);
+       }
+ #endif
        rhltable_walk_enter(&nfsd_file_rhltable, &iter);
        do {
                rhashtable_walk_start(&iter);
@@@ -1222,10 -1231,9 +1231,9 @@@ nfsd_file_acquire(struct svc_rqst *rqst
   * a file.  The security implications of this should be carefully
   * considered before use.
   *
-  * The nfsd_file object returned by this API is reference-counted
-  * and garbage-collected. The object is retained for a few
-  * seconds after the final nfsd_file_put() in case the caller
-  * wants to re-use it.
+  * The nfsd_file_object returned by this API is reference-counted
+  * but not garbage-collected. The object is unhashed after the
+  * final nfsd_file_put().
   *
   * Return values:
   *   %nfs_ok - @pnf points to an nfsd_file with its reference
@@@ -1247,8 -1255,8 +1255,8 @@@ nfsd_file_acquire_local(struct net *net
        __be32 beres;
  
        beres = nfsd_file_do_acquire(NULL, net, cred, client,
-                                    fhp, may_flags, NULL, pnf, true);
+                                    fhp, may_flags, NULL, pnf, false);
 -      revert_creds(save_cred);
 +      put_cred(revert_creds(save_cred));
        return beres;
  }
  
diff --combined fs/nfsd/netns.h
index 4a07b8d0837b6b77733987022ac3ee3dde7ed966,187c4140b19139760fc2c1a487fe126c54448250..3e2d0fde80a7ce434ef2cce9f1666c2bd16ab2eb
@@@ -128,15 -128,22 +128,16 @@@ struct nfsd_net 
        seqlock_t writeverf_lock;
        unsigned char writeverf[8];
  
 -      /*
 -       * Max number of connections this nfsd container will allow. Defaults
 -       * to '0' which is means that it bases this on the number of threads.
 -       */
 -      unsigned int max_connections;
 -
        u32 clientid_base;
        u32 clientid_counter;
        u32 clverifier_counter;
  
        struct svc_info nfsd_info;
  #define nfsd_serv nfsd_info.serv
-       struct percpu_ref nfsd_serv_ref;
-       struct completion nfsd_serv_confirm_done;
-       struct completion nfsd_serv_free_done;
+       struct percpu_ref nfsd_net_ref;
+       struct completion nfsd_net_confirm_done;
+       struct completion nfsd_net_free_done;
  
        /*
         * clientid and stateid data for construction of net unique COPY
  
  #if IS_ENABLED(CONFIG_NFS_LOCALIO)
        /* Local clients to be invalidated when net is shut down */
+       spinlock_t              local_clients_lock;
        struct list_head        local_clients;
  #endif
  };
  extern bool nfsd_support_version(int vers);
  extern unsigned int nfsd_net_id;
  
- bool nfsd_serv_try_get(struct net *net);
- void nfsd_serv_put(struct net *net);
+ bool nfsd_net_try_get(struct net *net);
+ void nfsd_net_put(struct net *net);
  
  void nfsd_copy_write_verifier(__be32 verf[2], struct nfsd_net *nn);
  void nfsd_reset_write_verifier(struct nfsd_net *nn);
diff --combined fs/nfsd/nfsctl.c
index 95ea4393305bd38493b640fbaba2e8f57f5a501d,70347b0ecdc4325623cf0aa8f49b0942d843a8ec..ce2a71e4904c1d0b6dd4049a4ad38cbc3bc74824
@@@ -48,6 -48,7 +48,6 @@@ enum 
        NFSD_Versions,
        NFSD_Ports,
        NFSD_MaxBlkSize,
 -      NFSD_MaxConnections,
        NFSD_Filecache,
        NFSD_Leasetime,
        NFSD_Gracetime,
@@@ -67,6 -68,7 +67,6 @@@ static ssize_t write_pool_threads(struc
  static ssize_t write_versions(struct file *file, char *buf, size_t size);
  static ssize_t write_ports(struct file *file, char *buf, size_t size);
  static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
 -static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
  #ifdef CONFIG_NFSD_V4
  static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
  static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
@@@ -85,6 -87,7 +85,6 @@@ static ssize_t (*const write_op[])(stru
        [NFSD_Versions] = write_versions,
        [NFSD_Ports] = write_ports,
        [NFSD_MaxBlkSize] = write_maxblksize,
 -      [NFSD_MaxConnections] = write_maxconn,
  #ifdef CONFIG_NFSD_V4
        [NFSD_Leasetime] = write_leasetime,
        [NFSD_Gracetime] = write_gracetime,
@@@ -899,6 -902,44 +899,6 @@@ static ssize_t write_maxblksize(struct 
                                                        nfsd_max_blksize);
  }
  
 -/*
 - * write_maxconn - Set or report the current max number of connections
 - *
 - * Input:
 - *                    buf:            ignored
 - *                    size:           zero
 - * OR
 - *
 - * Input:
 - *                    buf:            C string containing an unsigned
 - *                                    integer value representing the new
 - *                                    number of max connections
 - *                    size:           non-zero length of C string in @buf
 - * Output:
 - *    On success:     passed-in buffer filled with '\n'-terminated C string
 - *                    containing numeric value of max_connections setting
 - *                    for this net namespace;
 - *                    return code is the size in bytes of the string
 - *    On error:       return code is zero or a negative errno value
 - */
 -static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
 -{
 -      char *mesg = buf;
 -      struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
 -      unsigned int maxconn = nn->max_connections;
 -
 -      if (size > 0) {
 -              int rv = get_uint(&mesg, &maxconn);
 -
 -              if (rv)
 -                      return rv;
 -              trace_nfsd_ctl_maxconn(netns(file), maxconn);
 -              nn->max_connections = maxconn;
 -      }
 -
 -      return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn);
 -}
 -
  #ifdef CONFIG_NFSD_V4
  static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
                                  time64_t *time, struct nfsd_net *nn)
@@@ -1331,6 -1372,7 +1331,6 @@@ static int nfsd_fill_super(struct super
                [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
                [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
 -              [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
                [NFSD_Filecache] = {"filecache", &nfsd_file_cache_stats_fops, S_IRUGO},
  #ifdef CONFIG_NFSD_V4
                [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
@@@ -2217,6 -2259,7 +2217,7 @@@ static __net_init int nfsd_net_init(str
        seqlock_init(&nn->writeverf_lock);
        nfsd_proc_stat_init(net);
  #if IS_ENABLED(CONFIG_NFS_LOCALIO)
+       spin_lock_init(&nn->local_clients_lock);
        INIT_LIST_HEAD(&nn->local_clients);
  #endif
        return 0;
@@@ -2234,14 -2277,15 +2235,15 @@@ out_export_error
   * nfsd_net_pre_exit - Disconnect localio clients from net namespace
   * @net: a network namespace that is about to be destroyed
   *
-  * This invalidated ->net pointers held by localio clients
+  * This invalidates ->net pointers held by localio clients
   * while they can still safely access nn->counter.
   */
  static __net_exit void nfsd_net_pre_exit(struct net *net)
  {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  
-       nfs_uuid_invalidate_clients(&nn->local_clients);
+       nfs_localio_invalidate_clients(&nn->local_clients,
+                                      &nn->local_clients_lock);
  }
  #endif
  
diff --combined fs/nfsd/nfssvc.c
index 3f5104ed70bf8b69d049d6205447f179ecd520ce,e937e2d0ce62c3973267f21f4a1ea9a8997f2887..9b3d6cff0e1e248f0b9cae9f4557c22a7cec165c
@@@ -70,6 -70,16 +70,6 @@@ static __be32                        nfsd_init_request(struc
   */
  DEFINE_MUTEX(nfsd_mutex);
  
 -/*
 - * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used.
 - * nfsd_drc_max_pages limits the total amount of memory available for
 - * version 4.1 DRC caches.
 - * nfsd_drc_pages_used tracks the current version 4.1 DRC memory usage.
 - */
 -DEFINE_SPINLOCK(nfsd_drc_lock);
 -unsigned long nfsd_drc_max_mem;
 -unsigned long nfsd_drc_mem_used;
 -
  #if IS_ENABLED(CONFIG_NFS_LOCALIO)
  static const struct svc_version *localio_versions[] = {
        [1] = &localio_version1,
@@@ -204,32 -214,32 +204,32 @@@ int nfsd_minorversion(struct nfsd_net *
        return 0;
  }
  
- bool nfsd_serv_try_get(struct net *net) __must_hold(rcu)
+ bool nfsd_net_try_get(struct net *net) __must_hold(rcu)
  {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  
-       return (nn && percpu_ref_tryget_live(&nn->nfsd_serv_ref));
+       return (nn && percpu_ref_tryget_live(&nn->nfsd_net_ref));
  }
  
- void nfsd_serv_put(struct net *net) __must_hold(rcu)
+ void nfsd_net_put(struct net *net) __must_hold(rcu)
  {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  
-       percpu_ref_put(&nn->nfsd_serv_ref);
+       percpu_ref_put(&nn->nfsd_net_ref);
  }
  
- static void nfsd_serv_done(struct percpu_ref *ref)
+ static void nfsd_net_done(struct percpu_ref *ref)
  {
-       struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_serv_ref);
+       struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_net_ref);
  
-       complete(&nn->nfsd_serv_confirm_done);
+       complete(&nn->nfsd_net_confirm_done);
  }
  
- static void nfsd_serv_free(struct percpu_ref *ref)
+ static void nfsd_net_free(struct percpu_ref *ref)
  {
-       struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_serv_ref);
+       struct nfsd_net *nn = container_of(ref, struct nfsd_net, nfsd_net_ref);
  
-       complete(&nn->nfsd_serv_free_done);
+       complete(&nn->nfsd_net_free_done);
  }
  
  /*
@@@ -426,6 -436,10 +426,10 @@@ static void nfsd_shutdown_net(struct ne
  
        if (!nn->nfsd_net_up)
                return;
+       percpu_ref_kill_and_confirm(&nn->nfsd_net_ref, nfsd_net_done);
+       wait_for_completion(&nn->nfsd_net_confirm_done);
        nfsd_export_flush(net);
        nfs4_state_shutdown_net(net);
        nfsd_reply_cache_shutdown(nn);
                lockd_down(net);
                nn->lockd_up = false;
        }
-       percpu_ref_exit(&nn->nfsd_serv_ref);
+       wait_for_completion(&nn->nfsd_net_free_done);
+       percpu_ref_exit(&nn->nfsd_net_ref);
        nn->nfsd_net_up = false;
        nfsd_shutdown_generic();
  }
@@@ -516,11 -533,6 +523,6 @@@ void nfsd_destroy_serv(struct net *net
  
        lockdep_assert_held(&nfsd_mutex);
  
-       percpu_ref_kill_and_confirm(&nn->nfsd_serv_ref, nfsd_serv_done);
-       wait_for_completion(&nn->nfsd_serv_confirm_done);
-       wait_for_completion(&nn->nfsd_serv_free_done);
-       /* percpu_ref_exit is called in nfsd_shutdown_net */
        spin_lock(&nfsd_notifier_lock);
        nn->nfsd_serv = NULL;
        spin_unlock(&nfsd_notifier_lock);
@@@ -565,6 -577,27 +567,6 @@@ void nfsd_reset_versions(struct nfsd_ne
                }
  }
  
 -/*
 - * Each session guarantees a negotiated per slot memory cache for replies
 - * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated
 - * NFSv4.1 server might want to use more memory for a DRC than a machine
 - * with mutiple services.
 - *
 - * Impose a hard limit on the number of pages for the DRC which varies
 - * according to the machines free pages. This is of course only a default.
 - *
 - * For now this is a #defined shift which could be under admin control
 - * in the future.
 - */
 -static void set_max_drc(void)
 -{
 -      #define NFSD_DRC_SIZE_SHIFT     7
 -      nfsd_drc_max_mem = (nr_free_buffer_pages()
 -                                      >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE;
 -      nfsd_drc_mem_used = 0;
 -      dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem);
 -}
 -
  static int nfsd_get_default_max_blksize(void)
  {
        struct sysinfo i;
@@@ -621,12 -654,12 +623,12 @@@ int nfsd_create_serv(struct net *net
        if (nn->nfsd_serv)
                return 0;
  
-       error = percpu_ref_init(&nn->nfsd_serv_ref, nfsd_serv_free,
+       error = percpu_ref_init(&nn->nfsd_net_ref, nfsd_net_free,
                                0, GFP_KERNEL);
        if (error)
                return error;
-       init_completion(&nn->nfsd_serv_free_done);
-       init_completion(&nn->nfsd_serv_confirm_done);
+       init_completion(&nn->nfsd_net_free_done);
+       init_completion(&nn->nfsd_net_confirm_done);
  
        if (nfsd_max_blksize == 0)
                nfsd_max_blksize = nfsd_get_default_max_blksize();
        if (serv == NULL)
                return -ENOMEM;
  
 -      serv->sv_maxconn = nn->max_connections;
        error = svc_bind(serv, net);
        if (error < 0) {
                svc_destroy(&serv);
        nn->nfsd_serv = serv;
        spin_unlock(&nfsd_notifier_lock);
  
 -      set_max_drc();
        /* check if the notifier is already set */
        if (atomic_inc_return(&nfsd_notifier_refcount) == 1) {
                register_inetaddr_notifier(&nfsd_inetaddr_notifier);
@@@ -921,7 -956,11 +923,7 @@@ nfsd(void *vrqstp
         * The main request loop
         */
        while (!svc_thread_should_stop(rqstp)) {
 -              /* Update sv_maxconn if it has changed */
 -              rqstp->rq_server->sv_maxconn = nn->max_connections;
 -
                svc_recv(rqstp);
 -
                nfsd_file_net_dispose(nn);
        }
  
diff --combined include/linux/nfs_xdr.h
index e74a87bb18a44be8b757039a0d527078034ced47,80766ff0a47cf9d7c217d10e963c382a10cada76..162b7c0c35557b9dd1530c17e7c9bb27576c8004
@@@ -1315,6 -1315,11 +1315,6 @@@ struct nfs4_fsid_present_res 
  
  #endif /* CONFIG_NFS_V4 */
  
 -struct nfstime4 {
 -      u64     seconds;
 -      u32     nseconds;
 -};
 -
  #ifdef CONFIG_NFS_V4_1
  
  struct pnfs_commit_bucket {
@@@ -1632,6 -1637,7 +1632,7 @@@ enum 
        NFS_IOHDR_RESEND_PNFS,
        NFS_IOHDR_RESEND_MDS,
        NFS_IOHDR_UNSTABLE_WRITES,
+       NFS_IOHDR_ODIRECT,
  };
  
  struct nfs_io_completion;
This page took 0.089818 seconds and 4 git commands to generate.