File Index
Files and directories
Sign in
FILE

ofdlocks.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/filelock/ofdlocks.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#define _GNU_SOURCE
  4#include <fcntl.h>
  5#include <assert.h>
  6#include <stdio.h>
  7#include <unistd.h>
  8#include <string.h>
  9#include "kselftest.h"
 10
 11static int lock_set(int fd, struct flock *fl)
 12{
 13	int ret;
 14
 15	fl->l_pid = 0;		// needed for OFD locks
 16	fl->l_whence = SEEK_SET;
 17	ret = fcntl(fd, F_OFD_SETLK, fl);
 18	if (ret)
 19		perror("fcntl()");
 20	return ret;
 21}
 22
 23static int lock_get(int fd, struct flock *fl)
 24{
 25	int ret;
 26
 27	fl->l_pid = 0;		// needed for OFD locks
 28	fl->l_whence = SEEK_SET;
 29	ret = fcntl(fd, F_OFD_GETLK, fl);
 30	if (ret)
 31		perror("fcntl()");
 32	return ret;
 33}
 34
 35int main(void)
 36{
 37	int rc;
 38	struct flock fl, fl2;
 39	int fd = open("/tmp/aa", O_RDWR | O_CREAT | O_EXCL, 0600);
 40	int fd2 = open("/tmp/aa", O_RDONLY);
 41
 42	unlink("/tmp/aa");
 43	assert(fd != -1);
 44	assert(fd2 != -1);
 45	ksft_print_msg("[INFO] opened fds %i %i\n", fd, fd2);
 46
 47	/* Set some read lock */
 48	fl.l_type = F_RDLCK;
 49	fl.l_start = 5;
 50	fl.l_len = 3;
 51	rc = lock_set(fd, &fl);
 52	if (rc == 0) {
 53		ksft_print_msg
 54		    ("[SUCCESS] set OFD read lock on first fd\n");
 55	} else {
 56		ksft_print_msg("[FAIL] to set OFD read lock on first fd\n");
 57		return -1;
 58	}
 59	/* Make sure read locks do not conflict on different fds. */
 60	fl.l_type = F_RDLCK;
 61	fl.l_start = 5;
 62	fl.l_len = 1;
 63	rc = lock_get(fd2, &fl);
 64	if (rc != 0)
 65		return -1;
 66	if (fl.l_type != F_UNLCK) {
 67		ksft_print_msg("[FAIL] read locks conflicted\n");
 68		return -1;
 69	}
 70	/* Make sure read/write locks do conflict on different fds. */
 71	fl.l_type = F_WRLCK;
 72	fl.l_start = 5;
 73	fl.l_len = 1;
 74	rc = lock_get(fd2, &fl);
 75	if (rc != 0)
 76		return -1;
 77	if (fl.l_type != F_UNLCK) {
 78		ksft_print_msg
 79		    ("[SUCCESS] read and write locks conflicted\n");
 80	} else {
 81		ksft_print_msg
 82		    ("[SUCCESS] read and write locks not conflicted\n");
 83		return -1;
 84	}
 85	/* Get info about the lock on first fd. */
 86	fl.l_type = F_UNLCK;
 87	fl.l_start = 5;
 88	fl.l_len = 1;
 89	rc = lock_get(fd, &fl);
 90	if (rc != 0) {
 91		ksft_print_msg
 92		    ("[FAIL] F_OFD_GETLK with F_UNLCK not supported\n");
 93		return -1;
 94	}
 95	if (fl.l_type != F_UNLCK) {
 96		ksft_print_msg
 97		    ("[SUCCESS] F_UNLCK test returns: locked, type %i pid %i len %zi\n",
 98		     fl.l_type, fl.l_pid, fl.l_len);
 99	} else {
100		ksft_print_msg
101		    ("[FAIL] F_OFD_GETLK with F_UNLCK did not return lock info\n");
102		return -1;
103	}
104	/* Try the same but by locking everything by len==0. */
105	fl2.l_type = F_UNLCK;
106	fl2.l_start = 0;
107	fl2.l_len = 0;
108	rc = lock_get(fd, &fl2);
109	if (rc != 0) {
110		ksft_print_msg
111		    ("[FAIL] F_OFD_GETLK with F_UNLCK not supported\n");
112		return -1;
113	}
114	if (memcmp(&fl, &fl2, sizeof(fl))) {
115		ksft_print_msg
116		    ("[FAIL] F_UNLCK test returns: locked, type %i pid %i len %zi\n",
117		     fl.l_type, fl.l_pid, fl.l_len);
118		return -1;
119	}
120	ksft_print_msg("[SUCCESS] F_UNLCK with len==0 returned the same\n");
121	/* Get info about the lock on second fd - no locks on it. */
122	fl.l_type = F_UNLCK;
123	fl.l_start = 0;
124	fl.l_len = 0;
125	lock_get(fd2, &fl);
126	if (fl.l_type != F_UNLCK) {
127		ksft_print_msg
128		    ("[FAIL] F_OFD_GETLK with F_UNLCK return lock info from another fd\n");
129		return -1;
130	}
131	return 0;
132}
~/ Read-only file preview.