1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2001, International Business Machines  Corp.
4f08c3bdfSopenharmony_ci * Copyright (c) 2020, Joerg Vehlow <joerg.vehlow@aox-tech.de>
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * The purpose of this test is to verify the file size limitations
7f08c3bdfSopenharmony_ci * of a filesystem. It writes one buffer at a time and lseeks from
8f08c3bdfSopenharmony_ci * the beginning of the file to the end of the last write position.
9f08c3bdfSopenharmony_ci * The intent is to test lseek64.
10f08c3bdfSopenharmony_ci */
11f08c3bdfSopenharmony_ci
12f08c3bdfSopenharmony_ci#include <stdio.h>
13f08c3bdfSopenharmony_ci#include <stdlib.h>
14f08c3bdfSopenharmony_ci#include <sys/types.h>
15f08c3bdfSopenharmony_ci#include <sys/stat.h>
16f08c3bdfSopenharmony_ci#include <unistd.h>
17f08c3bdfSopenharmony_ci#include <fcntl.h>
18f08c3bdfSopenharmony_ci#include <time.h>
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci#include "tst_test.h"
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_cistatic char *str_bufnum;
23f08c3bdfSopenharmony_cistatic int bufnum = 100;
24f08c3bdfSopenharmony_cistatic char buf[TST_MB];
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cistatic void setup(void)
27f08c3bdfSopenharmony_ci{
28f08c3bdfSopenharmony_ci	unsigned int i;
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci	if (str_bufnum) {
31f08c3bdfSopenharmony_ci		if (tst_parse_int(str_bufnum, &bufnum, 0, INT_MAX)) {
32f08c3bdfSopenharmony_ci			tst_brk(TBROK, "Invalid buffer count '%s'", str_bufnum);
33f08c3bdfSopenharmony_ci		}
34f08c3bdfSopenharmony_ci	}
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci	buf[0] = 'A';
37f08c3bdfSopenharmony_ci	for (i = 1; i < ARRAY_SIZE(buf) - 1; i++)
38f08c3bdfSopenharmony_ci		buf[i] = '0';
39f08c3bdfSopenharmony_ci	buf[ARRAY_SIZE(buf) - 1] = 'Z';
40f08c3bdfSopenharmony_ci}
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cistatic void run(void)
43f08c3bdfSopenharmony_ci{
44f08c3bdfSopenharmony_ci	time_t time1, time2;
45f08c3bdfSopenharmony_ci	int i, fd, diff;
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_ci	time1 = time(NULL);
48f08c3bdfSopenharmony_ci	tst_res(TINFO, "started building a %d megabyte file", bufnum);
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci	if ((fd = creat("large_file", 0755)) == -1)
51f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "creat() failed");
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	for (i = 0; i < bufnum; i++) {
54f08c3bdfSopenharmony_ci		if (write(fd, buf, sizeof(buf)) == -1) {
55f08c3bdfSopenharmony_ci			tst_brk(TFAIL | TERRNO, "write() failed");
56f08c3bdfSopenharmony_ci		}
57f08c3bdfSopenharmony_ci		fsync(fd);
58f08c3bdfSopenharmony_ci		if (lseek(fd, (i + 1) * sizeof(buf), 0) == -1)
59f08c3bdfSopenharmony_ci			tst_brk(TFAIL | TERRNO, "lseek failed");
60f08c3bdfSopenharmony_ci	}
61f08c3bdfSopenharmony_ci	close(fd);
62f08c3bdfSopenharmony_ci	time2 = time(NULL);
63f08c3bdfSopenharmony_ci	tst_res(TINFO, "finished building a %d megabyte file", bufnum);
64f08c3bdfSopenharmony_ci	diff = time2 - time1;
65f08c3bdfSopenharmony_ci	tst_res(TINFO, "total time for test to run: %d minute(s) and %d seconds",
66f08c3bdfSopenharmony_ci	        diff / 60, diff % 60);
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci	tst_res(TPASS, "test successful");
69f08c3bdfSopenharmony_ci}
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_cistatic struct tst_test test = {
72f08c3bdfSopenharmony_ci	.options = (struct tst_option[]) {
73f08c3bdfSopenharmony_ci		{"n:", &str_bufnum, "COUNT Number of megabytes to write (default 100)"},
74f08c3bdfSopenharmony_ci		{}
75f08c3bdfSopenharmony_ci	},
76f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
77f08c3bdfSopenharmony_ci	.setup = setup,
78f08c3bdfSopenharmony_ci	.test_all = run
79f08c3bdfSopenharmony_ci};
80