diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-17 22:04:24 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-31 18:20:28 -0500 |
commit | 9157c31dd610a127bc6f01bc1953cf8b80382040 (patch) | |
tree | 0552a17b2f047da4240a62d06b9fe58b162bad35 /fs | |
parent | d1e284d50a1506aab8ad7895f31b5f93b5647fc9 (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.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 17 |
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 | */ |
94 | struct nfs4_state_owner { | 94 | struct 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 | ||
111 | enum { | 111 | enum { |
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); |
541 | out: | 548 | out: |