Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9157c31d authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Replace state_owner->so_owner_id with an ida based allocator



We're unlikely to ever need more than 2^31 simultaneous open owners,
so let's replace the custom allocator with the generic ida allocator.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent d1e284d5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1092,6 +1092,7 @@ static struct nfs_server *nfs_alloc_server(void)
		return NULL;
	}

	ida_init(&server->openowner_id);
	pnfs_init_server(server);

	return server;
@@ -1117,6 +1118,7 @@ void nfs_free_server(struct nfs_server *server)

	nfs_put_client(server->nfs_client);

	ida_destroy(&server->openowner_id);
	nfs_free_iostats(server->io_stats);
	bdi_destroy(&server->backing_dev_info);
	kfree(server);
+1 −1
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ struct nfs_unique_id {
 * semantics by allowing the server to identify replayed requests.
 */
struct nfs4_state_owner {
	struct nfs_unique_id so_owner_id;
	struct nfs_server    *so_server;
	struct list_head     so_lru;
	unsigned long        so_expires;
@@ -106,6 +105,7 @@ struct nfs4_state_owner {
	struct list_head     so_states;
	struct nfs_seqid_counter so_seqid;
	struct rpc_sequence  so_sequence;
	int		     so_owner_id;
};

enum {
+2 −2
Original line number Diff line number Diff line
@@ -815,7 +815,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
	p->o_arg.open_flags = flags;
	p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
	p->o_arg.clientid = server->nfs_client->cl_clientid;
	p->o_arg.id = sp->so_owner_id.id;
	p->o_arg.id = sp->so_owner_id;
	p->o_arg.name = &dentry->d_name;
	p->o_arg.server = server;
	p->o_arg.bitmask = server->attr_bitmask;
@@ -1440,7 +1440,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
		rcu_read_unlock();
	}
	/* Update sequence id. */
	data->o_arg.id = sp->so_owner_id.id;
	data->o_arg.id = sp->so_owner_id;
	data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
	if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
		task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
+12 −5
Original line number Diff line number Diff line
@@ -405,6 +405,7 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
	struct rb_node **p = &server->state_owners.rb_node,
		       *parent = NULL;
	struct nfs4_state_owner *sp;
	int err;

	while (*p != NULL) {
		parent = *p;
@@ -421,8 +422,9 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
			return sp;
		}
	}
	nfs_alloc_unique_id_locked(&server->openowner_id,
					&new->so_owner_id, 1, 64);
	err = ida_get_new(&server->openowner_id, &new->so_owner_id);
	if (err)
		return ERR_PTR(err);
	rb_link_node(&new->so_server_node, parent, p);
	rb_insert_color(&new->so_server_node, &server->state_owners);
	return new;
@@ -435,7 +437,7 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)

	if (!RB_EMPTY_NODE(&sp->so_server_node))
		rb_erase(&sp->so_server_node, &server->state_owners);
	nfs_free_unique_id(&server->openowner_id, &sp->so_owner_id);
	ida_remove(&server->openowner_id, sp->so_owner_id);
}

/*
@@ -534,8 +536,13 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
	new = nfs4_alloc_state_owner(server, cred, gfp_flags);
	if (new == NULL)
		goto out;
	do {
		if (ida_pre_get(&server->openowner_id, gfp_flags) == 0)
			break;
		spin_lock(&clp->cl_lock);
		sp = nfs4_insert_state_owner_locked(new);
		spin_unlock(&clp->cl_lock);
	} while (sp == ERR_PTR(-EAGAIN));
	if (sp != new)
		nfs4_free_state_owner(new);
out:
+2 −1
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#include <linux/list.h>
#include <linux/backing-dev.h>
#include <linux/idr.h>
#include <linux/wait.h>
#include <linux/nfs_xdr.h>
#include <linux/sunrpc/xprt.h>
@@ -151,9 +152,9 @@ struct nfs_server {

	/* the following fields are protected by nfs_client->cl_lock */
	struct rb_root		state_owners;
	struct rb_root		openowner_id;
	struct rb_root		lockowner_id;
#endif
	struct ida		openowner_id;
	struct list_head	state_owners_lru;
	struct list_head	layouts;
	struct list_head	delegations;