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/nfs/nfs4state.c | |
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/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 17 |
1 files changed, 12 insertions, 5 deletions
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: |