Updates to various subsystems which I help look after. lib, ocfs2,
fatfs, autofs, squashfs, procfs, etc. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCYu9BeQAKCRDdBJ7gKXxA jp1DAP4mjCSvAwYzXklrIt+Knv3CEY5oVVdS+pWOAOGiJpldTAD9E5/0NV+VmlD9 kwS/13j38guulSlXRzDLmitbg81zAAI= =Zfum -----END PGP SIGNATURE----- Merge tag 'mm-nonmm-stable-2022-08-06-2' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull misc updates from Andrew Morton: "Updates to various subsystems which I help look after. lib, ocfs2, fatfs, autofs, squashfs, procfs, etc. A relatively small amount of material this time" * tag 'mm-nonmm-stable-2022-08-06-2' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (72 commits) scripts/gdb: ensure the absolute path is generated on initial source MAINTAINERS: kunit: add David Gow as a maintainer of KUnit mailmap: add linux.dev alias for Brendan Higgins mailmap: update Kirill's email profile: setup_profiling_timer() is moslty not implemented ocfs2: fix a typo in a comment ocfs2: use the bitmap API to simplify code ocfs2: remove some useless functions lib/mpi: fix typo 'the the' in comment proc: add some (hopefully) insightful comments bdi: remove enum wb_congested_state kernel/hung_task: fix address space of proc_dohung_task_timeout_secs lib/lzo/lzo1x_compress.c: replace ternary operator with min() and min_t() squashfs: support reading fragments in readahead call squashfs: implement readahead squashfs: always build "file direct" version of page actor Revert "squashfs: provide backing_dev_info in order to disable read-ahead" fs/ocfs2: Fix spelling typo in comment ia64: old_rr4 added under CONFIG_HUGETLB_PAGE proc: fix test for "vsyscall=xonly" boot option ...
This commit is contained in:
commit
eb5699ba31
102 changed files with 1313 additions and 724 deletions
|
|
@ -17,6 +17,7 @@ TARGETS += exec
|
|||
TARGETS += filesystems
|
||||
TARGETS += filesystems/binderfs
|
||||
TARGETS += filesystems/epoll
|
||||
TARGETS += filesystems/fat
|
||||
TARGETS += firmware
|
||||
TARGETS += fpu
|
||||
TARGETS += ftrace
|
||||
|
|
|
|||
2
tools/testing/selftests/filesystems/fat/.gitignore
vendored
Normal file
2
tools/testing/selftests/filesystems/fat/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
rename_exchange
|
||||
7
tools/testing/selftests/filesystems/fat/Makefile
Normal file
7
tools/testing/selftests/filesystems/fat/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
TEST_PROGS := run_fat_tests.sh
|
||||
TEST_GEN_PROGS_EXTENDED := rename_exchange
|
||||
CFLAGS += -O2 -g -Wall $(KHDR_INCLUDES)
|
||||
|
||||
include ../../lib.mk
|
||||
2
tools/testing/selftests/filesystems/fat/config
Normal file
2
tools/testing/selftests/filesystems/fat/config
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_VFAT_FS=y
|
||||
37
tools/testing/selftests/filesystems/fat/rename_exchange.c
Normal file
37
tools/testing/selftests/filesystems/fat/rename_exchange.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Program that atomically exchanges two paths using
|
||||
* the renameat2() system call RENAME_EXCHANGE flag.
|
||||
*
|
||||
* Copyright 2022 Red Hat Inc.
|
||||
* Author: Javier Martinez Canillas <javierm@redhat.com>
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void print_usage(const char *program)
|
||||
{
|
||||
printf("Usage: %s [oldpath] [newpath]\n", program);
|
||||
printf("Atomically exchange oldpath and newpath\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (argc != 3) {
|
||||
print_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = renameat2(AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE);
|
||||
if (ret) {
|
||||
perror("rename exchange failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
82
tools/testing/selftests/filesystems/fat/run_fat_tests.sh
Normal file
82
tools/testing/selftests/filesystems/fat/run_fat_tests.sh
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Run filesystem operations tests on an 1 MiB disk image that is formatted with
|
||||
# a vfat filesystem and mounted in a temporary directory using a loop device.
|
||||
#
|
||||
# Copyright 2022 Red Hat Inc.
|
||||
# Author: Javier Martinez Canillas <javierm@redhat.com>
|
||||
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
BASE_DIR="$(dirname $0)"
|
||||
TMP_DIR="$(mktemp -d /tmp/fat_tests_tmp.XXXX)"
|
||||
IMG_PATH="${TMP_DIR}/fat.img"
|
||||
MNT_PATH="${TMP_DIR}/mnt"
|
||||
|
||||
cleanup()
|
||||
{
|
||||
mountpoint -q "${MNT_PATH}" && unmount_image
|
||||
rm -rf "${TMP_DIR}"
|
||||
}
|
||||
trap cleanup SIGINT SIGTERM EXIT
|
||||
|
||||
create_loopback()
|
||||
{
|
||||
touch "${IMG_PATH}"
|
||||
chattr +C "${IMG_PATH}" >/dev/null 2>&1 || true
|
||||
|
||||
truncate -s 1M "${IMG_PATH}"
|
||||
mkfs.vfat "${IMG_PATH}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
mount_image()
|
||||
{
|
||||
mkdir -p "${MNT_PATH}"
|
||||
sudo mount -o loop "${IMG_PATH}" "${MNT_PATH}"
|
||||
}
|
||||
|
||||
rename_exchange_test()
|
||||
{
|
||||
local rename_exchange="${BASE_DIR}/rename_exchange"
|
||||
local old_path="${MNT_PATH}/old_file"
|
||||
local new_path="${MNT_PATH}/new_file"
|
||||
|
||||
echo old | sudo tee "${old_path}" >/dev/null 2>&1
|
||||
echo new | sudo tee "${new_path}" >/dev/null 2>&1
|
||||
sudo "${rename_exchange}" "${old_path}" "${new_path}" >/dev/null 2>&1
|
||||
sudo sync -f "${MNT_PATH}"
|
||||
grep new "${old_path}" >/dev/null 2>&1
|
||||
grep old "${new_path}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
rename_exchange_subdir_test()
|
||||
{
|
||||
local rename_exchange="${BASE_DIR}/rename_exchange"
|
||||
local dir_path="${MNT_PATH}/subdir"
|
||||
local old_path="${MNT_PATH}/old_file"
|
||||
local new_path="${dir_path}/new_file"
|
||||
|
||||
sudo mkdir -p "${dir_path}"
|
||||
echo old | sudo tee "${old_path}" >/dev/null 2>&1
|
||||
echo new | sudo tee "${new_path}" >/dev/null 2>&1
|
||||
sudo "${rename_exchange}" "${old_path}" "${new_path}" >/dev/null 2>&1
|
||||
sudo sync -f "${MNT_PATH}"
|
||||
grep new "${old_path}" >/dev/null 2>&1
|
||||
grep old "${new_path}" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
unmount_image()
|
||||
{
|
||||
sudo umount "${MNT_PATH}" &> /dev/null
|
||||
}
|
||||
|
||||
create_loopback
|
||||
mount_image
|
||||
rename_exchange_test
|
||||
rename_exchange_subdir_test
|
||||
unmount_image
|
||||
|
||||
exit 0
|
||||
|
|
@ -211,10 +211,19 @@ static int make_exe(const uint8_t *payload, size_t len)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool g_vsyscall = false;
|
||||
/*
|
||||
* 0: vsyscall VMA doesn't exist vsyscall=none
|
||||
* 1: vsyscall VMA is r-xp vsyscall=emulate
|
||||
* 2: vsyscall VMA is --xp vsyscall=xonly
|
||||
*/
|
||||
static int g_vsyscall;
|
||||
static const char *str_vsyscall;
|
||||
|
||||
static const char str_vsyscall[] =
|
||||
static const char str_vsyscall_0[] = "";
|
||||
static const char str_vsyscall_1[] =
|
||||
"ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n";
|
||||
static const char str_vsyscall_2[] =
|
||||
"ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]\n";
|
||||
|
||||
#ifdef __x86_64__
|
||||
static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___)
|
||||
|
|
@ -223,13 +232,47 @@ static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___)
|
|||
}
|
||||
|
||||
/*
|
||||
* vsyscall page can't be unmapped, probe it with memory load.
|
||||
* vsyscall page can't be unmapped, probe it directly.
|
||||
*/
|
||||
static void vsyscall(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int wstatus;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "fork, errno %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
if (pid == 0) {
|
||||
struct rlimit rlim = {0, 0};
|
||||
(void)setrlimit(RLIMIT_CORE, &rlim);
|
||||
|
||||
/* Hide "segfault at ffffffffff600000" messages. */
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(struct sigaction));
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
act.sa_sigaction = sigaction_SIGSEGV;
|
||||
(void)sigaction(SIGSEGV, &act, NULL);
|
||||
|
||||
/* gettimeofday(NULL, NULL); */
|
||||
asm volatile (
|
||||
"call %P0"
|
||||
:
|
||||
: "i" (0xffffffffff600000), "D" (NULL), "S" (NULL)
|
||||
: "rax", "rcx", "r11"
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
waitpid(pid, &wstatus, 0);
|
||||
if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) {
|
||||
/* vsyscall page exists and is executable. */
|
||||
} else {
|
||||
/* vsyscall page doesn't exist. */
|
||||
g_vsyscall = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "fork, errno %d\n", errno);
|
||||
|
|
@ -251,8 +294,13 @@ static void vsyscall(void)
|
|||
}
|
||||
waitpid(pid, &wstatus, 0);
|
||||
if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) {
|
||||
g_vsyscall = true;
|
||||
/* vsyscall page is readable and executable. */
|
||||
g_vsyscall = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* vsyscall page is executable but unreadable. */
|
||||
g_vsyscall = 2;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
|
@ -261,6 +309,19 @@ int main(void)
|
|||
int exec_fd;
|
||||
|
||||
vsyscall();
|
||||
switch (g_vsyscall) {
|
||||
case 0:
|
||||
str_vsyscall = str_vsyscall_0;
|
||||
break;
|
||||
case 1:
|
||||
str_vsyscall = str_vsyscall_1;
|
||||
break;
|
||||
case 2:
|
||||
str_vsyscall = str_vsyscall_2;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
atexit(ate);
|
||||
|
||||
|
|
@ -314,7 +375,7 @@ int main(void)
|
|||
|
||||
/* Test /proc/$PID/maps */
|
||||
{
|
||||
const size_t len = strlen(buf0) + (g_vsyscall ? strlen(str_vsyscall) : 0);
|
||||
const size_t len = strlen(buf0) + strlen(str_vsyscall);
|
||||
char buf[256];
|
||||
ssize_t rv;
|
||||
int fd;
|
||||
|
|
@ -327,7 +388,7 @@ int main(void)
|
|||
rv = read(fd, buf, sizeof(buf));
|
||||
assert(rv == len);
|
||||
assert(memcmp(buf, buf0, strlen(buf0)) == 0);
|
||||
if (g_vsyscall) {
|
||||
if (g_vsyscall > 0) {
|
||||
assert(memcmp(buf + strlen(buf0), str_vsyscall, strlen(str_vsyscall)) == 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -374,7 +435,7 @@ int main(void)
|
|||
assert(memmem(buf, rv, S[i], strlen(S[i])));
|
||||
}
|
||||
|
||||
if (g_vsyscall) {
|
||||
if (g_vsyscall > 0) {
|
||||
assert(memmem(buf, rv, str_vsyscall, strlen(str_vsyscall)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue