Skip to content
  • Benjamin Coddington's avatar
    fs/locks: Remove fl_nspid and use fs-specific l_pid for remote locks · 9d5b86ac
    Benjamin Coddington authored
    Since commit c69899a1
    
     "NFSv4: Update of VFS byte range lock must be
    atomic with the stateid update", NFSv4 has been inserting locks in rpciod
    worker context.  The result is that the file_lock's fl_nspid is the
    kworker's pid instead of the original userspace pid.
    
    The fl_nspid is only used to represent the namespaced virtual pid number
    when displaying locks or returning from F_GETLK.  There's no reason to set
    it for every inserted lock, since we can usually just look it up from
    fl_pid.  So, instead of looking up and holding struct pid for every lock,
    let's just look up the virtual pid number from fl_pid when it is needed.
    That means we can remove fl_nspid entirely.
    
    The translaton and presentation of fl_pid should handle the following four
    cases:
    
    1 - F_GETLK on a remote file with a remote lock:
        In this case, the filesystem should determine the l_pid to return here.
        Filesystems should indicate that the fl_pid represents a non-local pid
        value that should not be translated by returning an fl_pid <= 0.
    
    2 - F_GETLK on a local file with a remote lock:
        This should be the l_pid of the lock manager process, and translated.
    
    3 - F_GETLK on a remote file with a local lock, and
    4 - F_GETLK on a local file with a local lock:
        These should be the translated l_pid of the local locking process.
    
    Fuse was already doing the correct thing by translating the pid into the
    caller's namespace.  With this change we must update fuse to translate
    to init's pid namespace, so that the locks API can then translate from
    init's pid namespace into the pid namespace of the caller.
    
    With this change, the locks API will expect that if a filesystem returns
    a remote pid as opposed to a local pid for F_GETLK, that remote pid will
    be <= 0.  This signifies that the pid is remote, and the locks API will
    forego translating that pid into the pid namespace of the local calling
    process.
    
    Finally, we convert remote filesystems to present remote pids using
    negative numbers. Have lustre, 9p, ceph, cifs, and dlm negate the remote
    pid returned for F_GETLK lock requests.
    
    Since local pids will never be larger than PID_MAX_LIMIT (which is
    currently defined as <= 4 million), but pid_t is an unsigned int, we
    should have plenty of room to represent remote pids with negative
    numbers if we assume that remote pid numbers are similarly limited.
    
    If this is not the case, then we run the risk of having a remote pid
    returned for which there is also a corresponding local pid.  This is a
    problem we have now, but this patch should reduce the chances of that
    occurring, while also returning those remote pid numbers, for whatever
    that may be worth.
    
    Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
    Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
    9d5b86ac