Commit 217526e7 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields

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: default avatarJeff Layton <jlayton@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 0a880a28
...@@ -1122,13 +1122,19 @@ static void unhash_openowner_locked(struct nfs4_openowner *oo) ...@@ -1122,13 +1122,19 @@ static void unhash_openowner_locked(struct nfs4_openowner *oo)
static void release_last_closed_stateid(struct nfs4_openowner *oo) static void release_last_closed_stateid(struct nfs4_openowner *oo)
{ {
struct nfs4_ol_stateid *s = oo->oo_last_closed_stid; struct nfsd_net *nn = net_generic(oo->oo_owner.so_client->net,
nfsd_net_id);
struct nfs4_ol_stateid *s;
spin_lock(&nn->client_lock);
s = oo->oo_last_closed_stid;
if (s) { if (s) {
list_del_init(&oo->oo_close_lru); list_del_init(&oo->oo_close_lru);
oo->oo_last_closed_stid = NULL; oo->oo_last_closed_stid = NULL;
nfs4_put_stid(&s->st_stid);
} }
spin_unlock(&nn->client_lock);
if (s)
nfs4_put_stid(&s->st_stid);
} }
static void release_openowner(struct nfs4_openowner *oo) static 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, ...@@ -3265,6 +3271,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
static void static void
move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
{ {
struct nfs4_ol_stateid *last;
struct nfs4_openowner *oo = openowner(s->st_stateowner); struct nfs4_openowner *oo = openowner(s->st_stateowner);
struct nfsd_net *nn = net_generic(s->st_stid.sc_client->net, struct nfsd_net *nn = net_generic(s->st_stid.sc_client->net,
nfsd_net_id); nfsd_net_id);
...@@ -3287,10 +3294,15 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) ...@@ -3287,10 +3294,15 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
put_nfs4_file(s->st_stid.sc_file); put_nfs4_file(s->st_stid.sc_file);
s->st_stid.sc_file = NULL; s->st_stid.sc_file = NULL;
} }
release_last_closed_stateid(oo);
spin_lock(&nn->client_lock);
last = oo->oo_last_closed_stid;
oo->oo_last_closed_stid = s; oo->oo_last_closed_stid = s;
list_move_tail(&oo->oo_close_lru, &nn->close_lru); list_move_tail(&oo->oo_close_lru, &nn->close_lru);
oo->oo_time = get_seconds(); oo->oo_time = get_seconds();
spin_unlock(&nn->client_lock);
if (last)
nfs4_put_stid(&last->st_stid);
} }
/* search file_hashtbl[] for file */ /* search file_hashtbl[] for file */
...@@ -4148,6 +4160,7 @@ nfs4_laundromat(struct nfsd_net *nn) ...@@ -4148,6 +4160,7 @@ nfs4_laundromat(struct nfsd_net *nn)
struct nfs4_client *clp; struct nfs4_client *clp;
struct nfs4_openowner *oo; struct nfs4_openowner *oo;
struct nfs4_delegation *dp; struct nfs4_delegation *dp;
struct nfs4_ol_stateid *stp;
struct list_head *pos, *next, reaplist; struct list_head *pos, *next, reaplist;
time_t cutoff = get_seconds() - nn->nfsd4_lease; time_t cutoff = get_seconds() - nn->nfsd4_lease;
time_t t, new_timeo = nn->nfsd4_lease; time_t t, new_timeo = nn->nfsd4_lease;
...@@ -4201,15 +4214,26 @@ nfs4_laundromat(struct nfsd_net *nn) ...@@ -4201,15 +4214,26 @@ nfs4_laundromat(struct nfsd_net *nn)
list_del_init(&dp->dl_recall_lru); list_del_init(&dp->dl_recall_lru);
revoke_delegation(dp); revoke_delegation(dp);
} }
list_for_each_safe(pos, next, &nn->close_lru) {
oo = container_of(pos, struct nfs4_openowner, oo_close_lru); spin_lock(&nn->client_lock);
if (time_after((unsigned long)oo->oo_time, (unsigned long)cutoff)) { while (!list_empty(&nn->close_lru)) {
oo = list_first_entry(&nn->close_lru, struct nfs4_openowner,
oo_close_lru);
if (time_after((unsigned long)oo->oo_time,
(unsigned long)cutoff)) {
t = oo->oo_time - cutoff; t = oo->oo_time - cutoff;
new_timeo = min(new_timeo, t); new_timeo = min(new_timeo, t);
break; break;
} }
release_last_closed_stateid(oo); list_del_init(&oo->oo_close_lru);
stp = oo->oo_last_closed_stid;
oo->oo_last_closed_stid = NULL;
spin_unlock(&nn->client_lock);
nfs4_put_stid(&stp->st_stid);
spin_lock(&nn->client_lock);
} }
spin_unlock(&nn->client_lock);
new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT); new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
nfs4_unlock_state(); nfs4_unlock_state();
return new_timeo; return new_timeo;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment