Locking patches (generic & nfs)

From: Olaf Kirch (okir@suse.de)
Date: Fri Jul 19 2002 - 03:19:50 EST


Hi,

I've been investigating an NFS locking problem a customer
of SuSE has had between an OpenServer machine (oh boy)
acting as the NFS client and a Linux box acting as the server.

In the process of debugging this, I came across a number of
bugs in the 2.4.18 kernel.

fs/locks.c:
        When a program locks the entire file, and then does an unlock
        of just the first byte in the file, the kernel will not modify
        the existing lock because of an overflow/signedness problem.

fs/lockd/svclock.c, include/linux/lockd.h:
        Consider the following scenario:
         client A locks a file
         client B requests a conflicting lock, and asks
                for "blocking" mode.
                lockd creates a "struct block" and attaches
                it to the existing lock
         client A unlocks the file
                This causes a call to nlmsvc_notify_blocked,
                which puts the blocked lock onto a list
                of locks which sould be retried, setting
                the b_when field to 0.
        The next time lockd comes around to inspecting this
        list, it should notice that the lock can now be granted,
        and send a NLM_GRANTED message to client B.

        However, due to a signedness problem, the lock is
        appended to the *end* of the list, where it's never
        picked up.

fs/lockd/svcproc.c:
        There's an interoperability problem with OpenServer and
        probably other lockd implementations when it comes to
        handling of blocked locks.
        
        The way Linux clients deal with blocked locks goes
        like this

                C->S: lock this range, block if already taken
         (1) S->C: blocked
                ...
                (some other client removes the conflicting lock)
         (2) S->C: the lock has been granted
                 C->S: ack
         (3) C->S: lock this range, block if already taken
                S->C: granted

        At (1), the server records the fact that there's a blocking
        lock request, and uses it at (2) to find out whom to
        notify that the previously blocked request can now
        be granted. When the client then follows up with a
        LOCK call, the server notices that there's a blocked
        lock around and destroys it.

        Now OSR and maybe other lockd implementations do not
        follow up on the GRANTED callback with another LOCK
        call. According to the NLM spec this is sufficient,
        because the GRANTED callback actually says "the lock
        has been granted". The reason the Linux client does an
        additional LOCK call is for stability (the NLM protocol is
        full of race conditions).

        However, for this to work properly, the Linux lockd must interpret
        the client's response to the GRANTED callback. When receiving
        this "ack" (in fact, it's a GRANTED_RES call), it must look
        up the corresponding blocked lock and take if off the
        list of blocked locks. If it doesn't, server and client
        get out of sync wrt to who is blocking on what lock, and
        start timing out).
        (If you want details of what's exactly going wrong, mail me
        for a packet trace).

        At any rate, the above means that lockd needs to handle
        GRANTED_MSG properly. The functionality to do so is already
        there; it's just the handling of the RPC call itself that
        wasn't there (or has been removed for some reason).

        The second patch does this (even though for NFSv2 only; the
        NFSv3 case is analogous).

I'm also attaching the test program I used.

Cheers
Olaf

-- 
Olaf Kirch     |  Anyone who has had to work with X.509 has probably
okir@suse.de   |  experienced what can best be described as
---------------+  ISO water torture. -- Peter Gutmann




- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jul 23 2002 - 22:00:29 EST