Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 3124
b: refs/heads/master
c: 3e9e3db
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Jun 24, 2005
1 parent 8953306 commit a251f52
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ea1da636e956ad1591a74904f23d98bbc26a644b
refs/heads/master: 3e9e3dbe0fe36c824ce2c5d7b05997c87a64bbdc
76 changes: 33 additions & 43 deletions trunk/fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -2583,22 +2583,6 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
deny->ld_type = NFS4_WRITE_LT;
}

static struct nfs4_stateowner *
find_lockstateowner(struct xdr_netobj *owner, clientid_t *clid)
{
struct nfs4_stateowner *local = NULL;
int i;

for (i = 0; i < LOCK_HASH_SIZE; i++) {
list_for_each_entry(local, &lock_ownerid_hashtbl[i], so_idhash) {
if (!cmp_owner_str(local, owner, clid))
continue;
return local;
}
}
return NULL;
}

static struct nfs4_stateowner *
find_lockstateowner_str(struct inode *inode, clientid_t *clid,
struct xdr_netobj *owner)
Expand Down Expand Up @@ -2697,7 +2681,7 @@ check_lock_length(u64 offset, u64 length)
int
nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
{
struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
struct nfs4_stateowner *open_sop = NULL;
struct nfs4_stateid *lock_stp;
struct file *filp;
struct file_lock file_lock;
Expand Down Expand Up @@ -2756,16 +2740,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
strhashval = lock_ownerstr_hashval(fp->fi_inode,
open_sop->so_client->cl_clientid.cl_id,
&lock->v.new.owner);
/*
* If we already have this lock owner, the client is in
* error (or our bookeeping is wrong!)
* for asking for a 'new lock'.
*/
status = nfserr_bad_stateid;
lock_sop = find_lockstateowner(&lock->v.new.owner,
&lock->v.new.clientid);
if (lock_sop)
goto out;
/* XXX: Do we need to check for duplicate stateowners on
* the same file, or should they just be allowed (and
* create new stateids)? */
status = nfserr_resource;
if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
goto out;
Expand Down Expand Up @@ -3056,8 +3033,11 @@ int
nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
{
clientid_t *clid = &rlockowner->rl_clientid;
struct nfs4_stateowner *local = NULL;
struct nfs4_stateowner *sop;
struct nfs4_stateid *stp;
struct xdr_netobj *owner = &rlockowner->rl_owner;
struct list_head matches;
int i;
int status;

dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
Expand All @@ -3073,22 +3053,32 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *

nfs4_lock_state();

status = nfs_ok;
local = find_lockstateowner(owner, clid);
if (local) {
struct nfs4_stateid *stp;

/* check for any locks held by any stateid
* associated with the (lock) stateowner */
status = nfserr_locks_held;
list_for_each_entry(stp, &local->so_stateids,
st_perstateowner) {
if (check_for_locks(stp->st_vfs_file, local))
goto out;
status = nfserr_locks_held;
/* XXX: we're doing a linear search through all the lockowners.
* Yipes! For now we'll just hope clients aren't really using
* release_lockowner much, but eventually we have to fix these
* data structures. */
INIT_LIST_HEAD(&matches);
for (i = 0; i < LOCK_HASH_SIZE; i++) {
list_for_each_entry(sop, &lock_ownerid_hashtbl[i], so_idhash) {
if (!cmp_owner_str(sop, owner, clid))
continue;
list_for_each_entry(stp, &sop->so_stateids,
st_perstateowner) {
if (check_for_locks(stp->st_vfs_file, sop))
goto out;
/* Note: so_perclient unused for lockowners,
* so it's OK to fool with here. */
list_add(&sop->so_perclient, &matches);
}
}
/* no locks held by (lock) stateowner */
status = nfs_ok;
release_stateowner(local);
}
/* Clients probably won't expect us to return with some (but not all)
* of the lockowner state released; so don't release any until all
* have been checked. */
status = nfs_ok;
list_for_each_entry(sop, &matches, so_perclient) {
release_stateowner(sop);
}
out:
nfs4_unlock_state();
Expand Down

0 comments on commit a251f52

Please sign in to comment.