Skip to content

Commit

Permalink
nfsd4: fix lockowner matching
Browse files Browse the repository at this point in the history
commit b93d87c upstream.

Lockowners are looked up by file as well as by owner, but we were
forgetting to do a comparison on the file.  This could cause an
incorrect result from lockt.

(Note looking up the inode from the lockowner is pretty awkward here.
The data structures need fixing.)

Signed-off-by: J. Bruce Fields <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
J. Bruce Fields authored and gregkh committed Jan 26, 2012
1 parent dd96317 commit 4c5ecfd
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -3809,16 +3809,29 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
deny->ld_type = NFS4_WRITE_LT;
}

static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner)
{
struct nfs4_ol_stateid *lst;

if (!same_owner_str(&lo->lo_owner, owner, clid))
return false;
lst = list_first_entry(&lo->lo_owner.so_stateids,
struct nfs4_ol_stateid, st_perstateowner);
return lst->st_file->fi_inode == inode;
}

static struct nfs4_lockowner *
find_lockowner_str(struct inode *inode, clientid_t *clid,
struct xdr_netobj *owner)
{
unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner);
struct nfs4_lockowner *lo;
struct nfs4_stateowner *op;

list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) {
if (same_owner_str(op, owner, clid))
return lockowner(op);
lo = lockowner(op);
if (same_lockowner_ino(lo, inode, clid, owner))
return lo;
}
return NULL;
}
Expand Down

0 comments on commit 4c5ecfd

Please sign in to comment.