Commit 310c7585 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfsd-4.20' of git://linux-nfs.org/~bfields/linux

Pull nfsd updates from Bruce Fields:
 "Olga added support for the NFSv4.2 asynchronous copy protocol. We
  already supported COPY, by copying a limited amount of data and then
  returning a short result, letting the client resend. The asynchronous
  protocol should offer better performance at the expense of some
  complexity.

  The other highlight is Trond's work to convert the duplicate reply
  cache to a red-black tree, and to move it and some other server caches
  to RCU. (Previously these have meant taking global spinlocks on every
  RPC)

  Otherwise, some RDMA work and miscellaneous bugfixes"

* tag 'nfsd-4.20' of git://linux-nfs.org/~bfields/linux: (30 commits)
  lockd: fix access beyond unterminated strings in prints
  nfsd: Fix an Oops in free_session()
  nfsd: correctly decrement odstate refcount in error path
  svcrdma: Increase the default connection credit limit
  svcrdma: Remove try_module_get from backchannel
  svcrdma: Remove ->release_rqst call in bc reply handler
  svcrdma: Reduce max_send_sges
  nfsd: fix fall-through annotations
  knfsd: Improve lookup performance in the duplicate reply cache using an rbtree
  knfsd: Further simplify the cache lookup
  knfsd: Simplify NFS duplicate replay cache
  knfsd: Remove dead code from nfsd_cache_lookup
  SUNRPC: Simplify TCP receive code
  SUNRPC: Replace the cache_detail->hash_lock with a regular spinlock
  SUNRPC: Remove non-RCU protected lookup
  NFS: Fix up a typo in nfs_dns_ent_put
  NFS: Lockless DNS lookups
  knfsd: Lockless lookup of NFSv4 identities.
  SUNRPC: Lockless server RPCSEC_GSS context lookup
  knfsd: Allow lockless lookups of the exports
  ...
parents 9b190ecc 93f38b6f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ Creating a Cache
		A message from user space has arrived to fill out a
		cache entry.  It is in 'buf' of length 'len'.
		cache_parse should parse this, find the item in the
		cache with sunrpc_cache_lookup, and update the item
		cache with sunrpc_cache_lookup_rcu, and update the item
		with sunrpc_cache_update.


@@ -95,7 +95,7 @@ Creating a Cache
Using a cache
-------------

To find a value in a cache, call sunrpc_cache_lookup passing a pointer
To find a value in a cache, call sunrpc_cache_lookup_rcu passing a pointer
to the cache_head in a sample item with the 'key' fields filled in.
This will be passed to ->match to identify the target entry.  If no
entry is found, a new entry will be create, added to the cache, and
@@ -116,7 +116,7 @@ item does become valid, the deferred copy of the request will be
revisited (->revisit).  It is expected that this method will
reschedule the request for processing.

The value returned by sunrpc_cache_lookup can also be passed to
The value returned by sunrpc_cache_lookup_rcu can also be passed to
sunrpc_cache_update to set the content for the item.  A second item is
passed which should hold the content.  If the item found by _lookup
has valid data, then it is discarded and a new item is created.  This
+1 −1
Original line number Diff line number Diff line
@@ -341,7 +341,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
	};
	struct lockd_net *ln = net_generic(net, lockd_net_id);

	dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__,
	dprintk("lockd: %s(host='%.*s', vers=%u, proto=%s)\n", __func__,
			(int)hostname_len, hostname, rqstp->rq_vers,
			(rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp"));

+12 −3
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ struct nfs_dns_ent {

	struct sockaddr_storage addr;
	size_t addrlen;
	struct rcu_head rcu_head;
};


@@ -101,15 +102,23 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
	}
}

static void nfs_dns_ent_put(struct kref *ref)
static void nfs_dns_ent_free_rcu(struct rcu_head *head)
{
	struct nfs_dns_ent *item;

	item = container_of(ref, struct nfs_dns_ent, h.ref);
	item = container_of(head, struct nfs_dns_ent, rcu_head);
	kfree(item->hostname);
	kfree(item);
}

static void nfs_dns_ent_put(struct kref *ref)
{
	struct nfs_dns_ent *item;

	item = container_of(ref, struct nfs_dns_ent, h.ref);
	call_rcu(&item->rcu_head, nfs_dns_ent_free_rcu);
}

static struct cache_head *nfs_dns_ent_alloc(void)
{
	struct nfs_dns_ent *item = kmalloc(sizeof(*item), GFP_KERNEL);
@@ -195,7 +204,7 @@ static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd,
{
	struct cache_head *ch;

	ch = sunrpc_cache_lookup(cd,
	ch = sunrpc_cache_lookup_rcu(cd,
			&key->h,
			nfs_dns_hash(key));
	if (!ch)
+12 −8
Original line number Diff line number Diff line
@@ -19,18 +19,22 @@
 * is much larger than a sockaddr_in6.
 */
struct svc_cacherep {
	struct list_head	c_lru;
	struct {
		/* Keep often-read xid, csum in the same cache line: */
		__be32			k_xid;
		__wsum			k_csum;
		u32			k_proc;
		u32			k_prot;
		u32			k_vers;
		unsigned int		k_len;
		struct sockaddr_in6	k_addr;
	} c_key;

	struct rb_node		c_node;
	struct list_head	c_lru;
	unsigned char		c_state,	/* unused, inprog, done */
				c_type,		/* status, buffer */
				c_secure : 1;	/* req came from port < 1024 */
	struct sockaddr_in6	c_addr;
	__be32			c_xid;
	u32			c_prot;
	u32			c_proc;
	u32			c_vers;
	unsigned int		c_len;
	__wsum			c_csum;
	unsigned long		c_timestamp;
	union {
		struct kvec	u_vec;
+7 −7
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ static void expkey_put(struct kref *ref)
	    !test_bit(CACHE_NEGATIVE, &key->h.flags))
		path_put(&key->ek_path);
	auth_domain_put(key->ek_client);
	kfree(key);
	kfree_rcu(key, ek_rcu);
}

static void expkey_request(struct cache_detail *cd,
@@ -265,7 +265,7 @@ svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *item)
	struct cache_head *ch;
	int hash = svc_expkey_hash(item);

	ch = sunrpc_cache_lookup(cd, &item->h, hash);
	ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
	if (ch)
		return container_of(ch, struct svc_expkey, h);
	else
@@ -314,7 +314,7 @@ static void svc_export_put(struct kref *ref)
	auth_domain_put(exp->ex_client);
	nfsd4_fslocs_free(&exp->ex_fslocs);
	kfree(exp->ex_uuid);
	kfree(exp);
	kfree_rcu(exp, ex_rcu);
}

static void svc_export_request(struct cache_detail *cd,
@@ -780,7 +780,7 @@ svc_export_lookup(struct svc_export *exp)
	struct cache_head *ch;
	int hash = svc_export_hash(exp);

	ch = sunrpc_cache_lookup(exp->cd, &exp->h, hash);
	ch = sunrpc_cache_lookup_rcu(exp->cd, &exp->h, hash);
	if (ch)
		return container_of(ch, struct svc_export, h);
	else
@@ -1216,9 +1216,9 @@ static int e_show(struct seq_file *m, void *p)
}

const struct seq_operations nfs_exports_op = {
	.start	= cache_seq_start,
	.next	= cache_seq_next,
	.stop	= cache_seq_stop,
	.start	= cache_seq_start_rcu,
	.next	= cache_seq_next_rcu,
	.stop	= cache_seq_stop_rcu,
	.show	= e_show,
};

Loading