brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · a55b798 Raw
133 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#define _GNU_SOURCE4#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 locks16	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 locks28	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_msg54		    ("[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_msg79		    ("[SUCCESS] read and write locks conflicted\n");80	} else {81		ksft_print_msg82		    ("[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_msg92		    ("[FAIL] F_OFD_GETLK with F_UNLCK not supported\n");93		return -1;94	}95	if (fl.l_type != F_UNLCK) {96		ksft_print_msg97		    ("[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_msg101		    ("[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_msg111		    ("[FAIL] F_OFD_GETLK with F_UNLCK not supported\n");112		return -1;113	}114	if (memcmp(&fl, &fl2, sizeof(fl))) {115		ksft_print_msg116		    ("[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_msg128		    ("[FAIL] F_OFD_GETLK with F_UNLCK return lock info from another fd\n");129		return -1;130	}131	return 0;132}133