Skip to content

Commit a961c73

Browse files
committed
coredump: prepare to simplify exit paths
The exit path is currently entangled with core pipe limit accounting which is really unpleasant. Use a local variable in struct core_name that remembers whether the count was incremented and if so to clean decrement in once the coredump is done. Assert that this only happens for pipes. Link: https://lore.kernel.org/20250612-work-coredump-massage-v1-11-315c0c34ba94@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 7bbb05d commit a961c73

1 file changed

Lines changed: 10 additions & 8 deletions

File tree

fs/coredump.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ enum coredump_type_t {
9393
struct core_name {
9494
char *corename;
9595
int used, size;
96+
unsigned int core_pipe_limit;
9697
enum coredump_type_t core_type;
9798
u64 mask;
9899
};
@@ -244,6 +245,7 @@ static bool coredump_parse(struct core_name *cn, struct coredump_params *cprm,
244245
cn->mask |= COREDUMP_WAIT;
245246
cn->used = 0;
246247
cn->corename = NULL;
248+
cn->core_pipe_limit = 0;
247249
if (*pat_ptr == '|')
248250
cn->core_type = COREDUMP_PIPE;
249251
else if (*pat_ptr == '@')
@@ -1031,7 +1033,6 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
10311033
break;
10321034
case COREDUMP_PIPE: {
10331035
int argi;
1034-
int dump_count;
10351036
char **helper_argv;
10361037
struct subprocess_info *sub_info;
10371038

@@ -1052,21 +1053,21 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
10521053
* core_pattern process dies.
10531054
*/
10541055
coredump_report_failure("RLIMIT_CORE is set to 1, aborting core");
1055-
goto fail_unlock;
1056+
goto close_fail;
10561057
}
10571058
cprm.limit = RLIM_INFINITY;
10581059

1059-
dump_count = atomic_inc_return(&core_dump_count);
1060-
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
1060+
cn.core_pipe_limit = atomic_inc_return(&core_dump_count);
1061+
if (core_pipe_limit && (core_pipe_limit < cn.core_pipe_limit)) {
10611062
coredump_report_failure("over core_pipe_limit, skipping core dump");
1062-
goto fail_dropcount;
1063+
goto close_fail;
10631064
}
10641065

10651066
helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv),
10661067
GFP_KERNEL);
10671068
if (!helper_argv) {
10681069
coredump_report_failure("%s failed to allocate memory", __func__);
1069-
goto fail_dropcount;
1070+
goto close_fail;
10701071
}
10711072
for (argi = 0; argi < argc; argi++)
10721073
helper_argv[argi] = cn.corename + argv[argi];
@@ -1168,9 +1169,10 @@ void vfs_coredump(const kernel_siginfo_t *siginfo)
11681169
close_fail:
11691170
if (cprm.file)
11701171
filp_close(cprm.file, NULL);
1171-
fail_dropcount:
1172-
if (cn.core_type == COREDUMP_PIPE)
1172+
if (cn.core_pipe_limit) {
1173+
VFS_WARN_ON_ONCE(cn.core_type != COREDUMP_PIPE);
11731174
atomic_dec(&core_dump_count);
1175+
}
11741176
fail_unlock:
11751177
kfree(argv);
11761178
kfree(cn.corename);

0 commit comments

Comments
 (0)