lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Thu,  7 Aug 2008 05:00:55 +0300
From:	Octavian Purdila <opurdila@...acom.com>
To:	linux-kernel@...r.kernel.org
Cc:	Octavian Purdila <opurdila@...acom.com>
Subject: [RFC] [PATCH] splice: add ->splice_read support for /dev/zero

Useful for testing.

Preallocating the zero page is simpler and faster with the relatively
small (?) drawback of using an extra page of memory.

Maybe when CONFIG_EMBEDED is selected we can switch to dynamically
allocating the page?

Signed-off-by: Octavian Purdila <opurdila@...acom.com>
---
 drivers/char/mem.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 934ffaf..fb33f9a 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -737,6 +737,69 @@ static int mmap_zero(struct file * file, struct vm_area_struct * vma)
 	return 0;
 }
 
+static void zero_pipe_buf_release(struct pipe_inode_info *pipe,
+				  struct pipe_buffer *buf)
+{
+}
+
+static void zero_pipe_buf_get(struct pipe_inode_info *pipe,
+				struct pipe_buffer *buf)
+{
+}
+
+static int zero_pipe_buf_steal(struct pipe_inode_info *pipe,
+			       struct pipe_buffer *buf)
+{
+	return 1;
+}
+
+static struct pipe_buf_operations zero_pipe_buf_ops = {
+	.can_merge = 0,
+	.map = generic_pipe_buf_map,
+	.unmap = generic_pipe_buf_unmap,
+	.confirm = generic_pipe_buf_confirm,
+	.release = zero_pipe_buf_release,
+	.steal = zero_pipe_buf_steal,
+	.get = zero_pipe_buf_get,
+};
+
+static void zero_spd_release(struct splice_pipe_desc *spd, unsigned int nr)
+{
+}
+
+static struct page *zero_page;
+
+ssize_t splice_read_zero(struct file *in, loff_t *ppos,
+			 struct pipe_inode_info *pipe, size_t size,
+			 unsigned int flags)
+{
+	struct partial_page partial[PIPE_BUFFERS];
+	struct page *pages[PIPE_BUFFERS];
+	struct splice_pipe_desc spd = {
+		.pages = pages,
+		.partial = partial,
+		.flags = flags,
+		.ops = &zero_pipe_buf_ops,
+		.spd_release = zero_spd_release
+	};
+	int last_page_len = PAGE_SIZE, i;
+
+	spd.nr_pages = size/PAGE_SIZE;
+	if (spd.nr_pages > PIPE_BUFFERS)
+		spd.nr_pages = PIPE_BUFFERS;
+	if (size < PAGE_SIZE*PIPE_BUFFERS)
+		last_page_len = size % PAGE_SIZE;
+
+	for (i = 0; i < spd.nr_pages; i++) {
+		pages[i] = zero_page;
+		partial[i].len = PAGE_SIZE;
+		partial[i].offset = 0;
+	}
+	partial[spd.nr_pages].len = last_page_len;
+
+	return splice_to_pipe(pipe, &spd);
+}
+
 static ssize_t write_full(struct file * file, const char __user * buf,
 			  size_t count, loff_t *ppos)
 {
@@ -839,6 +902,7 @@ static const struct file_operations zero_fops = {
 	.read		= read_zero,
 	.write		= write_zero,
 	.mmap		= mmap_zero,
+	.splice_read 	= splice_read_zero,
 };
 
 /*
@@ -974,6 +1038,10 @@ static int __init chr_dev_init(void)
 	int i;
 	int err;
 
+	zero_page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
+	if (!zero_page)
+		return -ENOMEM;
+
 	err = bdi_init(&zero_bdi);
 	if (err)
 		return err;
-- 
1.5.6.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ