// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#define __SANE_USERSPACE_TYPES__

#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <unistd.h>

#include "../kselftest_harness.h"

#include <linux/types.h>
#include <linux/mount.h>
#include <sys/syscall.h>

static inline int sys_fsopen(const char *fsname, unsigned int flags)
{
	return syscall(__NR_fsopen, fsname, flags);
}

static inline int sys_fsconfig(int fd, unsigned int cmd, const char *key,
			       const char *value, int aux)
{
	return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
}

static inline int sys_fsmount(int fd, unsigned int flags,
			      unsigned int attr_flags)
{
	return syscall(__NR_fsmount, fd, flags, attr_flags);
}

#ifndef MOVE_MOUNT_F_EMPTY_PATH
#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */
#endif

static inline int sys_move_mount(int from_dfd, const char *from_pathname,
				 int to_dfd, const char *to_pathname,
				 unsigned int flags)
{
	return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
		       to_pathname, flags);
}

FIXTURE(file_stressor) {
	int fd_tmpfs;
	int nr_procs;
	int max_fds;
	pid_t *pids_openers;
	pid_t *pids_getdents;
	int *fd_proc_pid;
};

FIXTURE_SETUP(file_stressor)
{
	int fd_context;

	ASSERT_EQ(unshare(CLONE_NEWNS), 0);
	ASSERT_EQ(mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
	ASSERT_EQ(mkdir("/slab_typesafe_by_rcu", 0755), 0);

	fd_context = sys_fsopen("tmpfs", 0);
	ASSERT_GE(fd_context, 0);

	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
	self->fd_tmpfs = sys_fsmount(fd_context, 0, 0);
	ASSERT_GE(self->fd_tmpfs, 0);
	ASSERT_EQ(close(fd_context), 0);

	ASSERT_EQ(sys_move_mount(self->fd_tmpfs, "", -EBADF, "/slab_typesafe_by_rcu", MOVE_MOUNT_F_EMPTY_PATH), 0);

	self->nr_procs = sysconf(_SC_NPROCESSORS_ONLN);
	self->pids_openers = malloc(sizeof(pid_t) * self->nr_procs);
	ASSERT_NE(self->pids_openers, NULL);
	self->pids_getdents = malloc(sizeof(pid_t) * self->nr_procs);
	ASSERT_NE(self->pids_getdents, NULL);
	self->fd_proc_pid = malloc(sizeof(int) * self->nr_procs);
	ASSERT_NE(self->fd_proc_pid, NULL);
	self->max_fds = 500;
}

FIXTURE_TEARDOWN(file_stressor)
{
	for (int i = 0; i < self->nr_procs; i++) {
		int wstatus;
		pid_t pid;

		pid = waitpid(self->pids_openers[i], &wstatus, 0);
		ASSERT_EQ(pid, self->pids_openers[i]);
		ASSERT_TRUE(!WIFEXITED(wstatus) || !WIFSIGNALED(wstatus));

		pid = waitpid(self->pids_getdents[i], &wstatus, 0);
		ASSERT_EQ(pid, self->pids_getdents[i]);
		ASSERT_TRUE(!WIFEXITED(wstatus) || !WIFSIGNALED(wstatus));
	}
	free(self->pids_openers);
	free(self->pids_getdents);
	ASSERT_EQ(close(self->fd_tmpfs), 0);

	umount2("/slab_typesafe_by_rcu", 0);
	ASSERT_EQ(rmdir("/slab_typesafe_by_rcu"), 0);
}

TEST_F_TIMEOUT(file_stressor, slab_typesafe_by_rcu, 900 * 2)
{
	for (int i = 0; i < self->nr_procs; i++) {
		pid_t pid_self;

		self->pids_openers[i] = fork();
		ASSERT_GE(self->pids_openers[i], 0);

		if (self->pids_openers[i] != 0)
			continue;

		self->pids_openers[i] = getpid();
		for (;;) {
			for (int i = 0; i < self->max_fds; i++) {
				char path[PATH_MAX];
				int fd;

				sprintf(path, "/slab_typesafe_by_rcu/file-%d-%d", self->pids_openers[i], i);
				fd = open(path, O_CREAT | O_RDONLY | O_CLOEXEC, 0644);
				if (fd < 0)
					continue;
			}

			close_range(3, ~0U, 0);
		}

		exit(0);
	}

	for (int i = 0; i < self->nr_procs; i++) {
		char path[PATH_MAX];

		sprintf(path, "/proc/%d/fd/", self->pids_openers[i]);
		self->fd_proc_pid[i] = open(path, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
		ASSERT_GE(self->fd_proc_pid[i], 0);
	}

	for (int i = 0; i < self->nr_procs; i++) {
		self->pids_getdents[i] = fork();
		ASSERT_GE(self->pids_getdents[i], 0);

		if (self->pids_getdents[i] != 0)
			continue;

		self->pids_getdents[i] = getpid();
		for (;;) {
			char ents[1024];
			ssize_t nr_read;

			/*
			 * Concurrently read /proc/<pid>/fd/ which rougly does:
			 *
			 * f = fget_task_next(p, &fd);
			 * if (!f)
			 *	break;
			 * data.mode = f->f_mode;
			 * fput(f);
			 *
			 * Which means that it'll try to get a reference to a
			 * file in another task's file descriptor table.
			 *
			 * Under heavy file load it is increasingly likely that
			 * the other task will manage to close @file and @file
			 * is being recycled due to SLAB_TYPEAFE_BY_RCU
			 * concurrently. This will trigger various warnings in
			 * the file reference counting code.
			 */
			do {
				nr_read = syscall(SYS_getdents64, self->fd_proc_pid[i], ents, sizeof(ents));
			} while (nr_read >= 0);

			lseek(self->fd_proc_pid[i], 0, SEEK_SET);
		}

		exit(0);
	}

	ASSERT_EQ(clock_nanosleep(CLOCK_MONOTONIC, 0, &(struct timespec){ .tv_sec = 900 /* 15 min */ }, NULL), 0);

	for (int i = 0; i < self->nr_procs; i++) {
		kill(self->pids_openers[i], SIGKILL);
		kill(self->pids_getdents[i], SIGKILL);
	}
}

TEST_HARNESS_MAIN
