1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2017 Google, Inc. All Rights Reserved.
4 * Author: Eric Biggers <ebiggers@google.com>
6 * t_encrypted_d_revalidate
8 * Test that ->d_revalidate() for encrypted dentries doesn't oops the
9 * kernel by incorrectly not dropping out of RCU mode. To do this, try
10 * to look up a negative dentry while another thread deletes its parent
11 * directory. Fixed by commit 03a8bb0e53d9 ("ext4/fscrypto: avoid RCU
12 * lookup in d_revalidate").
14 * This doesn't always reproduce reliably, but we give it a few seconds.
27 #define DIR_NAME "dir"
28 #define FILE_NAME DIR_NAME "/file"
30 static volatile sig_atomic_t timed_out = 0;
32 static void alarm_handler(int sig)
37 static void __attribute__((noreturn))
38 die(int err, const char *msg)
40 fprintf(stderr, "ERROR: %s", msg);
42 fprintf(stderr, ": %s", strerror(err));
47 static void *stat_thread(void *_arg)
52 if (stat(FILE_NAME, &stbuf) == 0)
53 die(0, "stat should have failed");
59 int main(int argc, char *argv[])
62 long num_stat_threads;
67 fprintf(stderr, "Usage: %s DIR\n", argv[0]);
71 if (chdir(argv[1]) != 0)
74 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
76 num_stat_threads = ncpus - 1;
80 for (i = 0; i < num_stat_threads; i++) {
84 err = pthread_create(&thread, NULL, stat_thread, NULL);
86 die(err, "pthread_create");
89 if (signal(SIGALRM, alarm_handler) == SIG_ERR)
95 if (mkdir(DIR_NAME, 0777) != 0)
97 if (stat(FILE_NAME, &stbuf) == 0)
98 die(0, "stat should have failed");
101 if (rmdir(DIR_NAME) != 0)
105 printf("t_encrypted_d_revalidate finished\n");