diff options
author | Jeff Layton <jlayton@poochiereds.net> | 2014-05-01 12:28:45 +0200 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-07-13 00:36:31 +0200 |
commit | 8003d3c4aaa5560400818e14ce5db49cdfd79865 (patch) | |
tree | 1a3e9445ad2aec42200cf0ec604e599ec4cd3dc1 /fs/nfs/nfs4_fs.h | |
parent | nfs41: layout return on close in delegation return (diff) | |
download | linux-8003d3c4aaa5560400818e14ce5db49cdfd79865.tar.xz linux-8003d3c4aaa5560400818e14ce5db49cdfd79865.zip |
nfs4: treat lock owners as opaque values
Do the following set of ops with a file on a NFSv4 mount:
exec 3>>/file/on/nfsv4
flock -x 3
exec 3>&-
You'll see the LOCK request go across the wire, but no LOCKU when the
file is closed.
What happens is that the fd is passed across a fork, and the final close
is done in a different process than the opener. That makes
__nfs4_find_lock_state miss finding the correct lock state because it
uses the fl_pid as a search key. A new one is created, and the locking
code treats it as a delegation stateid (because NFS_LOCK_INITIALIZED
isn't set).
The root cause of this breakage seems to be commit 77041ed9b49a9e
(NFSv4: Ensure the lockowners are labelled using the fl_owner and/or
fl_pid).
That changed it so that flock lockowners are allocated based on the
fl_pid. I think this is incorrect. flock locks should be "owned" by the
struct file, and that is already accounted for in the fl_owner field of
the lock request when it comes through nfs_flock.
This patch basically reverts the above commit and with it, a LOCKU is
sent in the above reproducer.
Signed-off-by: Jeff Layton <jlayton@poochiereds.net>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/nfs4_fs.h')
-rw-r--r-- | fs/nfs/nfs4_fs.h | 13 |
1 files changed, 1 insertions, 12 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index b8ea4a26998c..19f567c39670 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -129,17 +129,6 @@ enum { * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN) */ -struct nfs4_lock_owner { - unsigned int lo_type; -#define NFS4_ANY_LOCK_TYPE (0U) -#define NFS4_FLOCK_LOCK_TYPE (1U << 0) -#define NFS4_POSIX_LOCK_TYPE (1U << 1) - union { - fl_owner_t posix_owner; - pid_t flock_owner; - } lo_u; -}; - struct nfs4_lock_state { struct list_head ls_locks; /* Other lock stateids */ struct nfs4_state * ls_state; /* Pointer to open state */ @@ -149,7 +138,7 @@ struct nfs4_lock_state { struct nfs_seqid_counter ls_seqid; nfs4_stateid ls_stateid; atomic_t ls_count; - struct nfs4_lock_owner ls_owner; + fl_owner_t ls_owner; }; /* bits for nfs4_state->flags */ |