[LTP] [PATCH v1] Create dio_read.c test

Andrea Cervesato andrea.cervesato@suse.com
Wed Dec 15 10:58:31 CET 2021


dio_read.c has been created to replace ltp-diorh.c

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 runtest/ltp-aiodio.part4                   |  10 +-
 testcases/kernel/io/ltp-aiodio/.gitignore  |   2 +-
 testcases/kernel/io/ltp-aiodio/dio_read.c  | 162 +++++++++++++++++++
 testcases/kernel/io/ltp-aiodio/ltp-diorh.c | 176 ---------------------
 4 files changed, 168 insertions(+), 182 deletions(-)
 create mode 100644 testcases/kernel/io/ltp-aiodio/dio_read.c
 delete mode 100644 testcases/kernel/io/ltp-aiodio/ltp-diorh.c

diff --git a/runtest/ltp-aiodio.part4 b/runtest/ltp-aiodio.part4
index ef1cfdac6..88a1b492b 100644
--- a/runtest/ltp-aiodio.part4
+++ b/runtest/ltp-aiodio.part4
@@ -61,8 +61,8 @@ DIT001 dio_truncate
 DIT002 dio_truncate
 #Running read_checkzero
 #gread_checkzero
-#Running ltp-diorh
-DOR000 ltp-diorh $TMPDIR/aiodio.$$/file2
-DOR001 ltp-diorh $TMPDIR/aiodio.$$/file3
-DOR002 ltp-diorh $TMPDIR/aiodio.$$/file4
-DOR003 ltp-diorh $TMPDIR/aiodio.$$/file5
+#Running dio_read
+DOR000 dio_read
+DOR001 dio_read
+DOR002 dio_read
+DOR003 dio_read
diff --git a/testcases/kernel/io/ltp-aiodio/.gitignore b/testcases/kernel/io/ltp-aiodio/.gitignore
index 8da8e946b..f5f20d57e 100644
--- a/testcases/kernel/io/ltp-aiodio/.gitignore
+++ b/testcases/kernel/io/ltp-aiodio/.gitignore
@@ -5,6 +5,6 @@
 /dio_append
 /dio_sparse
 /dio_truncate
+/dio_read
 /dirty
-/ltp-diorh
 /read_checkzero
diff --git a/testcases/kernel/io/ltp-aiodio/dio_read.c b/testcases/kernel/io/ltp-aiodio/dio_read.c
new file mode 100644
index 000000000..aa75329b2
--- /dev/null
+++ b/testcases/kernel/io/ltp-aiodio/dio_read.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *   Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Create a file using buffered writes while other processes are doing
+ * O_DIRECT reads and check if the buffer reads always see zero.
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/wait.h>
+#include "tst_test.h"
+#include "common.h"
+
+static char *str_numchildren;
+static char *str_writesize;
+static char *str_readsize;
+static char *str_filesize;
+
+static int numchildren;
+static long long readsize;
+static long long writesize;
+static long long filesize;
+static long long alignment;
+static char *iobuf;
+
+static void do_buffered_writes(int fd, char *bufptr, long long fsize, long long wsize, int pattern)
+{
+	long long offset;
+	long long w;
+
+	memset(bufptr, pattern, wsize);
+
+	tst_res(TINFO, "child %i reading file", getpid());
+	for (offset = 0; offset + wsize <= fsize; offset += wsize) {
+		w = pwrite(fd, bufptr, wsize, offset);
+		if (w < 0)
+			tst_brk(TBROK, "pwrite: %s", tst_strerrno(-w));
+		if (w != wsize)
+			tst_brk(TBROK, "pwrite: wrote %lld bytes out of %lld", w, wsize);
+
+		fsync(fd);
+	}
+}
+
+static int do_direct_reads(char *filename, char *bufptr, long long fsize, long long rsize)
+{
+	int fd;
+	long long offset;
+	long long w;
+	int fail = 0;
+
+	while ((fd = open(filename, O_RDONLY | O_DIRECT, 0666)) < 0)
+		usleep(100);
+
+	for (offset = 0; offset + rsize < fsize; offset += rsize) {
+		char *bufoff;
+
+		w = pread(fd, bufptr, rsize, offset);
+		if (w < 0)
+			tst_brk(TBROK, "pread: %s", tst_strerrno(-w));
+		if (w != rsize)
+			tst_brk(TBROK, "pread: read %lld bytes out of %lld", w, rsize);
+
+		bufoff = check_zero(bufptr, rsize);
+		if (bufoff) {
+			fail = 1;
+			break;
+		}
+	}
+
+	SAFE_CLOSE(fd);
+	return fail;
+}
+
+static void setup(void)
+{
+	struct stat sb;
+	long long buffsize;
+
+	numchildren = 100;
+	readsize = 32 * 1024 * 1024;
+	writesize = 32 * 1024 * 1024;
+	filesize = 128 * 1024 * 1024;
+	alignment = 512;
+
+	if (tst_parse_filesize(str_filesize, &filesize, 1, LLONG_MAX))
+		tst_brk(TBROK, "Invalid file size '%s'", str_filesize);
+
+	if (tst_parse_int(str_numchildren, &numchildren, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of children '%s'", str_numchildren);
+
+	if (tst_parse_filesize(str_writesize, &writesize, 1, filesize))
+		tst_brk(TBROK, "Invalid write blocks size '%s'", str_writesize);
+
+	if (tst_parse_filesize(str_readsize, &readsize, 1, filesize))
+		tst_brk(TBROK, "Invalid read blocks size '%s'", str_readsize);
+
+	SAFE_STAT(".", &sb);
+	alignment = sb.st_blksize;
+
+	buffsize = readsize;
+	if (writesize > readsize)
+		buffsize = writesize;
+
+	iobuf = SAFE_MEMALIGN(alignment, buffsize);
+}
+
+static void run(void)
+{
+	char *filename = "file.bin";
+	int pid[numchildren];
+	int fd;
+	int i;
+	int fail;
+
+	fd = SAFE_OPEN(filename, O_CREAT | O_TRUNC | O_RDWR, 0666);
+	SAFE_FTRUNCATE(fd, filesize);
+
+	for (i = 0; i < numchildren; i++) {
+		pid[i] = SAFE_FORK();
+		if (!pid[i]) {
+			do_buffered_writes(fd, iobuf, filesize, writesize, 0);
+			return;
+		}
+	}
+
+	fail = do_direct_reads(filename, iobuf, filesize, readsize);
+	for (i = 0; i < numchildren; i++)
+		wait4(pid[i], NULL, WNOHANG, 0);
+
+	/* Fill the file with a known pattern so that the blocks
+	 * on disk can be detected if they become exposed. */
+	do_buffered_writes(fd, iobuf, filesize, writesize, 1);
+	fsync(fd);
+
+	SAFE_FTRUNCATE(fd, 0);
+	fsync(fd);
+
+	if (fail)
+		tst_res(TFAIL, "Non zero bytes read");
+	else
+		tst_res(TPASS, "All bytes read were zeroed");
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.forks_child = 1,
+	.options = (struct tst_option[]) {
+		{"n:", &str_numchildren, "Number of threads (default 100)"},
+		{"w:", &str_writesize, "Size of writing blocks (default 32M)"},
+		{"r:", &str_readsize, "Size of reading blocks (default 32M)"},
+		{"s:", &str_filesize, "File size (default 128M)"},
+		{}
+	},
+};
diff --git a/testcases/kernel/io/ltp-aiodio/ltp-diorh.c b/testcases/kernel/io/ltp-aiodio/ltp-diorh.c
deleted file mode 100644
index 3bdf62388..000000000
--- a/testcases/kernel/io/ltp-aiodio/ltp-diorh.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- *   Copyright (C) 2003,2004 Red Hat, Inc.  All rights reserved.
- *
- *   The contents of this file may be used under the terms of the GNU
- *   General Public License version 2 (the "GPL")
- *
- *   Author: Stephen C. Tweedie <sct@redhat.com>
- *   This program is free software;  you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
- *   the GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Module: .c
- */
-
-/*
- * Change History:
- *
- * 2/2004  Marty Ridgeway (mridge@us.ibm.com) Changes to adapt to LTP
- *
- */
-
-#define _XOPEN_SOURCE 600
-#define _GNU_SOURCE
-#define MAX_ITERATIONS 250
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-
-#define BIGSIZE 128*1024*1024
-#define READSIZE 32*1024*1024
-#define WRITESIZE 32*1024*1024
-
-int pagesize;
-char *iobuf;
-int pass = 0;
-
-void assert(const char *what, int assertion)
-{
-	if (assertion)
-		return;
-	perror(what);
-	exit(1);
-}
-
-void do_buffered_writes(int fd, int pattern)
-{
-	int rc;
-	int offset;
-
-	memset(iobuf, pattern, WRITESIZE);
-	for (offset = 0; offset + WRITESIZE <= BIGSIZE; offset += WRITESIZE) {
-		rc = pwrite(fd, iobuf, WRITESIZE, offset);
-		assert("pwrite", rc >= 0);
-		if (rc != WRITESIZE) {
-			fprintf(stderr, "Pass %d: short write (%d out of %d)\n",
-				pass, rc, WRITESIZE);
-			exit(1);
-		}
-		fsync(fd);
-	}
-}
-
-int do_direct_reads(char *filename)
-{
-	int fd;
-	int offset;
-	int rc, i;
-	int *p;
-
-	fd = open(filename, O_DIRECT | O_RDONLY, 0);
-	assert("open", fd >= 0);
-
-	for (offset = 0; offset + READSIZE <= BIGSIZE; offset += READSIZE) {
-		rc = pread(fd, iobuf, READSIZE, offset);
-		assert("pread", rc >= 0);
-		if (rc != READSIZE) {
-			fprintf(stderr, "Pass: %d short read (%d out of %d)\n",
-				pass, rc, READSIZE);
-			exit(1);
-		}
-		for (i = 0, p = (int *)iobuf; i < READSIZE; i += 4) {
-			if (*p) {
-				fprintf(stderr,
-					"Pass: %d Found data (%08x) at offset %d+%d\n",
-					pass, *p, offset, i);
-				close(fd);
-				return 1;
-			}
-			p++;
-		}
-	}
-	close(fd);
-	return 0;
-}
-
-int main(int argc, char *argv[])
-{
-	char *filename;
-	int fd;
-	int pid;
-	int err;
-	int bufsize;
-
-	if (argc != 2) {
-		fprintf(stderr, "Needs a filename as an argument.\n");
-		exit(1);
-	}
-
-	filename = argv[1];
-
-	pagesize = getpagesize();
-	bufsize = READSIZE;
-	if (WRITESIZE > READSIZE)
-		bufsize = WRITESIZE;
-	err = posix_memalign((void **)&iobuf, pagesize, bufsize);
-	if (err) {
-		fprintf(stderr, "Error allocating %d aligned bytes.\n",
-			bufsize);
-		exit(1);
-	}
-
-	fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666);
-	assert("open", fd >= 0);
-
-	do {
-
-		assert("ftruncate", ftruncate(fd, BIGSIZE) == 0);
-		fsync(fd);
-
-		pid = fork();
-		assert("fork", pid >= 0);
-
-		if (!pid) {
-			do_buffered_writes(fd, 0);
-			exit(0);
-		}
-
-		err = do_direct_reads(filename);
-
-		wait4(pid, NULL, WNOHANG, 0);
-
-		if (err)
-			break;
-
-		/* Fill the file with a known pattern so that the blocks
-		 * on disk can be detected if they become exposed. */
-		do_buffered_writes(fd, 1);
-		fsync(fd);
-
-		assert("ftruncate", ftruncate(fd, 0) == 0);
-		fsync(fd);
-	} while (pass++ < MAX_ITERATIONS);
-
-	if (!err) {
-		fprintf(stdout, "ltp-diorh: Completed %d iterations OK \n",
-			pass);
-	}
-
-	return err;
-}
-- 
2.34.1



More information about the ltp mailing list