You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
8.0 KiB
276 lines
8.0 KiB
/******************************************************************************
|
|
* fallocate01.c
|
|
* Mon Dec 24 2007
|
|
* Copyright (c) International Business Machines Corp., 2007
|
|
* Emali : 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.
|
|
*
|
|
* 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.
|
|
***************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* OS Test - International Business Machines Corp. 2007.
|
|
*
|
|
* TEST IDENTIFIER : fallocate01
|
|
*
|
|
* EXECUTED BY : anyone
|
|
*
|
|
* TEST TITLE : Basic test for fallocate()
|
|
*
|
|
* TEST CASE TOTAL : 2
|
|
*
|
|
* CPU ARCHITECTURES : PPC,X86, X86_64
|
|
*
|
|
* AUTHOR : Sharyathi Nagesh
|
|
*
|
|
* CO-PILOT :
|
|
*
|
|
* DATE STARTED : 24/12/2007
|
|
*
|
|
* TEST CASES
|
|
* (Working of fallocate under 2 modes)
|
|
* 1) DEFAULT 2)FALLOC_FL_KEEP_SIZE
|
|
*
|
|
* INPUT SPECIFICATIONS
|
|
* No input needs to be specified
|
|
* fallocate() in puts are generated randomly
|
|
*
|
|
* OUTPUT SPECIFICATIONS
|
|
* Output describing whether test cases passed or failed.
|
|
*
|
|
* ENVIRONMENTAL NEEDS
|
|
* Test Needs to be executed on file system supporting ext4
|
|
* LTP {TMP} Needs to be set to such a folder
|
|
*
|
|
* SPECIAL PROCEDURAL REQUIREMENTS
|
|
* None
|
|
*
|
|
* DETAILED DESCRIPTION
|
|
* This is a test case for fallocate() system call.
|
|
* This test suite tests basic working of fallocate under different modes
|
|
* It trys to fallocate memory blocks and write into that block
|
|
*
|
|
* Total 2 Test Cases :-
|
|
* (1) Test Case for DEFAULT MODE
|
|
* (2) Test Case for FALLOC_FL_KEEP_SIZE
|
|
*
|
|
* Setup:
|
|
* Setup file on which fallocate is to be called
|
|
* Set up 2 files for each mode
|
|
*
|
|
* Test:
|
|
* Loop if the proper options are given.
|
|
* Execute system call
|
|
* Check return code, if system call did fail
|
|
* lseek to some random location with in allocate block
|
|
* write data into the locattion Report if any error encountered
|
|
* PASS the test otherwise
|
|
*
|
|
* Cleanup:
|
|
* Cleanup the temporary folder
|
|
*
|
|
*************************************************************************/
|
|
|
|
#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 <sys/syscall.h>
|
|
#include <unistd.h>
|
|
#include <inttypes.h>
|
|
#include <sys/utsname.h>
|
|
|
|
#include "test.h"
|
|
#include "safe_macros.h"
|
|
#include "lapi/fallocate.h"
|
|
#include "lapi/fcntl.h"
|
|
|
|
#define BLOCKS_WRITTEN 12
|
|
|
|
void get_blocksize(int);
|
|
void populate_files(int fd);
|
|
void runtest(int, int, loff_t);
|
|
|
|
char *TCID = "fallocate01";
|
|
char fname_mode1[255], fname_mode2[255]; /* Files used for testing */
|
|
int fd_mode1, fd_mode2;
|
|
int TST_TOTAL = 2;
|
|
loff_t block_size;
|
|
int buf_size;
|
|
|
|
/******************************************************************************
|
|
* Performs all one time clean up for this test on successful
|
|
* completion, premature exit or failure. Closes all temporary
|
|
* files, removes all temporary directories exits the test with
|
|
* appropriate return code by calling tst_exit() function.
|
|
******************************************************************************/
|
|
void cleanup(void)
|
|
{
|
|
|
|
if (close(fd_mode1) == -1)
|
|
tst_resm(TWARN | TERRNO, "close(%s) failed", fname_mode1);
|
|
if (close(fd_mode2) == -1)
|
|
tst_resm(TWARN | TERRNO, "close(%s) failed", fname_mode2);
|
|
tst_rmdir();
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Performs all one time setup for this test. This function is
|
|
* used to create temporary dirs and temporary files
|
|
* that may be used in the course of this test
|
|
******************************************************************************/
|
|
void setup(void)
|
|
{
|
|
/* Create temporary directories */
|
|
TEST_PAUSE;
|
|
|
|
tst_tmpdir();
|
|
|
|
sprintf(fname_mode1, "tfile_mode1_%d", getpid());
|
|
fd_mode1 = SAFE_OPEN(cleanup, fname_mode1, O_RDWR | O_CREAT, 0700);
|
|
get_blocksize(fd_mode1);
|
|
populate_files(fd_mode1);
|
|
|
|
sprintf(fname_mode2, "tfile_mode2_%d", getpid());
|
|
fd_mode2 = SAFE_OPEN(cleanup, fname_mode2, O_RDWR | O_CREAT, 0700);
|
|
populate_files(fd_mode2);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Gets the block size for the file system
|
|
******************************************************************************/
|
|
void get_blocksize(int fd)
|
|
{
|
|
struct stat file_stat;
|
|
|
|
if (fstat(fd, &file_stat) < 0)
|
|
tst_resm(TFAIL | TERRNO,
|
|
"fstat failed while getting block_size");
|
|
|
|
block_size = file_stat.st_blksize;
|
|
buf_size = block_size;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Writes data into the file
|
|
******************************************************************************/
|
|
|
|
void populate_files(int fd)
|
|
{
|
|
char buf[buf_size + 1];
|
|
int index;
|
|
int blocks;
|
|
int data;
|
|
|
|
for (blocks = 0; blocks < BLOCKS_WRITTEN; blocks++) {
|
|
for (index = 0; index < buf_size; index++)
|
|
buf[index] = 'A' + (index % 26);
|
|
buf[buf_size] = '\0';
|
|
if ((data = write(fd, buf, buf_size)) == -1)
|
|
tst_brkm(TBROK | TERRNO, cleanup, "write failed");
|
|
}
|
|
}
|
|
|
|
int main(int ac, char **av)
|
|
{
|
|
loff_t expected_size;
|
|
int lc;
|
|
|
|
tst_parse_opts(ac, av, NULL, NULL);
|
|
|
|
setup();
|
|
|
|
for (lc = 0; TEST_LOOPING(lc); lc++) {
|
|
tst_count = 0;
|
|
|
|
expected_size = BLOCKS_WRITTEN * block_size + block_size;
|
|
runtest(0, fd_mode1, expected_size);
|
|
|
|
expected_size = BLOCKS_WRITTEN * block_size;
|
|
runtest(FALLOC_FL_KEEP_SIZE, fd_mode2, expected_size);
|
|
}
|
|
|
|
cleanup();
|
|
tst_exit();
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Calls the system call, with appropriate parameters and writes data
|
|
******************************************************************************/
|
|
void runtest(int mode, int fd, loff_t expected_size)
|
|
{
|
|
loff_t offset;
|
|
loff_t len = block_size;
|
|
loff_t write_offset, lseek_offset;
|
|
offset = lseek(fd, 0, SEEK_END);
|
|
struct stat file_stat;
|
|
errno = 0;
|
|
|
|
TEST(fallocate(fd, mode, offset, len));
|
|
/* check return code */
|
|
if (TEST_RETURN != 0) {
|
|
if (TEST_ERRNO == EOPNOTSUPP || TEST_ERRNO == ENOSYS) {
|
|
tst_brkm(TCONF, cleanup,
|
|
"fallocate system call is not implemented");
|
|
}
|
|
tst_resm(TFAIL | TTERRNO,
|
|
"fallocate(%d, %d, %" PRId64 ", %" PRId64 ") failed",
|
|
fd, mode, offset, len);
|
|
return;
|
|
} else {
|
|
tst_resm(TPASS,
|
|
"fallocate(%d, %d, %" PRId64 ", %" PRId64
|
|
") returned %ld", fd, mode, offset, len,
|
|
TEST_RETURN);
|
|
}
|
|
|
|
if (fstat(fd, &file_stat) < 0)
|
|
tst_resm(TFAIL | TERRNO, "fstat failed after fallocate()");
|
|
|
|
if (file_stat.st_size != expected_size)
|
|
tst_resm(TFAIL | TTERRNO,
|
|
"fstat test fails on fallocate (%d, %d, %" PRId64 ", %"
|
|
PRId64 ") Failed on mode", fd, mode, offset, len);
|
|
|
|
write_offset = random() % len;
|
|
lseek_offset = lseek(fd, write_offset, SEEK_CUR);
|
|
if (lseek_offset != offset + write_offset) {
|
|
tst_resm(TFAIL | TTERRNO,
|
|
"lseek fails in fallocate(%d, %d, %" PRId64 ", %"
|
|
PRId64 ") failed on mode", fd, mode, offset, len);
|
|
return;
|
|
}
|
|
//Write a character to file at random location
|
|
TEST(write(fd, "A", 1));
|
|
/* check return code */
|
|
if (TEST_RETURN == -1) {
|
|
tst_resm(TFAIL | TTERRNO,
|
|
"write fails in fallocate(%d, %d, %" PRId64 ", %"
|
|
PRId64 ") failed", fd, mode, offset, len);
|
|
} else {
|
|
tst_resm(TPASS,
|
|
"write operation on fallocated(%d, %d, %"
|
|
PRId64 ", %" PRId64 ") returned %ld", fd, mode,
|
|
offset, len, TEST_RETURN);
|
|
}
|
|
}
|