aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-17 22:04:24 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 18:20:28 -0500
commit9157c31dd610a127bc6f01bc1953cf8b80382040 (patch)
tree0552a17b2f047da4240a62d06b9fe58b162bad35 /fs
parentd1e284d50a1506aab8ad7895f31b5f93b5647fc9 (diff)
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--fs/nfs/nfs4state.c17
4 files changed, 17 insertions, 8 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ca9a4aa38dff..8d1739d3424d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1092,6 +1092,7 @@ static struct nfs_server *nfs_alloc_server(void)
1092 return NULL; 1092 return NULL;
1093 } 1093 }
1094 1094
1095 ida_init(&server->openowner_id);
1095 pnfs_init_server(server); 1096 pnfs_init_server(server);
1096 1097
1097 return server; 1098 return server;
@@ -1117,6 +1118,7 @@ void nfs_free_server(struct nfs_server *server)
1117 1118
1118 nfs_put_client(server->nfs_client); 1119 nfs_put_client(server->nfs_client);
1119 1120
1121 ida_destroy(&server->openowner_id);
1120 nfs_free_iostats(server->io_stats); 1122 nfs_free_iostats(server->io_stats);
1121 bdi_destroy(&server->backing_dev_info); 1123 bdi_destroy(&server->backing_dev_info);
1122 kfree(server); 1124 kfree(server);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 654b091644c5..091b679747ed 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -92,7 +92,6 @@ struct nfs_unique_id {
92 * semantics by allowing the server to identify replayed requests. 92 * semantics by allowing the server to identify replayed requests.
93 */ 93 */
94struct nfs4_state_owner { 94struct nfs4_state_owner {
95 struct nfs_unique_id so_owner_id;
96 struct nfs_server *so_server; 95 struct nfs_server *so_server;
97 struct list_head so_lru; 96 struct list_head so_lru;
98 unsigned long so_expires; 97 unsigned long so_expires;
@@ -106,6 +105,7 @@ struct nfs4_state_owner {
106 struct list_head so_states; 105 struct list_head so_states;
107 struct nfs_seqid_counter so_seqid; 106 struct nfs_seqid_counter so_seqid;
108 struct rpc_sequence so_sequence; 107 struct rpc_sequence so_sequence;
108 int so_owner_id;
109}; 109};
110 110
111enum { 111enum {
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 53ef365f4372..1dd2e407a901 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -815,7 +815,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
815 p->o_arg.open_flags = flags; 815 p->o_arg.open_flags = flags;
816 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); 816 p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
817 p->o_arg.clientid = server->nfs_client->cl_clientid; 817 p->o_arg.clientid = server->nfs_client->cl_clientid;
818 p->o_arg.id = sp->so_owner_id.id; 818 p->o_arg.id = sp->so_owner_id;
819 p->o_arg.name = &dentry->d_name; 819 p->o_arg.name = &dentry->d_name;
820 p->o_arg.server = server; 820 p->o_arg.server = server;
821 p->o_arg.bitmask = server->attr_bitmask; 821 p->o_arg.bitmask = server->attr_bitmask;
@@ -1440,7 +1440,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1440 rcu_read_unlock(); 1440 rcu_read_unlock();
1441 } 1441 }
1442 /* Update sequence id. */ 1442 /* Update sequence id. */
1443 data->o_arg.id = sp->so_owner_id.id; 1443 data->o_arg.id = sp->so_owner_id;
1444 data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid; 1444 data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
1445 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { 1445 if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
1446 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; 1446 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a8a42a677d8f..8472707286f9 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -405,6 +405,7 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
405 struct rb_node **p = &server->state_owners.rb_node, 405 struct rb_node **p = &server->state_owners.rb_node,
406 *parent = NULL; 406 *parent = NULL;
407 struct nfs4_state_owner *sp; 407 struct nfs4_state_owner *sp;
408 int err;
408 409
409 while (*p != NULL) { 410 while (*p != NULL) {
410 parent = *p; 411 parent = *p;
@@ -421,8 +422,9 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
421 return sp; 422 return sp;
422 } 423 }
423 } 424 }
424 nfs_alloc_unique_id_locked(&server->openowner_id, 425 err = ida_get_new(&server->openowner_id, &new->so_owner_id);
425 &new->so_owner_id, 1, 64); 426 if (err)
427 return ERR_PTR(err);
426 rb_link_node(&new->so_server_node, parent, p); 428 rb_link_node(&new->so_server_node, parent, p);
427 rb_insert_color(&new->so_server_node, &server->state_owners); 429 rb_insert_color(&new->so_server_node, &server->state_owners);
428 return new; 430 return new;
@@ -435,7 +437,7 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)
435 437
436 if (!RB_EMPTY_NODE(&sp->so_server_node)) 438 if (!RB_EMPTY_NODE(&sp->so_server_node))
437 rb_erase(&sp->so_server_node, &server->state_owners); 439 rb_erase(&sp->so_server_node, &server->state_owners);
438 nfs_free_unique_id(&server->openowner_id, &sp->so_owner_id); 440 ida_remove(&server->openowner_id, sp->so_owner_id);
439} 441}
440 442
441/* 443/*
@@ -534,8 +536,13 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
534 new = nfs4_alloc_state_owner(server, cred, gfp_flags); 536 new = nfs4_alloc_state_owner(server, cred, gfp_flags);
535 if (new == NULL) 537 if (new == NULL)
536 goto out; 538 goto out;
537 sp = nfs4_insert_state_owner_locked(new); 539 do {
538 spin_unlock(&clp->cl_lock); 540 if (ida_pre_get(&server->openowner_id, gfp_flags) == 0)
541 break;
542 spin_lock(&clp->cl_lock);
543 sp = nfs4_insert_state_owner_locked(new);
544 spin_unlock(&clp->cl_lock);
545 } while (sp == ERR_PTR(-EAGAIN));
539 if (sp != new) 546 if (sp != new)
540 nfs4_free_state_owner(new); 547 nfs4_free_state_owner(new);
541out: 548out: