Gidday,
Now I gather that Linux file leases (fcntl(fd, F_SETLEASE, lease)
and fcntl(fd, F_GETLEASE)) are provided for Samba support.
I'm investigating if they're more generally useful, and I've
run into a couple of issues which are either bugs, or failures in my
understanding (possible, since there is no documentation that I can find
explaining how file leases _should_ operate - I have by now had a good
look at the source code, but the intent of the code is not clear).
I'll describe two scenarios, and my expectations, and ask 5 questions.
Cheers,
Michael
The following experiments were conducted on kernel 2.4.18, Intel x86.
SCENARIO A:
===========
1. Process A (PID 13912) opens file X for reading.
2. Process B (PID 13912) opens file X for reading.
3. Process A sets a READ lease on file X.
4. Process B sets a READ lease on file X.
We now see the following in /proc/locks:
$ cat /proc/locks | grep LEASE
1: LEASE MANDATORY READ 13912 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72e10
00000000 c1f72d60
2: LEASE MANDATORY READ 13910 03:0b:72627 0 EOF c1f72e0c c1f72d58 c1f72f80
c1f72d54 c1f72e18
5. Process C (PID 13924) opens file X read-write - this blocks,
process A gets a SIGIO (or other) signal.
QUESTION 1: Why doesn't process B (which also holds a WRITE lease)
get signalled at this point?
$ cat /proc/locks | grep LEASE
1: LEASE MANDATORY READ 13912 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72e10
00000000 c1f72d60
2: LEASE MANDATORY READ 13910 03:0b:72627 0 EOF c1f72e0c c1f72d58 c1f72f80
c1f72d54 c1f720cc
2: -> LEASE MANDATORY READ 13924 <none>:0 0 EOF c1f720c0 c02cbaf0 c02cbaf0
c1f72e0c c1f72e18
6. Process A does not remove its lease explicitly, so that after the
lease-break timeout (45 secs) expires, the kernel breaks the lease
and process C's open succeeeds.
At this point F_GETLEASE in Process B returns F_UNLCK, BUT according
to/proc/locks Process B still holds a lease on the file:
$ cat /proc/locks | grep LEASE
1: LEASE MANDATORY READ 13912 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72f80
00000000 c1f72d60
QUESTION 2: Have (should) the leases by both processes (A & B) been (be)
broken by the kernel at this point? (I expected so, but the output
from /proc/locks, plus the following results are confusing.)
7. Process C exits.
8. Process D (PID 13958) opens file X read-write - this blocks:
$ cat /proc/locks | grep LEASE
1: LEASE MANDATORY READ 13912 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72f80
00000000 c1f720cc
1: -> LEASE MANDATORY READ 13958 <none>:0 0 EOF c1f720c0 c02cbaf0 c02cbaf0
c1f72d54 c1f72d60
9. Process B is NOT signaled. Unless Process B explicitly removes its
lease using F_SETLEASE-F_UNLCK (or closes its file descriptor, or
terminates) then process D remains blocked forever!
QUESTION 3: Is this really expected behavior, or is something broken?
(If things aren't broken, what does it mean for two processes to set
read leases on a file, and why aren't they both signalled?)
(As a variation of this scenario, at step 6, I tried having Process A
explicitly remove its lease (Process B did nothing). In this case,
Process C remained blocked until the 45-second lease timeout. Then
Process C's open unblocked, and looking in /proc/locks showed that
both Process A and Process B's leases were removed. This seems
reasonable behavior.)
SCENARIO B:
===========
(As I investigated this further it really seems like a variation on
the last part of the previous scenario).
1. Process A (PID=13980) opens file X read-write and obtains a
WRITE lease on it.
$ cat /proc/locks | grep LEASE
1: LEASE MANDATORY WRITE 13980 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72f80
00000000 c1f72d60
2. Process B opens file X for read-write specifying the O_NONBLOCK flag.
The open() returns immediately with EWOULDBLOCK.
(Alternatively: Process B performs a normal open(), but the blocked
call is prematurely terminated by catching a signal or by abnormal
process termination.)
3. Process A is sent SIGIO, and its WRITE lease is downgraded to F_UNLCK
(as revealed by F_GETLEASE). BUT, we see the following:
$ cat /proc/locks
1: LEASE MANDATORY READ 13980 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72f80
00000000 c1f72d60
4. Process B exits.
5. Process C (PID 14002) opens file X for writing (_without_ O_NONBLOCK).
6. Process A receives no signal. Process C blocks indefinitely,
unless Process A explicitly sets the lease to F_UNLCK
(or closes the file descriptor, or terminates).
$ cat /proc/locks | grep LEASE
1: LEASE MANDATORY READ 13980 03:0b:72627 0 EOF c1f72d54 c02cbae8 c1f72f80
00000000 c1f72dbc
1: -> LEASE MANDATORY READ 14002 <none>:0 0 EOF c1f72db0 c02cbaf0 c02cbaf0
c1f72d54 c1f72d60
QUESTION 4: Is this a bug?
And another question unrelated to the above two scenarios:
QUESTION 5:
Suppose that Process A sets a WRITE lease on a file, and Process B opens the
file for reading (blocks). At this point, I would have thought that if
Process A does an explicit F_SETLEASE-F_RDLCK, then this should be
enough to allow Process B's open to unblock (since, in the current
implementation, a read lease is compatible with an open for reading).
However, this is not so: Process A must do an F_SETLEASE-F_UNLCK.
Why is setting the lease to F_RDLCK insufficient?
-- GMX - Die Kommunikationsplattform im Internet. http://www.gmx.net- 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 May 07 2002 - 22:00:10 EST