From: Brandon S. Allbery (bsa@kf8nh.wariat.org)
Date: 06/13/93


From: bsa@kf8nh.wariat.org (Brandon S. Allbery)
Subject: Re: Locking mechanisms / fcntl.c locks.c
Date: Mon, 14 Jun 1993 02:04:28 GMT

In article <739984666.AA31812@remote.halcyon.com> Todd.Serulneck@f14.n333.z1.fidonet.org (Todd Serulneck) writes:
>I'm trying to figure out the best way to do some file locking. I'm working on
>putting together a message base that requires file locking. I've looked at the
>source code to Unaxcess BBS and find using lock files to be adequate, but
>slow, especially when needing to lock and unlock various files multiple times.

Lose it. I wrote UNaXcess intending a small system, since I was on a Radio
Shack Model 16 at the time. Both the system and the BBS usage rapidly outgrew
the existing code, and I didn't have the time to rewrite from scratch, so I
stopped working on it entirely.

It isn't lock files that cause the speed problem in any case: it's the fact
that the conference high message file is a single file for all conferences for
all users. This causes all sorts of problems in a system with more then a few
users or conferences, and especially on systems with multiple lines. The best
single thing you could possibly do is to give each user their own high-message
file.

The Model 16 origin is the reason why it uses lock files, also: there wasn't
anything else reliable and guaranteed to be available --- and NFS hadn't yet
become widespread enough for link-based locking to be a problem; if you mount
the message base via NFS you must *not* use lock files with the "guaranteed"
atomic behavior of link(), because it's neither guaranteed nor atomic over
NFS.

>The reference book I use, "Introduction to Unix" by Schulman and Que
>publishing, says that fcntl is a system call to change the way a file is
>accessed. When I used the man program, it said that fcntl was undocumented.
>When I tried calling it, the program wasn't there.

#include <fcntl.h>

struct flock fl;

fl.l_type = F_RDLCK; /* or F_WRLCK to allow reads */
fl.l_whence = 0; /* actually same as lseek() 3rd argument */
fl.l_start = offset; /* same as lseek() second argument */
fl.l_len = size; /* number of bytes to lock, 0 = to end of file */
/* fl.l_pid is used only by F_GETLK to indicate the owner of a lock */
fcntl(fd, F_SETLKW, &fl); /* lock file, blocking if necessary */
/* F_GETLK: return lock status; F_SETLK: non-blocking lock request */

System V requires read access for F_WRLCK and write access for F_RDLCK. I
don't know if Linux does this as well --- but I would hope not, since it won't
harm compatibility and the System V behavior is arguably overly strict.

Note also that fcntl() locking won't work over NFS. You need to use lockf()
for that, I believe.

++Brandon

-- 
Brandon S. Allbery         kf8nh@kf8nh.ampr.org          bsa@kf8nh.wariat.org

It's not too late to turn back from the "Gates" of Hell... Linux: the free 32-bit operating system, available NOW. Why waaaaaait for NT?