2 * t_encrypted_d_revalidate
4 * Test that ->d_revalidate() for encrypted dentries doesn't oops the
5 * kernel by incorrectly not dropping out of RCU mode. To do this, try
6 * to look up a negative dentry while another thread deletes its parent
7 * directory. Fixed by commit 03a8bb0e53d9 ("ext4/fscrypto: avoid RCU
8 * lookup in d_revalidate").
10 * This doesn't always reproduce reliably, but we give it a few seconds.
12 * ----------------------------------------------------------------------------
14 * Copyright (c) 2017 Google, Inc. All Rights Reserved.
16 * Author: Eric Biggers <ebiggers@google.com>
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public Licence as published by
20 * the Free Software Foundation; either version 2 of the Licence, or (at
21 * your option) any later version.
23 * This program is distributed in the hope that it would be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, see <http://www.gnu.org/licenses/>.
42 #define DIR_NAME "dir"
43 #define FILE_NAME DIR_NAME "/file"
45 static volatile sig_atomic_t timed_out = 0;
47 static void alarm_handler(int sig)
52 static void __attribute__((noreturn))
53 die(int err, const char *msg)
55 fprintf(stderr, "ERROR: %s", msg);
57 fprintf(stderr, ": %s", strerror(err));
62 static void *stat_thread(void *_arg)
67 if (stat(FILE_NAME, &stbuf) == 0)
68 die(0, "stat should have failed");
74 int main(int argc, char *argv[])
77 long num_stat_threads;
82 fprintf(stderr, "Usage: %s DIR\n", argv[0]);
86 if (chdir(argv[1]) != 0)
89 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
91 num_stat_threads = ncpus - 1;
95 for (i = 0; i < num_stat_threads; i++) {
99 err = pthread_create(&thread, NULL, stat_thread, NULL);
101 die(err, "pthread_create");
104 if (signal(SIGALRM, alarm_handler) == SIG_ERR)
105 die(errno, "signal");
110 if (mkdir(DIR_NAME, 0777) != 0)
112 if (stat(FILE_NAME, &stbuf) == 0)
113 die(0, "stat should have failed");
116 if (rmdir(DIR_NAME) != 0)
120 printf("t_encrypted_d_revalidate finished\n");