DBase File locking issues (PR#20441)
Jeremy Allison
jallison at cthulhu.engr.sgi.com
Fri Sep 17 02:07:06 GMT 1999
Jim at Morris.net wrote:
>
> The same test against the Samba 2.0.5a server(s) shows that the lock()
> call ALWAYS returns a 0 (zero) status - even if a different PC already
> has a lock!
Ok, I now understand the problem exactly. It *IS* the 64-bit
glibc2.1 bug with Linux on x86 biting us again. Let me explain :
On a full 64 bit system (IRIX), the value 0xEFFFFFFF is a
valid POSIX lock range (as it is a positive value less than
2^63 - 1), so locking a byte at this range succeeds, and
a second client attempt to lock this byte will fail (ie. the
lock conflicts). Thus on a 64 bit system the clients
conflict correctly. I have demonstrated this with my
test Win32 client code working perfectly against a Samba
server on an IRIX 6.5.x box.
Unfortunately, on x86 Linux using glibc2.1, the libc claims
to have 64 bit support, but really doesn't. Thus, the
datatype off_t is sized as 64 bits, even though the
underlying filesystem and locking mechanisms don't
support 64 bit ranges.
So what happens is that Samba thinks the underlying
system is 64 bit clean, and the locking workaround is
not activated, as 0xEFFFFFFF fits in 32 bits (this
locking workaround is only activated on a system with
non-working 64 bit locks when the client, usually NT,
sends a 64 bit lock range - this is a *client* bug...).
With me so far ?
In addition to the 64 bit locking workaround added in
2.0.5, Samba also has unsigned -> signed lock mangling code to
deal with the fact that Windows lock ranges are unsigned
and POSIX lock ranges are signed (ie. 0xEFFFFFFF is a
valid Windows lock range on a 32 bit system, but not
on a 32 bit POSIX system as it would be negative). But
because Samba on x86 Linux with glibc2.1 is being told off_t
is 64 bits this unsigned -> signed lock mangling code is never
activated (as 0x00000000EFFFFFFF is a positive 64 bit value), so the
64 bit value 0x00000000EFFFFFFF is being passed down to glibc
fcntl locking as a valid positive lock range. The
internals of glibc throws away the top 32 bits of this lock range
(which are zeros) and is left with a 32 bit value of
0xEFFFFFFF - which is a *negative* 32 bit value and
hence invalid as a POSIX lock range. So glibc 2.1 returns
an EINVAL error and that legacy code in Samba is then returning
True (meaning ok - lock granted).
I will fix Samba for 2.0.6 so that 64 bit code is *never*
activated on a Linux box and will have to leave it that
way until Linux truely is 64 bit. I have also removed the
legacy code in Samba that interprets EINVAL as a valid lock.
Give me a day or so and I'll have an RPM you can use to test
your code with.
Regards,
Jeremy Allison,
Samba Team.
--
--------------------------------------------------------
Buying an operating system without source is like buying
a self-assembly Space Shuttle with no instructions.
--------------------------------------------------------
More information about the samba
mailing list