aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-30 08:27:11 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-08-01 16:28:24 -0400
commit217526e7ecc9f6f243e976772e81eab7ab986a4c (patch)
tree07a271d7b7592f682ad8ff8ff08ddd2c61bfc860
parent0a880a28f8add9b134a26f6e058c40199a2ffbc8 (diff)
nfsd: protect the close_lru list and oo_last_closed_stid with client_lock
Currently, it's protected by the client_mutex. Move it so that the list and the fields in the openowner are protected by the client_lock. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4state.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e7dfd4e9d942..818480035453 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1122,13 +1122,19 @@ static void unhash_openowner_locked(struct nfs4_openowner *oo)
1122 1122
1123static void release_last_closed_stateid(struct nfs4_openowner *oo) 1123static void release_last_closed_stateid(struct nfs4_openowner *oo)
1124{ 1124{
1125 struct nfs4_ol_stateid *s = oo->oo_last_closed_stid; 1125 struct nfsd_net *nn = net_generic(oo->oo_owner.so_client->net,
1126 nfsd_net_id);
1127 struct nfs4_ol_stateid *s;
1126 1128
1129 spin_lock(&nn->client_lock);
1130 s = oo->oo_last_closed_stid;
1127 if (s) { 1131 if (s) {
1128 list_del_init(&oo->oo_close_lru); 1132 list_del_init(&oo->oo_close_lru);
1129 oo->oo_last_closed_stid = NULL; 1133 oo->oo_last_closed_stid = NULL;
1130 nfs4_put_stid(&s->st_stid);
1131 } 1134 }
1135 spin_unlock(&nn->client_lock);
1136 if (s)
1137 nfs4_put_stid(&s->st_stid);
1132} 1138}
1133 1139
1134static void release_openowner(struct nfs4_openowner *oo) 1140static void release_openowner(struct nfs4_openowner *oo)
@@ -3265,6 +3271,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
3265static void 3271static void
3266move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) 3272move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
3267{ 3273{
3274 struct nfs4_ol_stateid *last;
3268 struct nfs4_openowner *oo = openowner(s->st_stateowner); 3275 struct nfs4_openowner *oo = openowner(s->st_stateowner);
3269 struct nfsd_net *nn = net_generic(s->st_stid.sc_client->net, 3276 struct nfsd_net *nn = net_generic(s->st_stid.sc_client->net,
3270 nfsd_net_id); 3277 nfsd_net_id);
@@ -3287,10 +3294,15 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
3287 put_nfs4_file(s->st_stid.sc_file); 3294 put_nfs4_file(s->st_stid.sc_file);
3288 s->st_stid.sc_file = NULL; 3295 s->st_stid.sc_file = NULL;
3289 } 3296 }
3290 release_last_closed_stateid(oo); 3297
3298 spin_lock(&nn->client_lock);
3299 last = oo->oo_last_closed_stid;
3291 oo->oo_last_closed_stid = s; 3300 oo->oo_last_closed_stid = s;
3292 list_move_tail(&oo->oo_close_lru, &nn->close_lru); 3301 list_move_tail(&oo->oo_close_lru, &nn->close_lru);
3293 oo->oo_time = get_seconds(); 3302 oo->oo_time = get_seconds();
3303 spin_unlock(&nn->client_lock);
3304 if (last)
3305 nfs4_put_stid(&last->st_stid);
3294} 3306}
3295 3307
3296/* search file_hashtbl[] for file */ 3308/* search file_hashtbl[] for file */
@@ -4148,6 +4160,7 @@ nfs4_laundromat(struct nfsd_net *nn)
4148 struct nfs4_client *clp; 4160 struct nfs4_client *clp;
4149 struct nfs4_openowner *oo; 4161 struct nfs4_openowner *oo;
4150 struct nfs4_delegation *dp; 4162 struct nfs4_delegation *dp;
4163 struct nfs4_ol_stateid *stp;
4151 struct list_head *pos, *next, reaplist; 4164 struct list_head *pos, *next, reaplist;
4152 time_t cutoff = get_seconds() - nn->nfsd4_lease; 4165 time_t cutoff = get_seconds() - nn->nfsd4_lease;
4153 time_t t, new_timeo = nn->nfsd4_lease; 4166 time_t t, new_timeo = nn->nfsd4_lease;
@@ -4201,15 +4214,26 @@ nfs4_laundromat(struct nfsd_net *nn)
4201 list_del_init(&dp->dl_recall_lru); 4214 list_del_init(&dp->dl_recall_lru);
4202 revoke_delegation(dp); 4215 revoke_delegation(dp);
4203 } 4216 }
4204 list_for_each_safe(pos, next, &nn->close_lru) { 4217
4205 oo = container_of(pos, struct nfs4_openowner, oo_close_lru); 4218 spin_lock(&nn->client_lock);
4206 if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) { 4219 while (!list_empty(&nn->close_lru)) {
4220 oo = list_first_entry(&nn->close_lru, struct nfs4_openowner,
4221 oo_close_lru);
4222 if (time_after((unsigned long)oo->oo_time,
4223 (unsigned long)cutoff)) {
4207 t = oo->oo_time - cutoff; 4224 t = oo->oo_time - cutoff;
4208 new_timeo = min(new_timeo, t); 4225 new_timeo = min(new_timeo, t);
4209 break; 4226 break;
4210 } 4227 }
4211 release_last_closed_stateid(oo); 4228 list_del_init(&oo->oo_close_lru);
4229 stp = oo->oo_last_closed_stid;
4230 oo->oo_last_closed_stid = NULL;
4231 spin_unlock(&nn->client_lock);
4232 nfs4_put_stid(&stp->st_stid);
4233 spin_lock(&nn->client_lock);
4212 } 4234 }
4235 spin_unlock(&nn->client_lock);
4236
4213 new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT); 4237 new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
4214 nfs4_unlock_state(); 4238 nfs4_unlock_state();
4215 return new_timeo; 4239 return new_timeo;