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

Commit 5adfd885 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields
Browse files

nfsd: clean up refcounting for lockowners



Ensure that lockowner references are only held by lockstateids and
operations that are in-progress. With this, we can get rid of
release_lockowner_if_empty, which will be racy once we remove
client_mutex protection.

Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent e4f1dd7f
Loading
Loading
Loading
Loading
+7 −22
Original line number Diff line number Diff line
@@ -933,7 +933,7 @@ static void nfs4_free_lock_stateid(struct nfs4_stid *stid)
	nfs4_free_ol_stateid(stid);
}

static void __release_lock_stateid(struct nfs4_ol_stateid *stp)
static void release_lock_stateid(struct nfs4_ol_stateid *stp)
{
	struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);

@@ -957,7 +957,7 @@ static void release_lockowner_stateids(struct nfs4_lockowner *lo)
	while (!list_empty(&lo->lo_owner.so_stateids)) {
		stp = list_first_entry(&lo->lo_owner.so_stateids,
				struct nfs4_ol_stateid, st_perstateowner);
		__release_lock_stateid(stp);
		release_lock_stateid(stp);
	}
}

@@ -968,21 +968,6 @@ static void release_lockowner(struct nfs4_lockowner *lo)
	nfs4_put_stateowner(&lo->lo_owner);
}

static void release_lockowner_if_empty(struct nfs4_lockowner *lo)
{
	if (list_empty(&lo->lo_owner.so_stateids))
		release_lockowner(lo);
}

static void release_lock_stateid(struct nfs4_ol_stateid *stp)
{
	struct nfs4_lockowner *lo;

	lo = lockowner(stp->st_stateowner);
	__release_lock_stateid(stp);
	release_lockowner_if_empty(lo);
}

static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp)
	__releases(&open_stp->st_stateowner->so_client->cl_lock)
	__acquires(&open_stp->st_stateowner->so_client->cl_lock)
@@ -4323,7 +4308,7 @@ nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)

	if (check_for_locks(stp->st_stid.sc_file, lo))
		return nfserr_locks_held;
	release_lockowner_if_empty(lo);
	release_lock_stateid(stp);
	return nfs_ok;
}

@@ -4938,8 +4923,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
		lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock);
		if (lo == NULL)
			return nfserr_jukebox;
		/* FIXME: extra reference for new lockowners for the client */
		atomic_inc(&lo->lo_owner.so_count);
	} else {
		/* with an existing lockowner, seqids must be the same */
		status = nfserr_bad_seqid;
@@ -4950,7 +4933,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,

	*lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
	if (*lst == NULL) {
		release_lockowner_if_empty(lo);
		status = nfserr_jukebox;
		goto out;
	}
@@ -5379,6 +5361,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
			continue;
		if (same_owner_str(tmp, owner, clid)) {
			sop = tmp;
			atomic_inc(&sop->so_count);
			break;
		}
	}
@@ -5392,9 +5375,11 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
	lo = lockowner(sop);
	/* see if there are still any locks associated with it */
	list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
		if (check_for_locks(stp->st_stid.sc_file, lo))
		if (check_for_locks(stp->st_stid.sc_file, lo)) {
			nfs4_put_stateowner(sop);
			goto out;
		}
	}

	status = nfs_ok;
	release_lockowner(lo);