Loading fs/seq_file.c +21 −9 Original line number Diff line number Diff line Loading @@ -8,8 +8,10 @@ #include <linux/fs.h> #include <linux/export.h> #include <linux/seq_file.h> #include <linux/vmalloc.h> #include <linux/slab.h> #include <linux/cred.h> #include <linux/mm.h> #include <asm/uaccess.h> #include <asm/page.h> Loading @@ -30,6 +32,16 @@ static void seq_set_overflow(struct seq_file *m) m->count = m->size; } static void *seq_buf_alloc(unsigned long size) { void *buf; buf = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); if (!buf && size > PAGE_SIZE) buf = vmalloc(size); return buf; } /** * seq_open - initialize sequential file * @file: file we initialize Loading Loading @@ -96,7 +108,7 @@ static int traverse(struct seq_file *m, loff_t offset) return 0; } if (!m->buf) { m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); m->buf = seq_buf_alloc(m->size = PAGE_SIZE); if (!m->buf) return -ENOMEM; } Loading Loading @@ -135,9 +147,9 @@ static int traverse(struct seq_file *m, loff_t offset) Eoverflow: m->op->stop(m, p); kfree(m->buf); kvfree(m->buf); m->count = 0; m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); m->buf = seq_buf_alloc(m->size <<= 1); return !m->buf ? -ENOMEM : -EAGAIN; } Loading Loading @@ -192,7 +204,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) /* grab buffer if we didn't have one */ if (!m->buf) { m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); m->buf = seq_buf_alloc(m->size = PAGE_SIZE); if (!m->buf) goto Enomem; } Loading Loading @@ -232,9 +244,9 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) if (m->count < m->size) goto Fill; m->op->stop(m, p); kfree(m->buf); kvfree(m->buf); m->count = 0; m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); m->buf = seq_buf_alloc(m->size <<= 1); if (!m->buf) goto Enomem; m->version = 0; Loading Loading @@ -350,7 +362,7 @@ EXPORT_SYMBOL(seq_lseek); int seq_release(struct inode *inode, struct file *file) { struct seq_file *m = file->private_data; kfree(m->buf); kvfree(m->buf); kfree(m); return 0; } Loading Loading @@ -605,13 +617,13 @@ EXPORT_SYMBOL(single_open); int single_open_size(struct file *file, int (*show)(struct seq_file *, void *), void *data, size_t size) { char *buf = kmalloc(size, GFP_KERNEL); char *buf = seq_buf_alloc(size); int ret; if (!buf) return -ENOMEM; ret = single_open(file, show, data); if (ret) { kfree(buf); kvfree(buf); return ret; } ((struct seq_file *)file->private_data)->buf = buf; Loading Loading
fs/seq_file.c +21 −9 Original line number Diff line number Diff line Loading @@ -8,8 +8,10 @@ #include <linux/fs.h> #include <linux/export.h> #include <linux/seq_file.h> #include <linux/vmalloc.h> #include <linux/slab.h> #include <linux/cred.h> #include <linux/mm.h> #include <asm/uaccess.h> #include <asm/page.h> Loading @@ -30,6 +32,16 @@ static void seq_set_overflow(struct seq_file *m) m->count = m->size; } static void *seq_buf_alloc(unsigned long size) { void *buf; buf = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); if (!buf && size > PAGE_SIZE) buf = vmalloc(size); return buf; } /** * seq_open - initialize sequential file * @file: file we initialize Loading Loading @@ -96,7 +108,7 @@ static int traverse(struct seq_file *m, loff_t offset) return 0; } if (!m->buf) { m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); m->buf = seq_buf_alloc(m->size = PAGE_SIZE); if (!m->buf) return -ENOMEM; } Loading Loading @@ -135,9 +147,9 @@ static int traverse(struct seq_file *m, loff_t offset) Eoverflow: m->op->stop(m, p); kfree(m->buf); kvfree(m->buf); m->count = 0; m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); m->buf = seq_buf_alloc(m->size <<= 1); return !m->buf ? -ENOMEM : -EAGAIN; } Loading Loading @@ -192,7 +204,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) /* grab buffer if we didn't have one */ if (!m->buf) { m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); m->buf = seq_buf_alloc(m->size = PAGE_SIZE); if (!m->buf) goto Enomem; } Loading Loading @@ -232,9 +244,9 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) if (m->count < m->size) goto Fill; m->op->stop(m, p); kfree(m->buf); kvfree(m->buf); m->count = 0; m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); m->buf = seq_buf_alloc(m->size <<= 1); if (!m->buf) goto Enomem; m->version = 0; Loading Loading @@ -350,7 +362,7 @@ EXPORT_SYMBOL(seq_lseek); int seq_release(struct inode *inode, struct file *file) { struct seq_file *m = file->private_data; kfree(m->buf); kvfree(m->buf); kfree(m); return 0; } Loading Loading @@ -605,13 +617,13 @@ EXPORT_SYMBOL(single_open); int single_open_size(struct file *file, int (*show)(struct seq_file *, void *), void *data, size_t size) { char *buf = kmalloc(size, GFP_KERNEL); char *buf = seq_buf_alloc(size); int ret; if (!buf) return -ENOMEM; ret = single_open(file, show, data); if (ret) { kfree(buf); kvfree(buf); return ret; } ((struct seq_file *)file->private_data)->buf = buf; Loading