1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2014 4f08c3bdfSopenharmony_ci */ 5f08c3bdfSopenharmony_ci 6f08c3bdfSopenharmony_ci/*\ 7f08c3bdfSopenharmony_ci * [Description] 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * Testcase copied from sendfile02.c to test the basic functionality of 10f08c3bdfSopenharmony_ci * the sendfile() system call on large file. There is a kernel bug which 11f08c3bdfSopenharmony_ci * introduced by commit 8f9c0119d7ba9 and fixed by commit 5d73320a96fcc. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * Only supports 64bit systems. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * [Algorithm] 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * 1. Call sendfile() with offset at 0. 18f08c3bdfSopenharmony_ci * 2. Call sendfile() with offset at 3GB. 19f08c3bdfSopenharmony_ci */ 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci#include <inttypes.h> 22f08c3bdfSopenharmony_ci#include <sys/sendfile.h> 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_ci#include "tst_test.h" 25f08c3bdfSopenharmony_ci#include "lapi/abisize.h" 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_ci#ifndef TST_ABI32 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_ci#define ONE_GB (INT64_C(1) << 30) 30f08c3bdfSopenharmony_ci#define IN_FILE "in_file" 31f08c3bdfSopenharmony_ci#define OUT_FILE "out_file" 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_cistatic struct test_case_t { 34f08c3bdfSopenharmony_ci char *desc; 35f08c3bdfSopenharmony_ci off_t offset; 36f08c3bdfSopenharmony_ci int64_t count; 37f08c3bdfSopenharmony_ci int64_t exp_retval; 38f08c3bdfSopenharmony_ci int64_t exp_updated_offset; 39f08c3bdfSopenharmony_ci} tc[] = { 40f08c3bdfSopenharmony_ci { "offset at 0", 0, ONE_GB, ONE_GB, ONE_GB }, 41f08c3bdfSopenharmony_ci { "offset at 3GB", 3 * ONE_GB, ONE_GB, ONE_GB, 4 * ONE_GB } 42f08c3bdfSopenharmony_ci}; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_cistatic void setup(void) 45f08c3bdfSopenharmony_ci{ 46f08c3bdfSopenharmony_ci int i, fd; 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci if (!tst_fs_has_free(".", 5, TST_GB)) 49f08c3bdfSopenharmony_ci tst_brk(TCONF, "Test on large file needs 5G free space"); 50f08c3bdfSopenharmony_ci 51f08c3bdfSopenharmony_ci fd = SAFE_CREAT(IN_FILE, 00700); 52f08c3bdfSopenharmony_ci for (i = 1; i <= (4 * 1024); ++i) { 53f08c3bdfSopenharmony_ci SAFE_LSEEK(fd, 1024 * 1024 - 1, SEEK_CUR); 54f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd, "C", 1); 55f08c3bdfSopenharmony_ci } 56f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci fd = SAFE_CREAT(OUT_FILE, 00700); 59f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 60f08c3bdfSopenharmony_ci} 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void run(unsigned int i) 63f08c3bdfSopenharmony_ci{ 64f08c3bdfSopenharmony_ci int in_fd = SAFE_OPEN(IN_FILE, O_RDONLY); 65f08c3bdfSopenharmony_ci int out_fd = SAFE_OPEN(OUT_FILE, O_WRONLY); 66f08c3bdfSopenharmony_ci off_t offset = tc[i].offset; 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci off_t before_pos, after_pos; 69f08c3bdfSopenharmony_ci before_pos = SAFE_LSEEK(in_fd, 0, SEEK_CUR); 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci TEST(sendfile(out_fd, in_fd, &offset, tc[i].count)); 72f08c3bdfSopenharmony_ci after_pos = SAFE_LSEEK(in_fd, 0, SEEK_CUR); 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci if (TST_RET != tc[i].exp_retval) 75f08c3bdfSopenharmony_ci tst_res(TFAIL, "sendfile() failed to return expected value, " 76f08c3bdfSopenharmony_ci "expected: %" PRId64 ", got: %ld", 77f08c3bdfSopenharmony_ci tc[i].exp_retval, TST_RET); 78f08c3bdfSopenharmony_ci else if (offset != tc[i].exp_updated_offset) 79f08c3bdfSopenharmony_ci tst_res(TFAIL, "sendfile() failed to update OFFSET parameter to " 80f08c3bdfSopenharmony_ci "expected value, expected: %" PRId64 ", got: %" PRId64, 81f08c3bdfSopenharmony_ci tc[i].exp_updated_offset, (int64_t)(offset)); 82f08c3bdfSopenharmony_ci else if (before_pos != after_pos) 83f08c3bdfSopenharmony_ci tst_res(TFAIL, "sendfile() updated the file position of in_fd " 84f08c3bdfSopenharmony_ci "unexpectedly, expected file position: %" PRId64 85f08c3bdfSopenharmony_ci ", actual file position %" PRId64, 86f08c3bdfSopenharmony_ci (int64_t)(before_pos), (int64_t)(after_pos)); 87f08c3bdfSopenharmony_ci else 88f08c3bdfSopenharmony_ci tst_res(TPASS, "sendfile() with %s", tc[i].desc); 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_ci SAFE_CLOSE(in_fd); 91f08c3bdfSopenharmony_ci SAFE_CLOSE(out_fd); 92f08c3bdfSopenharmony_ci} 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_cistatic struct tst_test test = { 95f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 96f08c3bdfSopenharmony_ci .setup = setup, 97f08c3bdfSopenharmony_ci .test = run, 98f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tc), 99f08c3bdfSopenharmony_ci .max_runtime = 120, 100f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 101f08c3bdfSopenharmony_ci {"linux-git", "5d73320a96fcc"}, 102f08c3bdfSopenharmony_ci {} 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci}; 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_ci#else 107f08c3bdfSopenharmony_ciTST_TEST_TCONF("This test is only for 64bit"); 108f08c3bdfSopenharmony_ci#endif 109