• Chuck Lever's avatar
    nfsd: Fix race between FREE_STATEID and LOCK · 42691398
    Chuck Lever authored
    When running LTP's nfslock01 test, the Linux client can send a LOCK
    and a FREE_STATEID request at the same time. The outcome is:
    
    Frame 324    R OPEN stateid [2,O]
    
    Frame 115004 C LOCK lockowner_is_new stateid [2,O] offset 672000 len 64
    Frame 115008 R LOCK stateid [1,L]
    Frame 115012 C WRITE stateid [0,L] offset 672000 len 64
    Frame 115016 R WRITE NFS4_OK
    Frame 115019 C LOCKU stateid [1,L] offset 672000 len 64
    Frame 115022 R LOCKU NFS4_OK
    Frame 115025 C FREE_STATEID stateid [2,L]
    Frame 115026 C LOCK lockowner_is_new stateid [2,O] offset 672128 len 64
    Frame 115029 R FREE_STATEID NFS4_OK
    Frame 115030 R LOCK stateid [3,L]
    Frame 115034 C WRITE stateid [0,L] offset 672128 len 64
    Frame 115038 R WRITE NFS4ERR_BAD_STATEID
    
    In other words, the server returns stateid L in a successful LOCK
    reply, but it has already released it. Subsequent uses of stateid L
    fail.
    
    To address this, protect the generation check in nfsd4_free_stateid
    with the st_mutex. This should guarantee that only one of two
    outcomes occurs: either LOCK returns a fresh valid stateid, or
    FREE_STATEID returns NFS4ERR_LOCKS_HELD.
    Reported-by: default avatarAlexey Kodanev <alexey.kodanev@oracle.com>
    Fix-suggested-by: default avatarJeff Layton <jlayton@redhat.com>
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    Tested-by: default avatarAlexey Kodanev <alexey.kodanev@oracle.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    42691398
nfs4state.c 176 KB