locks: fix tracking of inprogress lease breaks
authorJ. Bruce Fields <bfields@redhat.com>
Tue, 26 Jul 2011 22:25:49 +0000 (18:25 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 19 Aug 2011 17:25:34 +0000 (13:25 -0400)
commit778fc546f749c588aa2f6cd50215d2715c374252
treeb3ffa04327884cd0491c3ee1677f0ffc589ebe9c
parent710b7216964d6455cf1b215c43b03a1a79008c7d
locks: fix tracking of inprogress lease breaks

We currently use a bit in fl_flags to record whether a lease is being
broken, and set fl_type to the type (RDLCK or UNLCK) that it will
eventually have.  This means that once the lease break starts, we forget
what the lease's type *used* to be.  Breaking a read lease will then
result in blocking read opens, even though there's no conflict--because
the lease type is now F_UNLCK and we can no longer tell whether it was
previously a read or write lease.

So, instead keep fl_type as the original type (the type which we
enforce), and keep track of whether we're unlocking or merely
downgrading by replacing the single FL_INPROGRESS flag by
FL_UNLOCK_PENDING and FL_DOWNGRADE_PENDING flags.

To get this right we also need to track separate downgrade and break
times, to handle the case where a write-leased file gets conflicting
opens first for read, then later for write.

(I first considered just eliminating the downgrade behavior
completely--nfsv4 doesn't need it, and nobody as far as I can tell
actually uses it currently--but Jeremy Allison tells me that Windows
oplocks do behave this way, so Samba will probably use this some day.)

Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/locks.c
include/linux/fs.h