Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+31 −7
Original line number Original line Diff line number Diff line
@@ -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,
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)
		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)
	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)
		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;