summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2013-04-07 13:28:16 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-04-09 09:08:56 -0400
commiteb2099f31b0f090684a64ef8df44a30ff7c45fc2 (patch)
treec413f56772a69937303a3b0f6a2e8ee039fa6e14
parentbbc9c36c31fc5827c22359a8b0ba9dd71b5eecfc (diff)
downloadblackbird-op-linux-eb2099f31b0f090684a64ef8df44a30ff7c45fc2.tar.gz
blackbird-op-linux-eb2099f31b0f090684a64ef8df44a30ff7c45fc2.zip
nfsd4: release lockowners on last unlock in 4.1 case
In the 4.1 case we're supposed to release lockowners as soon as they're no longer used. It would probably be more efficient to reference count them, but that's slightly fiddly due to the need to have callbacks from locks.c to take into account lock merging and splitting. For most cases just scanning the inode's lock list on unlock for matching locks will be sufficient. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4state.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 16db25dc364f..ff1577d6df62 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4387,6 +4387,7 @@ __be32
nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_locku *locku)
{
+ struct nfs4_lockowner *lo;
struct nfs4_ol_stateid *stp;
struct file *filp = NULL;
struct file_lock *file_lock = NULL;
@@ -4419,9 +4420,10 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfserr_jukebox;
goto out;
}
+ lo = lockowner(stp->st_stateowner);
locks_init_lock(file_lock);
file_lock->fl_type = F_UNLCK;
- file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
+ file_lock->fl_owner = (fl_owner_t)lo;
file_lock->fl_pid = current->tgid;
file_lock->fl_file = filp;
file_lock->fl_flags = FL_POSIX;
@@ -4440,6 +4442,11 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
update_stateid(&stp->st_stid.sc_stateid);
memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+ if (nfsd4_has_session(cstate) && !check_for_locks(stp->st_file, lo)) {
+ WARN_ON_ONCE(cstate->replay_owner);
+ release_lockowner(lo);
+ }
+
out:
nfsd4_bump_seqid(cstate, status);
if (!cstate->replay_owner)
OpenPOWER on IntegriCloud