fix RLIMIT_CORE accounting for sparse dumps
Subsystems (5)
v3 cover fix RLIMIT_CORE accounting for sparse dumps
From: Omar Sandoval <[email protected]>
Al, could you please apply this series for v4.7? I first sent it out during the v4.5 cycle, it'd be great to be done with it, especially since it's fixing a regression.
Here's the cover letter from v1:
http://www.spinics.net/lists/linux-fsdevel/msg94735.html
Omar Sandoval (2):
coredump: get rid of coredump_params->written
coredump: only charge written data against RLIMIT_CORE
arch/powerpc/platforms/cell/spufs/coredump.c | 5 +++-- fs/binfmt_elf.c | 2 +- fs/binfmt_elf_fdpic.c | 2 +- fs/coredump.c | 5 +---- 4 files changed, 6 insertions(+), 8 deletions(-)
Signature · 1 line
2.8.2
PATCH RESEND v3 1/2 coredump: get rid of coredump_params->written
From: Omar Sandoval <[email protected]>
cprm->written is redundant with cprm->file->f_pos, so use that instead.
--- arch/powerpc/platforms/cell/spufs/coredump.c | 5 +++-- fs/binfmt_elf.c | 2 +- fs/binfmt_elf_fdpic.c | 2 +- fs/coredump.c | 8 +++----- include/linux/binfmts.h | 1 - 5 files changed, 8 insertions(+), 10 deletions(-)
arch/powerpc/platforms/cell/spufs/coredump.c +3 -2
@@ -137,6 +137,7 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i,char *name;char fullname[80 ], *buf;struct elf_note en; +size_t skip; buf = (void *)get_zeroed_page (GFP_KERNEL );if (!buf)
@@ -171,8 +172,8 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i,if (rc <0 ) goto out; -if (!dump_skip (cprm, -roundup (cprm->written - total + sz,4 ) - cprm->written)) + skip =roundup (cprm->file->f_pos - total + sz,4 ) - cprm->file->f_pos; +if (!dump_skip (cprm, skip)) goto Eio; out:free_page ((unsigned long )buf);
fs/binfmt_elf.c +1 -1
@@ -2273,7 +2273,7 @@ static int elf_core_dump(struct coredump_params *cprm) goto end_coredump;/* Align to page */ -if (!dump_skip (cprm, dataoff - cprm->written)) +if (!dump_skip (cprm, dataoff - cprm->file->f_pos)) goto end_coredump; for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
fs/binfmt_elf_fdpic.c +1 -1
@@ -1787,7 +1787,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) goto end_coredump; } -if (!dump_skip (cprm, dataoff - cprm->written)) +if (!dump_skip (cprm, dataoff - cprm->file->f_pos)) goto end_coredump;if (!elf_fdpic_dump_segments (cprm))
fs/coredump.c +3 -5
@@ -782,7 +782,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)struct file *file = cprm->file;loff_t pos = file->f_pos;ssize_t n; -if (cprm->written + nr > cprm->limit) +if (pos + nr > cprm->limit)return 0 ;while (nr) {if (dump_interrupted ())
@@ -791,7 +791,6 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)if (n <=0 )return 0 ; file->f_pos = pos; - cprm->written += n; nr -= n; }return 1 ;
@@ -803,12 +802,11 @@ int dump_skip(struct coredump_params *cprm, size_t nr)static char zeroes[PAGE_SIZE ];struct file *file = cprm->file;if (file->f_op->llseek && file->f_op->llseek != no_llseek) { -if (cprm->written + nr > cprm->limit) +if (file->f_pos + nr > cprm->limit)return 0 ;if (dump_interrupted () || file->f_op->llseek (file, nr,SEEK_CUR ) <0 )return 0 ; - cprm->written += nr;return 1 ; }else {while (nr >PAGE_SIZE ) {
@@ -823,7 +821,7 @@ EXPORT_SYMBOL(dump_skip);int dump_align (struct coredump_params *cprm,int align) { -unsigned mod = cprm->written & (align -1 ); +unsigned mod = cprm->file->f_pos & (align -1 );if (align & (align -1 ))return 0 ;return mod ?dump_skip (cprm, align - mod) :1 ;
include/linux/binfmts.h +0 -1
@@ -64,7 +64,6 @@ struct coredump_params {struct file *file;unsigned long limit;unsigned long mm_flags; -loff_t written; };/*
Signature · 1 line
2.8.2
PATCH RESEND v3 2/2 coredump: only charge written data against RLIMIT_CORE
In reply to Omar SandovalFrom: Omar Sandoval <[email protected]>
Commit 9b56d54380ad ("dump_skip(): dump_seek() replacement taking coredump_params") introduced a regression with regard to RLIMIT_CORE. Previously, when a core dump was sparse, only the data that was actually written out would count against the limit. Now, the sparse ranges are also included, which leads to truncated core dumps when the actual disk usage is still well below the limit. Restore the old behavior by only counting what gets emitted and ignoring what gets skipped.
--- fs/coredump.c | 5 ++--- include/linux/binfmts.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-)
fs/coredump.c +2 -3
@@ -782,7 +782,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)struct file *file = cprm->file;loff_t pos = file->f_pos;ssize_t n; -if (pos + nr > cprm->limit) +if (cprm->written + nr > cprm->limit)return 0 ;while (nr) {if (dump_interrupted ())
@@ -791,6 +791,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr)if (n <=0 )return 0 ; file->f_pos = pos; + cprm->written += n; nr -= n; }return 1 ;
@@ -802,8 +803,6 @@ int dump_skip(struct coredump_params *cprm, size_t nr)static char zeroes[PAGE_SIZE ];struct file *file = cprm->file;if (file->f_op->llseek && file->f_op->llseek != no_llseek) { -if (file->f_pos + nr > cprm->limit) -return 0 ;if (dump_interrupted () || file->f_op->llseek (file, nr,SEEK_CUR ) <0 )return 0 ;
include/linux/binfmts.h +1 -0
@@ -64,6 +64,7 @@ struct coredump_params {struct file *file;unsigned long limit;unsigned long mm_flags; +loff_t written; };/*
Signature · 1 line
2.8.2
Quoted 5 lines · Omar Sandoval
From: Omar Sandoval <[email protected]>
Al, could you please apply this series for v4.7? I first sent it out during the v4.5 cycle, it'd be great to be done with it, especially since it's fixing a regression.
Applied.