Sample Header Ad - 728x90

Is mmap holding a reference to the OFD specified by POSIX, or a Linux extension, and where is it documented?

0 votes
1 answer
38 views
I am using Open File Description (OFD) owned locks on Linux (fcntl with command F_OFD_SETLK). After locking a file, I memory mapped it, and closed the file descriptor. Another process tried to lock the same file, and was unable to do so until the first process unmapped the memory. It seems Linux, at least, keeps a reference to the open file description when a mapping is still active. POSIX.1-2024 documents that [mmap](https://pubs.opengroup.org/onlinepubs/9799919799/functions/mmap.html) adds a reference to the "file associated with the file descriptor". > The mmap() function shall add an extra reference to the file associated with the file descriptor fildes which is not removed by a subsequent close() on that file descriptor. This reference shall be removed when there are no more mappings to the file. A literal interpretation here would mean that the reference is to the file itself, but I don't know if that was the intent when the documentation was written. I would like to be able to rely on this behavior. Is there somewhere in POSIX where it's specified that I am missing? Could this be a defect report? If it's Linux exclusive, is there a reference anywhere that this was their intended behavior (and, possibly, their interpretation of the POSIX standard)? Test program (might require different feature test macros on other platforms):
-c
#define _GNU_SOURCE

#include 
#include 
#include 
#include 
#include 

int main()
{
	char filename[] = "/tmp/ofd-test.XXXXXX";
	int fd = mkstemp(filename);
	if (fd < 0) {
		perror("mkstemp");
		return 1;
	}

	fprintf(stderr, "created file '%s'\n", filename);

	struct flock lock = {
		.l_len = 0,
		.l_pid = 0,
		.l_whence = SEEK_SET,
		.l_start = 0,
		.l_type = F_WRLCK,
	};
	if (fcntl(fd, F_OFD_SETLK, &lock) < 0) {
		perror("first lock");
		return 1;
	}

	void *ptr = mmap(0, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if (ptr == MAP_FAILED) {
		perror("mmap");
		return 1;
	}

	close(fd);

	int newfd = open(filename, O_RDWR);
	if (newfd < 0) {
		perror("re-open");
		return 1;
	}

	lock.l_pid = 0;
	if (fcntl(newfd, F_OFD_SETLK, &lock) == 0) {
		fputs("locking after mmap worked\n", stderr);
		return 1;
	}
	perror("locking after mmap");

	munmap(ptr, 1024);

	lock.l_pid = 0;
	if (fcntl(newfd, F_OFD_SETLK, &lock) < 0) {
		perror("locking after munmap");
		return 1;
	}
	fputs("locking after munmap worked\n", stderr);

	if (unlink(filename) < 0) {
		perror("unlink");
		return 1;
	}

	return 0;
}
For me, this outputs:
created file '/tmp/ofd-test.Pyf3oj'
locking after mmap: Resource temporarily unavailable
locking after munmap worked
Asked by &#201;rico Rolim (35 rep)
Sep 24, 2024, 03:10 PM
Last activity: Sep 24, 2024, 04:08 PM