File Locking

Source 1 - Understanding Linux Kernel by Daniel Bovet and Marco Cesati

When a file can be accessed by more than one process, a synchronization problem occurs. Take the following two scenarios as an example -

Concurrent access to a file can, hence, result in unpredictable results. However, there's a solution to this - File Locking!

File locking can be of two types in Linux - Mandatory locking & Advisory (or record) locking. Regardless of whether processes use advisory or mandatory locks, they can use both shared read locks and exclusive write locks.

Several processes can have a shared read lock on some region (or whole file) but only one process can have a write lock on it at the same time. Moreover, it is not possible to get a write lock when another process owns a read lock for the same file region (or whole file), and vice versa, i.e., you cannot get a read lock on a region (or whole file) that is locked for writing.

Advisory File Locking

It is possible to lock an arbitrary region of a file (even a single byte) and hence a process can also hold multiple locks on different parts of the file i.e., it provides granularity. Such types of locks are known as advisory locks. This kind of lock does not keep out another process that is ignorant of locking i.e., the lock doesn’t work unless other processes cooperate in checking the existence of a lock before accessing the file.

![Here we see the Advisory lock at work. We can observe the following -

  1. Process 7 holds the read lock on the record 1 and hence Process 6 cannot obtain a record lock on it.
  2. A vice versa of the above scenario can be observed on record 5, i.e., Process 2 holds the write lock on the record 5 and hence Process 4 cannot obtain a read lock on it.](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9c6d8bd5-f15e-4b94-b64c-2c9e855669a1/Untitled.png)

Here we see the Advisory lock at work. We can observe the following -

  1. Process 7 holds the read lock on the record 1 and hence Process 6 cannot obtain a record lock on it.
  2. A vice versa of the above scenario can be observed on record 5, i.e., Process 2 holds the write lock on the record 5 and hence Process 4 cannot obtain a read lock on it.

Mandatory File Locking

A lock can be imposed on the entire file as opposed to only a region (record) of the file. Such types of locks are known as mandatory locks. Mandatory locking is kernel enforced file locking, as opposed to advisory file locking. This is because the kernel checks that every invocation of the open(), read(), and write() system calls does not violate a mandatory lock on the file being accessed.

Process 1 holds the mandatory write lock on the entire file and hence all the other processes (2, 3, 4 & 5) cannot access the file i.e., they cannot get the write lock (Processes 2 & 3) or the read lock (Processes 4 & 5) on the file.

Process 1 holds the mandatory write lock on the entire file and hence all the other processes (2, 3, 4 & 5) cannot access the file i.e., they cannot get the write lock (Processes 2 & 3) or the read lock (Processes 4 & 5) on the file.

Process 1, 2 & 4 hold the mandatory read lock on the entire file and hence all the Process 4 cannot access the file i.e., it cannot get the write lock on the file.

Process 1, 2 & 4 hold the mandatory read lock on the entire file and hence all the Process 4 cannot access the file i.e., it cannot get the write lock on the file.

Locking files with fcntl and the flock structure

(Source - man page for fcntl system call [man 2 fcntl])

The fcntl() system call can be used to acquire an advisory lock on a file's record. The general syntax of fcntl() system call is show below -

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */);

The commands specific to advisory locking are used -