aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index af88d1d7ccae..f318e706cb35 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1009,16 +1009,20 @@ static void nfs4_put_stateowner(struct nfs4_stateowner *sop)
1009 nfs4_free_stateowner(sop); 1009 nfs4_free_stateowner(sop);
1010} 1010}
1011 1011
1012static void unhash_ol_stateid(struct nfs4_ol_stateid *stp) 1012static bool unhash_ol_stateid(struct nfs4_ol_stateid *stp)
1013{ 1013{
1014 struct nfs4_file *fp = stp->st_stid.sc_file; 1014 struct nfs4_file *fp = stp->st_stid.sc_file;
1015 1015
1016 lockdep_assert_held(&stp->st_stateowner->so_client->cl_lock); 1016 lockdep_assert_held(&stp->st_stateowner->so_client->cl_lock);
1017 1017
1018 if (list_empty(&stp->st_perfile))
1019 return false;
1020
1018 spin_lock(&fp->fi_lock); 1021 spin_lock(&fp->fi_lock);
1019 list_del(&stp->st_perfile); 1022 list_del_init(&stp->st_perfile);
1020 spin_unlock(&fp->fi_lock); 1023 spin_unlock(&fp->fi_lock);
1021 list_del(&stp->st_perstateowner); 1024 list_del(&stp->st_perstateowner);
1025 return true;
1022} 1026}
1023 1027
1024static void nfs4_free_ol_stateid(struct nfs4_stid *stid) 1028static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
@@ -1068,25 +1072,27 @@ static void put_ol_stateid_locked(struct nfs4_ol_stateid *stp,
1068 list_add(&stp->st_locks, reaplist); 1072 list_add(&stp->st_locks, reaplist);
1069} 1073}
1070 1074
1071static void unhash_lock_stateid(struct nfs4_ol_stateid *stp) 1075static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp)
1072{ 1076{
1073 struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner); 1077 struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
1074 1078
1075 lockdep_assert_held(&oo->oo_owner.so_client->cl_lock); 1079 lockdep_assert_held(&oo->oo_owner.so_client->cl_lock);
1076 1080
1077 list_del_init(&stp->st_locks); 1081 list_del_init(&stp->st_locks);
1078 unhash_ol_stateid(stp);
1079 nfs4_unhash_stid(&stp->st_stid); 1082 nfs4_unhash_stid(&stp->st_stid);
1083 return unhash_ol_stateid(stp);
1080} 1084}
1081 1085
1082static void release_lock_stateid(struct nfs4_ol_stateid *stp) 1086static void release_lock_stateid(struct nfs4_ol_stateid *stp)
1083{ 1087{
1084 struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner); 1088 struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
1089 bool unhashed;
1085 1090
1086 spin_lock(&oo->oo_owner.so_client->cl_lock); 1091 spin_lock(&oo->oo_owner.so_client->cl_lock);
1087 unhash_lock_stateid(stp); 1092 unhashed = unhash_lock_stateid(stp);
1088 spin_unlock(&oo->oo_owner.so_client->cl_lock); 1093 spin_unlock(&oo->oo_owner.so_client->cl_lock);
1089 nfs4_put_stid(&stp->st_stid); 1094 if (unhashed)
1095 nfs4_put_stid(&stp->st_stid);
1090} 1096}
1091 1097
1092static void unhash_lockowner_locked(struct nfs4_lockowner *lo) 1098static void unhash_lockowner_locked(struct nfs4_lockowner *lo)
@@ -1134,7 +1140,7 @@ static void release_lockowner(struct nfs4_lockowner *lo)
1134 while (!list_empty(&lo->lo_owner.so_stateids)) { 1140 while (!list_empty(&lo->lo_owner.so_stateids)) {
1135 stp = list_first_entry(&lo->lo_owner.so_stateids, 1141 stp = list_first_entry(&lo->lo_owner.so_stateids,
1136 struct nfs4_ol_stateid, st_perstateowner); 1142 struct nfs4_ol_stateid, st_perstateowner);
1137 unhash_lock_stateid(stp); 1143 WARN_ON(!unhash_lock_stateid(stp));
1138 put_ol_stateid_locked(stp, &reaplist); 1144 put_ol_stateid_locked(stp, &reaplist);
1139 } 1145 }
1140 spin_unlock(&clp->cl_lock); 1146 spin_unlock(&clp->cl_lock);
@@ -1147,21 +1153,26 @@ static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp,
1147{ 1153{
1148 struct nfs4_ol_stateid *stp; 1154 struct nfs4_ol_stateid *stp;
1149 1155
1156 lockdep_assert_held(&open_stp->st_stid.sc_client->cl_lock);
1157
1150 while (!list_empty(&open_stp->st_locks)) { 1158 while (!list_empty(&open_stp->st_locks)) {
1151 stp = list_entry(open_stp->st_locks.next, 1159 stp = list_entry(open_stp->st_locks.next,
1152 struct nfs4_ol_stateid, st_locks); 1160 struct nfs4_ol_stateid, st_locks);
1153 unhash_lock_stateid(stp); 1161 WARN_ON(!unhash_lock_stateid(stp));
1154 put_ol_stateid_locked(stp, reaplist); 1162 put_ol_stateid_locked(stp, reaplist);
1155 } 1163 }
1156} 1164}
1157 1165
1158static void unhash_open_stateid(struct nfs4_ol_stateid *stp, 1166static bool unhash_open_stateid(struct nfs4_ol_stateid *stp,
1159 struct list_head *reaplist) 1167 struct list_head *reaplist)
1160{ 1168{
1169 bool unhashed;
1170
1161 lockdep_assert_held(&stp->st_stid.sc_client->cl_lock); 1171 lockdep_assert_held(&stp->st_stid.sc_client->cl_lock);
1162 1172
1163 unhash_ol_stateid(stp); 1173 unhashed = unhash_ol_stateid(stp);
1164 release_open_stateid_locks(stp, reaplist); 1174 release_open_stateid_locks(stp, reaplist);
1175 return unhashed;
1165} 1176}
1166 1177
1167static void release_open_stateid(struct nfs4_ol_stateid *stp) 1178static void release_open_stateid(struct nfs4_ol_stateid *stp)
@@ -1169,8 +1180,8 @@ static void release_open_stateid(struct nfs4_ol_stateid *stp)
1169 LIST_HEAD(reaplist); 1180 LIST_HEAD(reaplist);
1170 1181
1171 spin_lock(&stp->st_stid.sc_client->cl_lock); 1182 spin_lock(&stp->st_stid.sc_client->cl_lock);
1172 unhash_open_stateid(stp, &reaplist); 1183 if (unhash_open_stateid(stp, &reaplist))
1173 put_ol_stateid_locked(stp, &reaplist); 1184 put_ol_stateid_locked(stp, &reaplist);
1174 spin_unlock(&stp->st_stid.sc_client->cl_lock); 1185 spin_unlock(&stp->st_stid.sc_client->cl_lock);
1175 free_ol_stateid_reaplist(&reaplist); 1186 free_ol_stateid_reaplist(&reaplist);
1176} 1187}
@@ -1215,8 +1226,8 @@ static void release_openowner(struct nfs4_openowner *oo)
1215 while (!list_empty(&oo->oo_owner.so_stateids)) { 1226 while (!list_empty(&oo->oo_owner.so_stateids)) {
1216 stp = list_first_entry(&oo->oo_owner.so_stateids, 1227 stp = list_first_entry(&oo->oo_owner.so_stateids,
1217 struct nfs4_ol_stateid, st_perstateowner); 1228 struct nfs4_ol_stateid, st_perstateowner);
1218 unhash_open_stateid(stp, &reaplist); 1229 if (unhash_open_stateid(stp, &reaplist))
1219 put_ol_stateid_locked(stp, &reaplist); 1230 put_ol_stateid_locked(stp, &reaplist);
1220 } 1231 }
1221 spin_unlock(&clp->cl_lock); 1232 spin_unlock(&clp->cl_lock);
1222 free_ol_stateid_reaplist(&reaplist); 1233 free_ol_stateid_reaplist(&reaplist);
@@ -4752,7 +4763,7 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4752 if (check_for_locks(stp->st_stid.sc_file, 4763 if (check_for_locks(stp->st_stid.sc_file,
4753 lockowner(stp->st_stateowner))) 4764 lockowner(stp->st_stateowner)))
4754 break; 4765 break;
4755 unhash_lock_stateid(stp); 4766 WARN_ON(!unhash_lock_stateid(stp));
4756 spin_unlock(&cl->cl_lock); 4767 spin_unlock(&cl->cl_lock);
4757 nfs4_put_stid(s); 4768 nfs4_put_stid(s);
4758 ret = nfs_ok; 4769 ret = nfs_ok;
@@ -4968,20 +4979,23 @@ out:
4968static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) 4979static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
4969{ 4980{
4970 struct nfs4_client *clp = s->st_stid.sc_client; 4981 struct nfs4_client *clp = s->st_stid.sc_client;
4982 bool unhashed;
4971 LIST_HEAD(reaplist); 4983 LIST_HEAD(reaplist);
4972 4984
4973 s->st_stid.sc_type = NFS4_CLOSED_STID; 4985 s->st_stid.sc_type = NFS4_CLOSED_STID;
4974 spin_lock(&clp->cl_lock); 4986 spin_lock(&clp->cl_lock);
4975 unhash_open_stateid(s, &reaplist); 4987 unhashed = unhash_open_stateid(s, &reaplist);
4976 4988
4977 if (clp->cl_minorversion) { 4989 if (clp->cl_minorversion) {
4978 put_ol_stateid_locked(s, &reaplist); 4990 if (unhashed)
4991 put_ol_stateid_locked(s, &reaplist);
4979 spin_unlock(&clp->cl_lock); 4992 spin_unlock(&clp->cl_lock);
4980 free_ol_stateid_reaplist(&reaplist); 4993 free_ol_stateid_reaplist(&reaplist);
4981 } else { 4994 } else {
4982 spin_unlock(&clp->cl_lock); 4995 spin_unlock(&clp->cl_lock);
4983 free_ol_stateid_reaplist(&reaplist); 4996 free_ol_stateid_reaplist(&reaplist);
4984 move_to_close_lru(s, clp->net); 4997 if (unhashed)
4998 move_to_close_lru(s, clp->net);
4985 } 4999 }
4986} 5000}
4987 5001
@@ -6014,7 +6028,7 @@ nfsd_inject_add_lock_to_list(struct nfs4_ol_stateid *lst,
6014 6028
6015static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max, 6029static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max,
6016 struct list_head *collect, 6030 struct list_head *collect,
6017 void (*func)(struct nfs4_ol_stateid *)) 6031 bool (*func)(struct nfs4_ol_stateid *))
6018{ 6032{
6019 struct nfs4_openowner *oop; 6033 struct nfs4_openowner *oop;
6020 struct nfs4_ol_stateid *stp, *st_next; 6034 struct nfs4_ol_stateid *stp, *st_next;
@@ -6028,9 +6042,9 @@ static u64 nfsd_foreach_client_lock(struct nfs4_client *clp, u64 max,
6028 list_for_each_entry_safe(lst, lst_next, 6042 list_for_each_entry_safe(lst, lst_next,
6029 &stp->st_locks, st_locks) { 6043 &stp->st_locks, st_locks) {
6030 if (func) { 6044 if (func) {
6031 func(lst); 6045 if (func(lst))
6032 nfsd_inject_add_lock_to_list(lst, 6046 nfsd_inject_add_lock_to_list(lst,
6033 collect); 6047 collect);
6034 } 6048 }
6035 ++count; 6049 ++count;
6036 /* 6050 /*