aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2012-11-29 11:40:42 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-12-03 09:58:59 -0500
commit269de30f10604710dde8d544748b5b6c748b7de8 (patch)
treed242751b315ff5dcbf1adbb8380162d02ffcf03b /fs/nfsd/nfs4state.c
parent4dbdbda84f963312e0b5dfdf2dfbf64de047dd44 (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.c94
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
4660static 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
4675u64 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
4691u64 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
4660u64 nfsd_for_n_state(u64 max, u64 (*func)(struct nfs4_client *, u64)) 4706u64 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
4696static 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
4715void nfsd_forget_delegations(u64 num) 4742void 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
4731void nfsd_recall_delegations(u64 num) 4748void 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 */