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:
Linus Torvalds 2022-08-07 10:03:24 -07:00
commit eb5699ba31
102 changed files with 1313 additions and 724 deletions

View file

@ -17,6 +17,7 @@ TARGETS += exec
TARGETS += filesystems
TARGETS += filesystems/binderfs
TARGETS += filesystems/epoll
TARGETS += filesystems/fat
TARGETS += firmware
TARGETS += fpu
TARGETS += ftrace

View file

@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
rename_exchange

View 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

View file

@ -0,0 +1,2 @@
CONFIG_BLK_DEV_LOOP=y
CONFIG_VFAT_FS=y

View 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);
}

View 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

View file

@ -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)));
}
}