18445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/* IBM Corporation */
28445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/* 01/02/2003	Port to LTP	avenkat@us.ibm.com*/
38445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
48445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/*
58445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   Copyright (c) International Business Machines  Corp., 2003
68445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *
78445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *
88445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   This program is free software;  you can redistribute it and/or modify
98445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   it under the terms of the GNU General Public License as published by
108445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   the Free Software Foundation; either version 2 of the License, or
118445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   (at your option) any later version.
128445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *
138445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   This program is distributed in the hope that it will be useful,
148445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
158445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
168445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   the GNU General Public License for more details.
178445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *
188445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   You should have received a copy of the GNU General Public License
198445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *   along with this program;  if not, write to the Free Software
204548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
218445709ba82f1e90bde58aa07128ac5048ea0daerobbiew */
228445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
238445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/* mfile_insque:
248445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *	This test mmaps a portion of a file, and then mmaps the next
258445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *	portion of the file in front of the virtual space containing the
268445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *	original mmap.  It then mmaps the preceding portion of the file behind
278445709ba82f1e90bde58aa07128ac5048ea0daerobbiew *	the original mmap.  None of the mmaps can be concatenated.
288445709ba82f1e90bde58aa07128ac5048ea0daerobbiew */
298445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include <sys/types.h>
308445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include <sys/mman.h>
318445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include <unistd.h>
328445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include <fcntl.h>
338445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include <signal.h>
348445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include <stdio.h>
35c0325f7b651f42a514c19d4238e5f66949b50c50robbiew#include <errno.h>
368445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/* #include <sys/pte.h> */
378445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
388445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/*****	LTP Port	*****/
398445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#include "test.h"
408445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/*****	**	**	*****/
418445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
428445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#ifndef MMU_NARROWPTEPG
438445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define MMU_NARROWPTEPG	1024
448445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#endif
458445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
468445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/*****	LTP Port	*****/
478445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define FAILED 0
488445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define PASSED 1
498445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
508445709ba82f1e90bde58aa07128ac5048ea0daerobbiewint local_flag = PASSED;
51354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaochar *TCID = "mmapstress05";	//mfile_insque
528445709ba82f1e90bde58aa07128ac5048ea0daerobbiewFILE *temp;
538445709ba82f1e90bde58aa07128ac5048ea0daerobbiewint TST_TOTAL = 1;
548445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
558445709ba82f1e90bde58aa07128ac5048ea0daerobbiewint anyfail();
568445709ba82f1e90bde58aa07128ac5048ea0daerobbiewvoid ok_exit();
578445709ba82f1e90bde58aa07128ac5048ea0daerobbiew/*****	**	**	*****/
588445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
598445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define ERROR(M)	(void)fprintf(stderr, "%s:  errno = %d; " M "\n", \
608445709ba82f1e90bde58aa07128ac5048ea0daerobbiew				progname, errno);
618445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define CLEAN	(void)close(fd); \
6276a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak		if (munmap(mmapaddr+pagesize, pagesize) == -1) { \
6376a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak			ERROR("munmap failed"); \
6476a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak		} \
6576a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak		if (munmap(mmapaddr, pagesize) == -1) { \
6676a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak			ERROR("munmap failed"); \
6776a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak		} \
6876a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak		if (munmap(mmapaddr+2*pagesize, pagesize) == -1) { \
6976a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak			ERROR("munmap failed"); \
7076a720a381f351b33eb203c7c519e6f44bbe7219Subrata Modak		} \
718445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		if (unlink(tmpname)) { \
728445709ba82f1e90bde58aa07128ac5048ea0daerobbiew			ERROR("couldn't clean up temp file"); \
738445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		}
748445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
758445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define CERROR(M)	CLEAN; ERROR(M)
768445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
778445709ba82f1e90bde58aa07128ac5048ea0daerobbiew#define CATCH_SIG(SIG) \
788445709ba82f1e90bde58aa07128ac5048ea0daerobbiew        if (sigaction(SIG, &sa, 0) == -1) { \
798445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		ERROR("couldn't catch signal " #SIG); \
808445709ba82f1e90bde58aa07128ac5048ea0daerobbiew                exit(1); \
818445709ba82f1e90bde58aa07128ac5048ea0daerobbiew        }
828445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
83354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoextern time_t time(time_t *);
84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoextern char *ctime(const time_t *);
858445709ba82f1e90bde58aa07128ac5048ea0daerobbiewextern void exit(int);
868445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
878445709ba82f1e90bde58aa07128ac5048ea0daerobbiewstatic int fd;
888445709ba82f1e90bde58aa07128ac5048ea0daerobbiew//static char *tmpname; 12/31/02
898445709ba82f1e90bde58aa07128ac5048ea0daerobbiewstatic char tmpname[] = "fileXXXXXX";
908445709ba82f1e90bde58aa07128ac5048ea0daerobbiewstatic char *progname;
918445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /*ARGSUSED*/ static
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid cleanup(int sig)
948445709ba82f1e90bde58aa07128ac5048ea0daerobbiew{
958445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	/*
968445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	 * Don't check error codes - we could be signaled before the file is
978445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	 * created.
988445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	 */
998445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	(void)close(fd);
1008445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	(void)unlink(tmpname);
1018445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	exit(1);
1028445709ba82f1e90bde58aa07128ac5048ea0daerobbiew}
1038445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint main(int argc, char *argv[])
1058445709ba82f1e90bde58aa07128ac5048ea0daerobbiew{
106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t pagesize = (size_t) sysconf(_SC_PAGE_SIZE);
107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	caddr_t mmapaddr;
108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *buf;
109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	time_t t;
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int i;
111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	struct sigaction sa;
1128445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
1138445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	if (!argc) {
1148445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		(void)fprintf(stderr, "argc == 0\n");
1158445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		return 1;
1168445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1178445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	tst_tmpdir();
1188445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	progname = argv[0];
1198445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	(void)time(&t);
120354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao//      (void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port
121354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (sbrk(pagesize - ((ulong) sbrk(0) & (pagesize - 1))) == (char *)-1) {
1228445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		ERROR("couldn't round up brk");
1238445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1248445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1258445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	if ((buf = sbrk(pagesize)) == (char *)-1) {
1268445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		ERROR("couldn't allocate output buffer");
1278445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1288445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if ((mmapaddr = (caddr_t) sbrk(0)) == (caddr_t) - 1) {
1308445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		ERROR("couldn't find top of brk");
1318445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1328445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1332c28215423293e443469a07ae7011135d058b671Garrett Cooper
1348445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	/* i changed the second argument to NULL
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	   from argv[0]. otherwise it causes the
136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	   open to fail
137354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	   -- sreeni
138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	 */
1398445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if ((fd = mkstemp(tmpname)) == -1) {
141e93a32461314822bdf3eab4f336fa88f8d8eb8afrobbiew		ERROR("mkstemp failed");
1428445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1438445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1448445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	sa.sa_handler = cleanup;
145354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	sa.sa_flags = 0;
146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (sigemptyset(&sa.sa_mask)) {
1478445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		ERROR("sigemptyset failed");
1488445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
1508445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	CATCH_SIG(SIGINT);
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	CATCH_SIG(SIGQUIT);
152354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	CATCH_SIG(SIGTERM);
1538445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	for (i = 0; i < pagesize; i++)
1548445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		buf[i] = 'a';
1558445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	if (write(fd, buf, pagesize) != pagesize) {
1568445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("couldn't write page case 1");
1578445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1588445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (lseek(fd, MMU_NARROWPTEPG * pagesize, SEEK_SET) == -1) {
1608445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("lseek case 1 failed");
1618445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1628445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1638445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	if (write(fd, buf, pagesize) != pagesize) {
1648445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("couldn't write page case 2");
1658445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1668445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
167354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (lseek(fd, 2 * MMU_NARROWPTEPG * pagesize, SEEK_SET) == -1) {
1688445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("lseek case 2 failed");
1698445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1708445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1718445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	if (write(fd, buf, pagesize) != pagesize) {
1728445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("couldn't write page case 3");
1738445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1748445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1758445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	/* fd now references a sparce file which has three pages widely spaced.
1768445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	 * Hopefully different mfile objects will be needed to reference each
1778445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	 * page.
1788445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	 */
179354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (mmap(mmapaddr + pagesize, pagesize, PROT_READ,
180354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd,
181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 MMU_NARROWPTEPG * pagesize)
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    == (caddr_t) - 1) {
1838445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("first mmap (of third page) failed");
1848445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1858445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
1868445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	if (mmap(mmapaddr, pagesize, PROT_READ,
187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd,
188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 2 * MMU_NARROWPTEPG * pagesize)
189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	    == (caddr_t) - 1) {
1908445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("second mmap (of fifth page) failed");
1918445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1928445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
193354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (mmap(mmapaddr + 2 * pagesize, pagesize, PROT_READ,
194354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd, 0) == (caddr_t) - 1) {
1958445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		CERROR("third mmap (of first page) failed");
1968445709ba82f1e90bde58aa07128ac5048ea0daerobbiew		anyfail();
1978445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	}
198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	CLEAN;			/*comment */
1998445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	(void)time(&t);
200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao//      (void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP Port
2018445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	ok_exit();
2022c28215423293e443469a07ae7011135d058b671Garrett Cooper	tst_exit();
2038445709ba82f1e90bde58aa07128ac5048ea0daerobbiew}
2048445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
205829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingervoid ok_exit(void)
2068445709ba82f1e90bde58aa07128ac5048ea0daerobbiew{
207354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	tst_resm(TPASS, "Test passed\n");
208354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	tst_rmdir();
2098445709ba82f1e90bde58aa07128ac5048ea0daerobbiew	tst_exit();
2108445709ba82f1e90bde58aa07128ac5048ea0daerobbiew}
2118445709ba82f1e90bde58aa07128ac5048ea0daerobbiew
212829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysingerint anyfail(void)
2138445709ba82f1e90bde58aa07128ac5048ea0daerobbiew{
2149fa8ad01f33c6390cc08626a185111631c8df495Cyril Hrubis	tst_brkm(TFAIL, tst_rmdir, "Test failed\n");
215ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
216