[LTP] [PATCH 2/2] fallocate02: Convert to new API
Andrea Cervesato
andrea.cervesato@suse.de
Mon Jul 20 13:48:27 CEST 2026
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the fallocate02 test case from the legacy LTP API (test.h) to the
new tst_test API using a table-driven struct tcase[] and TST_EXP_FAIL for
each error-path oracle.
Preserve every scenario and its exact errno (EBADF, EINVAL, EFBIG), the
64-bit-only guard around the EFBIG cases, the read-only fd that drives
EBADF, and the pre-population of the writable file. Map EOPNOTSUPP/ENOSYS
to TCONF via a support probe in setup(), and rely on framework
.needs_tmpdir instead of manual tmpdir handling.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/fallocate/fallocate02.c | 193 +++++++---------------
1 file changed, 61 insertions(+), 132 deletions(-)
diff --git a/testcases/kernel/syscalls/fallocate/fallocate02.c b/testcases/kernel/syscalls/fallocate/fallocate02.c
index 4469f02f2c45604c4f0503f0e824dd37f371b245..d31d2a1e407c5a78ece134387cad7e065fce473b 100644
--- a/testcases/kernel/syscalls/fallocate/fallocate02.c
+++ b/testcases/kernel/syscalls/fallocate/fallocate02.c
@@ -1,164 +1,93 @@
-/******************************************************************************
- * Copyright (c) International Business Machines Corp., 2007
- * Author: Sharyathi Nagesh <sharyathi@in.ibm.com>
- ******************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2007
+ * Author: Sharyathi Nagesh <sharyathi@in.ibm.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.
+/*\
+ * Verify that :manpage:`fallocate(2)` fails with the expected error codes:
*
- * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-***************************************************************************/
-
-/*
- * DESCRIPTION
- * check fallocate() with various error conditions that should produce
- * EBADF, EINVAL and EFBIG.
+ * - EBADF when the file descriptor is opened read-only.
+ * - EINVAL when the offset or length is negative, or the length is zero.
+ * - EFBIG when the requested range exceeds the maximum file size (only
+ * tested on 64-bit offset ABIs).
*/
#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <endian.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <sys/utsname.h>
-#include <limits.h>
-
-#include "test.h"
-#include "tso_safe_macros.h"
+#include "tst_test.h"
#include "lapi/fallocate.h"
#include "lapi/abisize.h"
-#define BLOCKS_WRITTEN 12
-#ifdef TEST_DEFAULT
-# define DEFAULT_TEST_MODE 0
-#else
-# define DEFAULT_TEST_MODE 1
-#endif
-#define OFFSET 12
-#define FNAMER "test_file1"
-#define FNAMEW "test_file2"
-#define BLOCK_SIZE 1024
-#define MAX_FILESIZE (LLONG_MAX / 1024)
-
-static void setup(void);
-static void fallocate_verify(int);
-static void cleanup(void);
+#define BLOCKS_WRITTEN 12
+#define OFFSET 12
+#define FNAMER "test_file1"
+#define FNAMEW "test_file2"
+#define BLOCK_SIZE 1024
+#define MAX_FILESIZE (LLONG_MAX / BLOCK_SIZE)
-static int fdw;
-static int fdr;
+static int fdr = -1;
+static int fdw = -1;
-static struct test_data_t {
+static struct tcase {
int *fd;
- char *fname;
- int mode;
loff_t offset;
loff_t len;
- int error;
-} test_data[] = {
- {&fdr, FNAMER, DEFAULT_TEST_MODE, 0, 1, EBADF},
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, -1, 1, EINVAL},
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, 1, -1, EINVAL},
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, BLOCKS_WRITTEN, 0, EINVAL},
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, BLOCKS_WRITTEN, -1, EINVAL},
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, -(BLOCKS_WRITTEN+OFFSET), 1, EINVAL},
+ int exp_errno;
+} tcases[] = {
+ {&fdr, 0, 1, EBADF},
+ {&fdw, -1, 1, EINVAL},
+ {&fdw, 1, -1, EINVAL},
+ {&fdw, BLOCKS_WRITTEN, 0, EINVAL},
+ {&fdw, BLOCKS_WRITTEN, -1, EINVAL},
+ {&fdw, -(BLOCKS_WRITTEN + OFFSET), 1, EINVAL},
#if defined(TST_ABI64) || _FILE_OFFSET_BITS == 64
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, MAX_FILESIZE, 1, EFBIG},
- {&fdw, FNAMEW, DEFAULT_TEST_MODE, 1, MAX_FILESIZE, EFBIG},
+ {&fdw, MAX_FILESIZE, 1, EFBIG},
+ {&fdw, 1, MAX_FILESIZE, EFBIG},
#endif
};
-TCID_DEFINE(fallocate02);
-int TST_TOTAL = ARRAY_SIZE(test_data);
-
-int main(int ac, char **av)
-{
- int lc;
- int i;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++)
- fallocate_verify(i);
- }
-
- cleanup();
-
- tst_exit();
-}
-
static void setup(void)
{
+ char buf[BLOCK_SIZE];
int i;
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-
- fdr = SAFE_OPEN(cleanup, FNAMER, O_RDONLY | O_CREAT, S_IRUSR);
+ fdr = SAFE_OPEN(FNAMER, O_RDONLY | O_CREAT, 0400);
+ fdw = SAFE_OPEN(FNAMEW, O_RDWR | O_CREAT, 0700);
- fdw = SAFE_OPEN(cleanup, FNAMEW, O_RDWR | O_CREAT, S_IRWXU);
-
- char buf[BLOCK_SIZE];
memset(buf, 'A', BLOCK_SIZE);
for (i = 0; i < BLOCKS_WRITTEN; i++)
- SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fdw, buf, BLOCK_SIZE);
-}
+ SAFE_WRITE(SAFE_WRITE_ALL, fdw, buf, BLOCK_SIZE);
-static void fallocate_verify(int i)
-{
- TEST(fallocate(*test_data[i].fd, test_data[i].mode,
- test_data[i].offset * BLOCK_SIZE,
- test_data[i].len * BLOCK_SIZE));
- if (TEST_ERRNO != test_data[i].error) {
- if (TEST_ERRNO == EOPNOTSUPP ||
- TEST_ERRNO == ENOSYS) {
- tst_brkm(TCONF, cleanup,
- "fallocate system call is not implemented");
- }
- tst_resm(TFAIL | TTERRNO,
- "fallocate(%s:%d, %d, %" PRId64 ", %" PRId64 ") "
- "failed, expected errno:%d", test_data[i].fname,
- *test_data[i].fd, test_data[i].mode,
- test_data[i].offset * BLOCK_SIZE,
- test_data[i].len * BLOCK_SIZE, test_data[i].error);
- } else {
- tst_resm(TPASS | TTERRNO,
- "fallocate(%s:%d, %d, %" PRId64 ", %" PRId64 ") "
- "returned %d", test_data[i].fname, *test_data[i].fd,
- test_data[i].mode, test_data[i].offset * BLOCK_SIZE,
- test_data[i].len * BLOCK_SIZE, TEST_ERRNO);
- }
+ TEST(fallocate(fdw, FALLOC_FL_KEEP_SIZE, 0, BLOCK_SIZE));
+ if (TST_RET == -1 && (TST_ERR == EOPNOTSUPP || TST_ERR == ENOSYS))
+ tst_brk(TCONF, "fallocate() not supported");
}
static void cleanup(void)
{
- if (fdw > 0)
- SAFE_CLOSE(NULL, fdw);
- if (fdr > 0)
- SAFE_CLOSE(NULL, fdr);
+ if (fdw != -1)
+ SAFE_CLOSE(fdw);
+ if (fdr != -1)
+ SAFE_CLOSE(fdr);
+}
- tst_rmdir();
+static void verify_fallocate(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ TST_EXP_FAIL(fallocate(*tc->fd, FALLOC_FL_KEEP_SIZE,
+ tc->offset * BLOCK_SIZE,
+ tc->len * BLOCK_SIZE), tc->exp_errno,
+ "fallocate(%d, %lld, %lld)", *tc->fd,
+ (long long)(tc->offset * BLOCK_SIZE),
+ (long long)(tc->len * BLOCK_SIZE));
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test = verify_fallocate,
+ .tcnt = ARRAY_SIZE(tcases),
+ .needs_tmpdir = 1,
+};
--
2.51.0
More information about the ltp
mailing list