Path: blob/master/tools/testing/selftests/filelock/ofdlocks.c
26285 views
// SPDX-License-Identifier: GPL-2.012#define _GNU_SOURCE3#include <fcntl.h>4#include <assert.h>5#include <stdio.h>6#include <unistd.h>7#include <string.h>8#include "../kselftest.h"910static int lock_set(int fd, struct flock *fl)11{12int ret;1314fl->l_pid = 0; // needed for OFD locks15fl->l_whence = SEEK_SET;16ret = fcntl(fd, F_OFD_SETLK, fl);17if (ret)18perror("fcntl()");19return ret;20}2122static int lock_get(int fd, struct flock *fl)23{24int ret;2526fl->l_pid = 0; // needed for OFD locks27fl->l_whence = SEEK_SET;28ret = fcntl(fd, F_OFD_GETLK, fl);29if (ret)30perror("fcntl()");31return ret;32}3334int main(void)35{36int rc;37struct flock fl, fl2;38int fd = open("/tmp/aa", O_RDWR | O_CREAT | O_EXCL, 0600);39int fd2 = open("/tmp/aa", O_RDONLY);4041unlink("/tmp/aa");42assert(fd != -1);43assert(fd2 != -1);44ksft_print_msg("[INFO] opened fds %i %i\n", fd, fd2);4546/* Set some read lock */47fl.l_type = F_RDLCK;48fl.l_start = 5;49fl.l_len = 3;50rc = lock_set(fd, &fl);51if (rc == 0) {52ksft_print_msg53("[SUCCESS] set OFD read lock on first fd\n");54} else {55ksft_print_msg("[FAIL] to set OFD read lock on first fd\n");56return -1;57}58/* Make sure read locks do not conflict on different fds. */59fl.l_type = F_RDLCK;60fl.l_start = 5;61fl.l_len = 1;62rc = lock_get(fd2, &fl);63if (rc != 0)64return -1;65if (fl.l_type != F_UNLCK) {66ksft_print_msg("[FAIL] read locks conflicted\n");67return -1;68}69/* Make sure read/write locks do conflict on different fds. */70fl.l_type = F_WRLCK;71fl.l_start = 5;72fl.l_len = 1;73rc = lock_get(fd2, &fl);74if (rc != 0)75return -1;76if (fl.l_type != F_UNLCK) {77ksft_print_msg78("[SUCCESS] read and write locks conflicted\n");79} else {80ksft_print_msg81("[SUCCESS] read and write locks not conflicted\n");82return -1;83}84/* Get info about the lock on first fd. */85fl.l_type = F_UNLCK;86fl.l_start = 5;87fl.l_len = 1;88rc = lock_get(fd, &fl);89if (rc != 0) {90ksft_print_msg91("[FAIL] F_OFD_GETLK with F_UNLCK not supported\n");92return -1;93}94if (fl.l_type != F_UNLCK) {95ksft_print_msg96("[SUCCESS] F_UNLCK test returns: locked, type %i pid %i len %zi\n",97fl.l_type, fl.l_pid, fl.l_len);98} else {99ksft_print_msg100("[FAIL] F_OFD_GETLK with F_UNLCK did not return lock info\n");101return -1;102}103/* Try the same but by locking everything by len==0. */104fl2.l_type = F_UNLCK;105fl2.l_start = 0;106fl2.l_len = 0;107rc = lock_get(fd, &fl2);108if (rc != 0) {109ksft_print_msg110("[FAIL] F_OFD_GETLK with F_UNLCK not supported\n");111return -1;112}113if (memcmp(&fl, &fl2, sizeof(fl))) {114ksft_print_msg115("[FAIL] F_UNLCK test returns: locked, type %i pid %i len %zi\n",116fl.l_type, fl.l_pid, fl.l_len);117return -1;118}119ksft_print_msg("[SUCCESS] F_UNLCK with len==0 returned the same\n");120/* Get info about the lock on second fd - no locks on it. */121fl.l_type = F_UNLCK;122fl.l_start = 0;123fl.l_len = 0;124lock_get(fd2, &fl);125if (fl.l_type != F_UNLCK) {126ksft_print_msg127("[FAIL] F_OFD_GETLK with F_UNLCK return lock info from another fd\n");128return -1;129}130return 0;131}132133134