nfs4: treat lock owners as opaque values
authorJeff Layton <jlayton@poochiereds.net>
Thu, 1 May 2014 10:28:45 +0000 (06:28 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Sat, 12 Jul 2014 22:36:31 +0000 (18:36 -0400)
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>
fs/nfs/nfs4_fs.h
fs/nfs/nfs4state.c

index b8ea4a2..19f567c 100644 (file)
@@ -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 */
Simple merge