aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2014-06-30 11:48:38 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-07-08 17:14:37 -0400
commit3c87b9b7c05d7775a3d942de588296025023c6d2 (patch)
tree5f2f480974ad925b754b91cea2037d5237bc28e4
parentacf9295b1c4e60fc205e21b7a5c9dc6e1cb2764a (diff)
nfsd: lock owners are not per open stateid
In the NFSv4 spec, lock stateids are per-file objects. Lockowners are not. This patch replaces the current list of lock owners in the open stateids with a list of lock stateids. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4state.c53
-rw-r--r--fs/nfsd/state.h3
2 files changed, 36 insertions, 20 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 1e973f67999d..137fdcce9023 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -695,10 +695,11 @@ static void free_generic_stateid(struct nfs4_ol_stateid *stp)
695 nfs4_free_stid(stateid_slab, &stp->st_stid); 695 nfs4_free_stid(stateid_slab, &stp->st_stid);
696} 696}
697 697
698static void release_lock_stateid(struct nfs4_ol_stateid *stp) 698static void __release_lock_stateid(struct nfs4_ol_stateid *stp)
699{ 699{
700 struct file *file; 700 struct file *file;
701 701
702 list_del(&stp->st_locks);
702 unhash_generic_stateid(stp); 703 unhash_generic_stateid(stp);
703 unhash_stid(&stp->st_stid); 704 unhash_stid(&stp->st_stid);
704 file = find_any_file(stp->st_file); 705 file = find_any_file(stp->st_file);
@@ -713,12 +714,11 @@ static void unhash_lockowner(struct nfs4_lockowner *lo)
713 struct nfs4_ol_stateid *stp; 714 struct nfs4_ol_stateid *stp;
714 715
715 list_del(&lo->lo_owner.so_strhash); 716 list_del(&lo->lo_owner.so_strhash);
716 list_del(&lo->lo_perstateid);
717 list_del(&lo->lo_owner_ino_hash); 717 list_del(&lo->lo_owner_ino_hash);
718 while (!list_empty(&lo->lo_owner.so_stateids)) { 718 while (!list_empty(&lo->lo_owner.so_stateids)) {
719 stp = list_first_entry(&lo->lo_owner.so_stateids, 719 stp = list_first_entry(&lo->lo_owner.so_stateids,
720 struct nfs4_ol_stateid, st_perstateowner); 720 struct nfs4_ol_stateid, st_perstateowner);
721 release_lock_stateid(stp); 721 __release_lock_stateid(stp);
722 } 722 }
723} 723}
724 724
@@ -734,22 +734,36 @@ static void release_lockowner(struct nfs4_lockowner *lo)
734 nfs4_free_lockowner(lo); 734 nfs4_free_lockowner(lo);
735} 735}
736 736
737static void 737static void release_lockowner_if_empty(struct nfs4_lockowner *lo)
738release_stateid_lockowners(struct nfs4_ol_stateid *open_stp) 738{
739 if (list_empty(&lo->lo_owner.so_stateids))
740 release_lockowner(lo);
741}
742
743static void release_lock_stateid(struct nfs4_ol_stateid *stp)
739{ 744{
740 struct nfs4_lockowner *lo; 745 struct nfs4_lockowner *lo;
741 746
742 while (!list_empty(&open_stp->st_lockowners)) { 747 lo = lockowner(stp->st_stateowner);
743 lo = list_entry(open_stp->st_lockowners.next, 748 __release_lock_stateid(stp);
744 struct nfs4_lockowner, lo_perstateid); 749 release_lockowner_if_empty(lo);
745 release_lockowner(lo); 750}
751
752static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp)
753{
754 struct nfs4_ol_stateid *stp;
755
756 while (!list_empty(&open_stp->st_locks)) {
757 stp = list_entry(open_stp->st_locks.next,
758 struct nfs4_ol_stateid, st_locks);
759 release_lock_stateid(stp);
746 } 760 }
747} 761}
748 762
749static void unhash_open_stateid(struct nfs4_ol_stateid *stp) 763static void unhash_open_stateid(struct nfs4_ol_stateid *stp)
750{ 764{
751 unhash_generic_stateid(stp); 765 unhash_generic_stateid(stp);
752 release_stateid_lockowners(stp); 766 release_open_stateid_locks(stp);
753 close_generic_stateid(stp); 767 close_generic_stateid(stp);
754} 768}
755 769
@@ -2744,7 +2758,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
2744 struct nfs4_openowner *oo = open->op_openowner; 2758 struct nfs4_openowner *oo = open->op_openowner;
2745 2759
2746 stp->st_stid.sc_type = NFS4_OPEN_STID; 2760 stp->st_stid.sc_type = NFS4_OPEN_STID;
2747 INIT_LIST_HEAD(&stp->st_lockowners); 2761 INIT_LIST_HEAD(&stp->st_locks);
2748 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); 2762 list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
2749 list_add(&stp->st_perfile, &fp->fi_stateids); 2763 list_add(&stp->st_perfile, &fp->fi_stateids);
2750 stp->st_stateowner = &oo->oo_owner; 2764 stp->st_stateowner = &oo->oo_owner;
@@ -4335,7 +4349,6 @@ static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, s
4335 4349
4336 list_add(&lo->lo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]); 4350 list_add(&lo->lo_owner.so_strhash, &nn->ownerstr_hashtbl[strhashval]);
4337 list_add(&lo->lo_owner_ino_hash, &nn->lockowner_ino_hashtbl[inohash]); 4351 list_add(&lo->lo_owner_ino_hash, &nn->lockowner_ino_hashtbl[inohash]);
4338 list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
4339} 4352}
4340 4353
4341/* 4354/*
@@ -4380,6 +4393,7 @@ alloc_init_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp, struct
4380 stp->st_access_bmap = 0; 4393 stp->st_access_bmap = 0;
4381 stp->st_deny_bmap = open_stp->st_deny_bmap; 4394 stp->st_deny_bmap = open_stp->st_deny_bmap;
4382 stp->st_openstp = open_stp; 4395 stp->st_openstp = open_stp;
4396 list_add(&stp->st_locks, &open_stp->st_locks);
4383 return stp; 4397 return stp;
4384} 4398}
4385 4399
@@ -4967,18 +4981,21 @@ static void nfsd_print_count(struct nfs4_client *clp, unsigned int count,
4967 printk(KERN_INFO "NFS Client: %s has %u %s\n", buf, count, type); 4981 printk(KERN_INFO "NFS Client: %s has %u %s\n", buf, count, type);
4968} 4982}
4969 4983
4970static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max, void (*func)(struct nfs4_lockowner *)) 4984static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max,
4985 void (*func)(struct nfs4_ol_stateid *))
4971{ 4986{
4972 struct nfs4_openowner *oop; 4987 struct nfs4_openowner *oop;
4973 struct nfs4_lockowner *lop, *lo_next;
4974 struct nfs4_ol_stateid *stp, *st_next; 4988 struct nfs4_ol_stateid *stp, *st_next;
4989 struct nfs4_ol_stateid *lst, *lst_next;
4975 u64 count = 0; 4990 u64 count = 0;
4976 4991
4977 list_for_each_entry(oop, &clp->cl_openowners, oo_perclient) { 4992 list_for_each_entry(oop, &clp->cl_openowners, oo_perclient) {
4978 list_for_each_entry_safe(stp, st_next, &oop->oo_owner.so_stateids, st_perstateowner) { 4993 list_for_each_entry_safe(stp, st_next,
4979 list_for_each_entry_safe(lop, lo_next, &stp->st_lockowners, lo_perstateid) { 4994 &oop->oo_owner.so_stateids, st_perstateowner) {
4995 list_for_each_entry_safe(lst, lst_next,
4996 &stp->st_locks, st_locks) {
4980 if (func) 4997 if (func)
4981 func(lop); 4998 func(lst);
4982 if (++count == max) 4999 if (++count == max)
4983 return count; 5000 return count;
4984 } 5001 }
@@ -4990,7 +5007,7 @@ static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max, void (*fun
4990 5007
4991u64 nfsd_forget_client_locks(struct nfs4_client *clp, u64 max) 5008u64 nfsd_forget_client_locks(struct nfs4_client *clp, u64 max)
4992{ 5009{
4993 return nfsd_foreach_client_lock(clp, max, release_lockowner); 5010 return nfsd_foreach_client_lock(clp, max, release_lock_stateid);
4994} 5011}
4995 5012
4996u64 nfsd_print_client_locks(struct nfs4_client *clp, u64 max) 5013u64 nfsd_print_client_locks(struct nfs4_client *clp, u64 max)
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 62f33b7ec10c..c1e384a0a40a 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -365,7 +365,6 @@ struct nfs4_openowner {
365struct nfs4_lockowner { 365struct nfs4_lockowner {
366 struct nfs4_stateowner lo_owner; /* must be first element */ 366 struct nfs4_stateowner lo_owner; /* must be first element */
367 struct list_head lo_owner_ino_hash; /* hash by owner,file */ 367 struct list_head lo_owner_ino_hash; /* hash by owner,file */
368 struct list_head lo_perstateid;
369 struct list_head lo_list; /* for temporary uses */ 368 struct list_head lo_list; /* for temporary uses */
370}; 369};
371 370
@@ -433,7 +432,7 @@ struct nfs4_ol_stateid {
433 struct nfs4_stid st_stid; /* must be first field */ 432 struct nfs4_stid st_stid; /* must be first field */
434 struct list_head st_perfile; 433 struct list_head st_perfile;
435 struct list_head st_perstateowner; 434 struct list_head st_perstateowner;
436 struct list_head st_lockowners; 435 struct list_head st_locks;
437 struct nfs4_stateowner * st_stateowner; 436 struct nfs4_stateowner * st_stateowner;
438 struct nfs4_file * st_file; 437 struct nfs4_file * st_file;
439 unsigned long st_access_bmap; 438 unsigned long st_access_bmap;