diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2012-11-29 11:40:42 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-12-03 09:58:59 -0500 |
commit | 269de30f10604710dde8d544748b5b6c748b7de8 (patch) | |
tree | d242751b315ff5dcbf1adbb8380162d02ffcf03b /fs/nfsd/nfs4state.c | |
parent | 4dbdbda84f963312e0b5dfdf2dfbf64de047dd44 (diff) |
NFSD: Clean up forgetting and recalling delegations
Once I have a client, I can easily use its delegation list rather than
searching the file hash table for delegations to remove.
Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 94 |
1 files changed, 50 insertions, 44 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 00d4398e2324..dc7c22f14fef 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -4657,6 +4657,52 @@ u64 nfsd_forget_client_openowners(struct nfs4_client *clp, u64 max) | |||
4657 | return nfsd_foreach_client_open(clp, max, release_openowner); | 4657 | return nfsd_foreach_client_open(clp, max, release_openowner); |
4658 | } | 4658 | } |
4659 | 4659 | ||
4660 | static u64 nfsd_find_all_delegations(struct nfs4_client *clp, u64 max, | ||
4661 | struct list_head *victims) | ||
4662 | { | ||
4663 | struct nfs4_delegation *dp, *next; | ||
4664 | u64 count = 0; | ||
4665 | |||
4666 | list_for_each_entry_safe(dp, next, &clp->cl_delegations, dl_perclnt) { | ||
4667 | if (victims) | ||
4668 | list_move(&dp->dl_recall_lru, victims); | ||
4669 | if (++count == max) | ||
4670 | break; | ||
4671 | } | ||
4672 | return count; | ||
4673 | } | ||
4674 | |||
4675 | u64 nfsd_forget_client_delegations(struct nfs4_client *clp, u64 max) | ||
4676 | { | ||
4677 | struct nfs4_delegation *dp, *next; | ||
4678 | LIST_HEAD(victims); | ||
4679 | u64 count; | ||
4680 | |||
4681 | spin_lock(&recall_lock); | ||
4682 | count = nfsd_find_all_delegations(clp, max, &victims); | ||
4683 | spin_unlock(&recall_lock); | ||
4684 | |||
4685 | list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) | ||
4686 | unhash_delegation(dp); | ||
4687 | |||
4688 | return count; | ||
4689 | } | ||
4690 | |||
4691 | u64 nfsd_recall_client_delegations(struct nfs4_client *clp, u64 max) | ||
4692 | { | ||
4693 | struct nfs4_delegation *dp, *next; | ||
4694 | LIST_HEAD(victims); | ||
4695 | u64 count; | ||
4696 | |||
4697 | spin_lock(&recall_lock); | ||
4698 | count = nfsd_find_all_delegations(clp, max, &victims); | ||
4699 | list_for_each_entry_safe(dp, next, &victims, dl_recall_lru) | ||
4700 | nfsd_break_one_deleg(dp); | ||
4701 | spin_unlock(&recall_lock); | ||
4702 | |||
4703 | return count; | ||
4704 | } | ||
4705 | |||
4660 | u64 nfsd_for_n_state(u64 max, u64 (*func)(struct nfs4_client *, u64)) | 4706 | u64 nfsd_for_n_state(u64 max, u64 (*func)(struct nfs4_client *, u64)) |
4661 | { | 4707 | { |
4662 | struct nfs4_client *clp, *next; | 4708 | struct nfs4_client *clp, *next; |
@@ -4693,56 +4739,16 @@ void nfsd_forget_openowners(u64 num) | |||
4693 | printk(KERN_INFO "NFSD: Forgot %llu open owners", count); | 4739 | printk(KERN_INFO "NFSD: Forgot %llu open owners", count); |
4694 | } | 4740 | } |
4695 | 4741 | ||
4696 | static int nfsd_process_n_delegations(u64 num, struct list_head *list) | ||
4697 | { | ||
4698 | int i, count = 0; | ||
4699 | struct nfs4_file *fp, *fnext; | ||
4700 | struct nfs4_delegation *dp, *dnext; | ||
4701 | |||
4702 | for (i = 0; i < FILE_HASH_SIZE; i++) { | ||
4703 | list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) { | ||
4704 | list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) { | ||
4705 | list_move(&dp->dl_recall_lru, list); | ||
4706 | if (++count == num) | ||
4707 | return count; | ||
4708 | } | ||
4709 | } | ||
4710 | } | ||
4711 | |||
4712 | return count; | ||
4713 | } | ||
4714 | |||
4715 | void nfsd_forget_delegations(u64 num) | 4742 | void nfsd_forget_delegations(u64 num) |
4716 | { | 4743 | { |
4717 | unsigned int count; | 4744 | u64 count = nfsd_for_n_state(num, nfsd_forget_client_delegations); |
4718 | LIST_HEAD(victims); | 4745 | printk(KERN_INFO "NFSD: Forgot %llu delegations", count); |
4719 | struct nfs4_delegation *dp, *dnext; | ||
4720 | |||
4721 | spin_lock(&recall_lock); | ||
4722 | count = nfsd_process_n_delegations(num, &victims); | ||
4723 | spin_unlock(&recall_lock); | ||
4724 | |||
4725 | list_for_each_entry_safe(dp, dnext, &victims, dl_recall_lru) | ||
4726 | unhash_delegation(dp); | ||
4727 | |||
4728 | printk(KERN_INFO "NFSD: Forgot %d delegations", count); | ||
4729 | } | 4746 | } |
4730 | 4747 | ||
4731 | void nfsd_recall_delegations(u64 num) | 4748 | void nfsd_recall_delegations(u64 num) |
4732 | { | 4749 | { |
4733 | unsigned int count; | 4750 | u64 count = nfsd_for_n_state(num, nfsd_recall_client_delegations); |
4734 | LIST_HEAD(victims); | 4751 | printk(KERN_INFO "NFSD: Recalled %llu delegations", count); |
4735 | struct nfs4_delegation *dp, *dnext; | ||
4736 | |||
4737 | spin_lock(&recall_lock); | ||
4738 | count = nfsd_process_n_delegations(num, &victims); | ||
4739 | list_for_each_entry_safe(dp, dnext, &victims, dl_recall_lru) { | ||
4740 | list_del(&dp->dl_recall_lru); | ||
4741 | nfsd_break_one_deleg(dp); | ||
4742 | } | ||
4743 | spin_unlock(&recall_lock); | ||
4744 | |||
4745 | printk(KERN_INFO "NFSD: Recalled %d delegations", count); | ||
4746 | } | 4752 | } |
4747 | 4753 | ||
4748 | #endif /* CONFIG_NFSD_FAULT_INJECTION */ | 4754 | #endif /* CONFIG_NFSD_FAULT_INJECTION */ |