/*
 * Copyright (C) Ingo Molnar, 2002
 * Copyright (C) Ricardo Salveti de Araujo, 2007
 * Copyright (C) International Business Machines  Corp., 2007
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/*
 * NAME
 *     remap_file_pages01
 *
 * DESCRIPTION
 *     The remap_file_pages() system call is used to create a non-linear
 *     mapping, that is, a mapping in which the pages of the file are mapped
 *     into a non-sequential order in memory.  The advantage of using
 *     remap_file_pages() over using repeated calls to mmap(2) is that
 *     the former  approach  does  not require the kernel to create
 *     additional VMA (Virtual Memory Area) data structures.
 *
 *     Runs remap_file_pages agains a mmaped area and check the results
 *
 *     Setup:
 *       Create a temp directory, open a file and get the file descriptor
 *
 *     Test:
 *       Test with a normal file and with /dev/shm/cache_<pid>
 *       1. Set up the cache
 *       2. Write the cache to the file
 *       3. Runs mmap at the same file
 *       4. Runs remap_file_pages at the mapped memory
 *       5. Check the results
 *   $
 *     Cleanup:
 *       Remove the file and erase the tmp directory
 *
 * Usage:  <for command-line>
 *  remap_file_pages01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
 *     where,  -c n : Run n copies concurrently.
 *             -f   : Turn off functionality Testing.
 *             -i n : Execute test n times.
 *             -I x : Execute test for x seconds.
 *             -P x : Pause for x seconds between iterations.
 *             -t   : Turn on syscall timing.
 *
 * HISTORY
 *                - Ingo Molnar, <mingo@elte.hu> wrote this test case
 *                - Nick Piggin, <nickpiggin@yahoo.com.au> did the following cleanup
 *
 *     11/10/2007 - Port to LTP format by Subrata Modak, <subrata@linux.vnet.ibm.com>
 *                  and Ricardo Salveti de Araujo, <rsalveti@linux.vnet.ibm.com>
 *     25/02/2008 - Renaud Lottiaux, <Renaud.Lottiaux@kerlabs.com>
 *                  Fix NFS remove tmpdir issue due to non unmapped files.
 *                  Fix concurrency issue on the file /dev/shm/cache.
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <linux/unistd.h>

#include "test.h"		/*LTP Specific Include File */

/* Test case defines */
#define WINDOW_START 0x48000000

static int page_sz;
size_t page_words;
size_t cache_pages;
size_t cache_sz;
size_t window_pages;
size_t window_sz;

static void setup();
static void cleanup();
static void test_nonlinear(int fd);

char *TCID = "remap_file_pages01";
int TST_TOTAL = 2;

static char *cache_contents;
int fd1, fd2;			/* File descriptors used at the test */
char fname[255];

int main(int ac, char **av)
{
	int lc;
	const char *msg;

#if defined (__s390__) || (__s390x__) || (__ia64__)
	/* Disables the test in case the kernel version is lower than 2.6.12 and arch is s390 */
	if ((tst_kvercmp(2, 6, 12)) < 0) {
		tst_resm(TWARN,
			 "This test can only run on kernels that are 2.6.12 and higher");
		exit(0);
	}
#endif

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
	}

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {

		tst_count = 0;

		test_nonlinear(fd1);
		tst_resm(TPASS, "Non-Linear shm file OK");

		test_nonlinear(fd2);
		tst_resm(TPASS, "Non-Linear /tmp/ file OK");
	}

	/* clean up and exit */
	cleanup();
	tst_exit();

}

/* test case function, that runs remap_file_pages */
static void test_nonlinear(int fd)
{
	char *data = NULL;
	int i, j, repeat = 2;

	for (i = 0; i < cache_pages; i++) {
		char *page = cache_contents + i * page_sz;

		for (j = 0; j < page_words; j++)
			page[j] = i;
	}

	if (write(fd, cache_contents, cache_sz) != cache_sz) {
		tst_resm(TFAIL,
			 "Write Error for \"cache_contents\" to \"cache_sz\" of %zu (errno=%d : %s)",
			 cache_sz, errno, strerror(errno));
		cleanup(NULL);
	}

	data = mmap((void *)WINDOW_START,
		    window_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

	if (data == MAP_FAILED) {
		tst_resm(TFAIL, "mmap Error, errno=%d : %s", errno,
			 strerror(errno));
		cleanup(NULL);
	}

again:
	for (i = 0; i < window_pages; i += 2) {
		char *page = data + i * page_sz;

		if (remap_file_pages(page, page_sz * 2, 0,
				     (window_pages - i - 2), 0) == -1) {
			tst_resm(TFAIL | TERRNO,
				 "remap_file_pages error for page=%p, "
				 "page_sz=%d, window_pages=%zu",
				 page, (page_sz * 2), (window_pages - i - 2));
			cleanup(data);
		}
	}

	for (i = 0; i < window_pages; i++) {
		/*
		 * Double-check the correctness of the mapping:
		 */
		if (i & 1) {
			if (data[i * page_sz] != window_pages - i) {
				tst_resm(TFAIL,
					 "hm, mapped incorrect data, "
					 "data[%d]=%d, (window_pages-%d)=%zu",
					 (i * page_sz), data[i * page_sz], i,
					 (window_pages - i));
				cleanup(data);
			}
		} else {
			if (data[i * page_sz] != window_pages - i - 2) {
				tst_resm(TFAIL,
					 "hm, mapped incorrect data, "
					 "data[%d]=%d, (window_pages-%d-2)=%zu",
					 (i * page_sz), data[i * page_sz], i,
					 (window_pages - i - 2));
				cleanup(data);
			}
		}
	}

	if (--repeat)
		goto again;

	munmap(data, window_sz);
}

/* setup() - performs all ONE TIME setup for this test */
void setup(void)
{

	tst_sig(FORK, DEF_HANDLER, cleanup);

	tst_tmpdir();

	TEST_PAUSE;

	/* Get page size */
	page_sz = getpagesize();

	page_words = page_sz;

	/* Set the cache size */
	cache_pages = 1024;
	cache_sz = cache_pages * page_sz;
	cache_contents = malloc(cache_sz * sizeof(char));

	/* Set the window size */
	window_pages = 16;
	window_sz = window_pages * page_sz;

	sprintf(fname, "/dev/shm/cache_%d", getpid());

	if ((fd1 = open(fname, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
		tst_brkm(TBROK, cleanup,
			 "open(%s, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU) Failed, errno=%d : %s",
			 fname, errno, strerror(errno));
	}

	if ((fd2 = open("cache", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
		tst_brkm(TBROK, cleanup,
			 "open(%s, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU) Failed, errno=%d : %s",
			 "cache", errno, strerror(errno));
	}

}

/*
* cleanup() - Performs one time cleanup for this test at
* completion or premature exit
*/
void cleanup(char *data)
{
	/* Close the file descriptors */
	close(fd1);
	close(fd2);

	if (data)
		munmap(data, window_sz);

	/* Remove the /dev/shm/cache_<pid> file */
	unlink(fname);

	tst_rmdir();

}
