Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

switch elf_coredump_extra_notes_write() to dump_emit()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro cdc3d562 e6c1baa9

+30 -38
+2 -1
arch/powerpc/include/asm/spu.h
··· 235 235 236 236 /* syscalls implemented in spufs */ 237 237 struct file; 238 + struct coredump_params; 238 239 struct spufs_calls { 239 240 long (*create_thread)(const char __user *name, 240 241 unsigned int flags, umode_t mode, ··· 243 242 long (*spu_run)(struct file *filp, __u32 __user *unpc, 244 243 __u32 __user *ustatus); 245 244 int (*coredump_extra_notes_size)(void); 246 - int (*coredump_extra_notes_write)(struct file *file, loff_t *foffset); 245 + int (*coredump_extra_notes_write)(struct coredump_params *cprm); 247 246 void (*notify_spus_active)(void); 248 247 struct module *owner; 249 248 };
+3 -2
arch/powerpc/platforms/cell/spu_syscalls.c
··· 25 25 #include <linux/module.h> 26 26 #include <linux/syscalls.h> 27 27 #include <linux/rcupdate.h> 28 + #include <linux/binfmts.h> 28 29 29 30 #include <asm/spu.h> 30 31 ··· 127 126 return ret; 128 127 } 129 128 130 - int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset) 129 + int elf_coredump_extra_notes_write(struct coredump_params *cprm) 131 130 { 132 131 struct spufs_calls *calls; 133 132 int ret; ··· 136 135 if (!calls) 137 136 return 0; 138 137 139 - ret = calls->coredump_extra_notes_write(file, foffset); 138 + ret = calls->coredump_extra_notes_write(cprm); 140 139 141 140 spufs_calls_put(calls); 142 141
+17 -27
arch/powerpc/platforms/cell/spufs/coredump.c
··· 27 27 #include <linux/gfp.h> 28 28 #include <linux/list.h> 29 29 #include <linux/syscalls.h> 30 + #include <linux/coredump.h> 31 + #include <linux/binfmts.h> 30 32 31 33 #include <asm/uaccess.h> 32 34 ··· 54 52 * These are the only things you should do on a core-file: use only these 55 53 * functions to write out all the necessary info. 56 54 */ 57 - static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset) 55 + static int spufs_dump_write(struct coredump_params *cprm, const void *addr, int nr) 58 56 { 59 - unsigned long limit = rlimit(RLIMIT_CORE); 60 - ssize_t written; 61 - 62 - if (*foffset + nr > limit) 57 + if (!dump_emit(cprm, addr, nr)) 63 58 return -EIO; 64 - 65 - written = file->f_op->write(file, addr, nr, &file->f_pos); 66 - *foffset += written; 67 - 68 - if (written != nr) 69 - return -EIO; 70 - 71 59 return 0; 72 60 } 73 61 74 - static int spufs_dump_align(struct file *file, char *buf, loff_t new_off, 75 - loff_t *foffset) 62 + static int spufs_dump_align(struct coredump_params *cprm, char *buf, loff_t new_off) 76 63 { 77 64 int rc, size; 78 65 79 - size = min((loff_t)PAGE_SIZE, new_off - *foffset); 66 + size = min((loff_t)PAGE_SIZE, new_off - cprm->written); 80 67 memset(buf, 0, size); 81 68 82 69 rc = 0; 83 - while (rc == 0 && new_off > *foffset) { 84 - size = min((loff_t)PAGE_SIZE, new_off - *foffset); 85 - rc = spufs_dump_write(file, buf, size, foffset); 70 + while (rc == 0 && new_off > cprm->written) { 71 + size = min((loff_t)PAGE_SIZE, new_off - cprm->written); 72 + rc = spufs_dump_write(cprm, buf, size); 86 73 } 87 74 88 75 return rc; ··· 156 165 } 157 166 158 167 static int spufs_arch_write_note(struct spu_context *ctx, int i, 159 - struct file *file, int dfd, loff_t *foffset) 168 + struct coredump_params *cprm, int dfd) 160 169 { 161 170 loff_t pos = 0; 162 171 int sz, rc, nread, total = 0; ··· 177 186 en.n_descsz = sz; 178 187 en.n_type = NT_SPU; 179 188 180 - rc = spufs_dump_write(file, &en, sizeof(en), foffset); 189 + rc = spufs_dump_write(cprm, &en, sizeof(en)); 181 190 if (rc) 182 191 goto out; 183 192 184 - rc = spufs_dump_write(file, fullname, en.n_namesz, foffset); 193 + rc = spufs_dump_write(cprm, fullname, en.n_namesz); 185 194 if (rc) 186 195 goto out; 187 196 188 - rc = spufs_dump_align(file, buf, roundup(*foffset, 4), foffset); 197 + rc = spufs_dump_align(cprm, buf, roundup(cprm->written, 4)); 189 198 if (rc) 190 199 goto out; 191 200 192 201 do { 193 202 nread = do_coredump_read(i, ctx, buf, bufsz, &pos); 194 203 if (nread > 0) { 195 - rc = spufs_dump_write(file, buf, nread, foffset); 204 + rc = spufs_dump_write(cprm, buf, nread); 196 205 if (rc) 197 206 goto out; 198 207 total += nread; ··· 204 213 goto out; 205 214 } 206 215 207 - rc = spufs_dump_align(file, buf, roundup(*foffset - total + sz, 4), 208 - foffset); 216 + rc = spufs_dump_align(cprm, buf, roundup(cprm->written - total + sz, 4)); 209 217 210 218 out: 211 219 free_page((unsigned long)buf); 212 220 return rc; 213 221 } 214 222 215 - int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset) 223 + int spufs_coredump_extra_notes_write(struct coredump_params *cprm) 216 224 { 217 225 struct spu_context *ctx; 218 226 int fd, j, rc; ··· 223 233 return rc; 224 234 225 235 for (j = 0; spufs_coredump_read[j].name != NULL; j++) { 226 - rc = spufs_arch_write_note(ctx, j, file, fd, foffset); 236 + rc = spufs_arch_write_note(ctx, j, cprm, fd); 227 237 if (rc) { 228 238 spu_release_saved(ctx); 229 239 return rc;
+2 -1
arch/powerpc/platforms/cell/spufs/spufs.h
··· 247 247 248 248 /* system call implementation */ 249 249 extern struct spufs_calls spufs_calls; 250 + struct coredump_params; 250 251 long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); 251 252 long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, 252 253 umode_t mode, struct file *filp); 253 254 /* ELF coredump callbacks for writing SPU ELF notes */ 254 255 extern int spufs_coredump_extra_notes_size(void); 255 - extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset); 256 + extern int spufs_coredump_extra_notes_write(struct coredump_params *cprm); 256 257 257 258 extern const struct file_operations spufs_context_fops; 258 259
+3 -4
fs/binfmt_elf.c
··· 2037 2037 size_t size = 0; 2038 2038 struct vm_area_struct *vma, *gate_vma; 2039 2039 struct elfhdr *elf = NULL; 2040 - loff_t offset = 0, dataoff, foffset; 2040 + loff_t offset = 0, dataoff; 2041 2041 struct elf_note_info info = { }; 2042 2042 struct elf_phdr *phdr4note = NULL; 2043 2043 struct elf_shdr *shdr4extnum = NULL; ··· 2160 2160 if (!write_note_info(&info, cprm)) 2161 2161 goto end_coredump; 2162 2162 2163 - foffset = cprm->written; 2164 - if (elf_coredump_extra_notes_write(cprm->file, &foffset)) 2163 + if (elf_coredump_extra_notes_write(cprm)) 2165 2164 goto end_coredump; 2166 2165 2167 2166 /* Align to page */ 2168 - if (!dump_seek(cprm->file, dataoff - foffset)) 2167 + if (!dump_seek(cprm->file, dataoff - cprm->written)) 2169 2168 goto end_coredump; 2170 2169 2171 2170 cprm->written = size;
+3 -3
include/linux/elf.h
··· 39 39 40 40 /* Optional callbacks to write extra ELF notes. */ 41 41 struct file; 42 + struct coredump_params; 42 43 43 44 #ifndef ARCH_HAVE_EXTRA_ELF_NOTES 44 45 static inline int elf_coredump_extra_notes_size(void) { return 0; } 45 - static inline int elf_coredump_extra_notes_write(struct file *file, 46 - loff_t *foffset) { return 0; } 46 + static inline int elf_coredump_extra_notes_write(struct coredump_params *cprm) { return 0; } 47 47 #else 48 48 extern int elf_coredump_extra_notes_size(void); 49 - extern int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset); 49 + extern int elf_coredump_extra_notes_write(struct coredump_params *cprm); 50 50 #endif 51 51 #endif /* _LINUX_ELF_H */