Esempio n. 1
0
static void do_child(void)
{
	int fd, offset;
	char buf[FS_BLOCKSIZE];
	char *addr = NULL;

	/*
	 * We have changed SIGBUS' handler in parent process by calling
	 * tst_sig(FORK, DEF_HANDLER, NULL), so here just restore it.
	 */
	if (signal(SIGBUS, SIG_DFL) == SIG_ERR)
		tst_brkm(TBROK | TERRNO, NULL, "signal(SIGBUS) failed");

	memset(buf, 'a', FS_BLOCKSIZE);
	fd = SAFE_OPEN(NULL, "testfilec", O_RDWR);
	SAFE_PWRITE(NULL, 1, fd, buf, FS_BLOCKSIZE, 0);

	/*
	 * In case mremap() may fail because that memory area can not be
	 * expanded at current virtual address(MREMAP_MAYMOVE is not set),
	 * we first do a mmap(page_size * 2) operation to reserve some
	 * free address space.
	 */
	addr = SAFE_MMAP(NULL, NULL, page_size * 2, PROT_WRITE | PROT_READ,
			 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, -1, 0);
	SAFE_MUNMAP(NULL, addr, page_size * 2);

	addr = SAFE_MMAP(NULL, addr, FS_BLOCKSIZE, PROT_WRITE | PROT_READ,
			 MAP_SHARED, fd, 0);

	addr[0] = 'a';

	SAFE_FTRUNCATE(NULL, fd, page_size * 2);
	addr = mremap(addr, FS_BLOCKSIZE, 2 * page_size, 0);
	if (addr == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, NULL, "mremap failed unexpectedly");

	/*
	 * Let parent process consume FS free blocks as many as possible, then
	 * there'll be no free blocks allocated for this new file mmaping for
	 * offset starting at 1024, 2048, or 3072. If this above kernel bug
	 * has been fixed, usually child process will killed by SIGBUS signal,
	 * if not, the data 'A', 'B', 'C' will be silently discarded later when
	 * kernel writepage is called, that means data corruption.
	 */
	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);
	TST_SAFE_CHECKPOINT_WAIT(NULL, 0);

	for (offset = FS_BLOCKSIZE; offset < page_size; offset += FS_BLOCKSIZE)
		addr[offset] = 'a';

	SAFE_MUNMAP(NULL, addr, 2 * page_size);
	SAFE_CLOSE(NULL, fd);
	exit(TFAIL);
}
Esempio n. 2
0
static void verify_pwritev2(unsigned int n)
{
	int i;
	char preadbuf[CHUNK];
	struct tcase *tc = &tcases[n];

	SAFE_PWRITE(1, fd, initbuf, sizeof(initbuf), 0);
	SAFE_LSEEK(fd, tc->seek_off, SEEK_SET);

	TEST(pwritev2(fd, wr_iovec, tc->count, tc->write_off, 0));
	if (TST_RET < 0) {
		tst_res(TFAIL | TTERRNO, "pwritev2() failed");
		return;
	}

	if (TST_RET != tc->size) {
		tst_res(TFAIL, "pwritev2() wrote %li bytes, expected %zi",
			 TST_RET, tc->size);
		return;
	}

	if (SAFE_LSEEK(fd, 0, SEEK_CUR) != tc->exp_off) {
		tst_res(TFAIL, "pwritev2() had changed file offset");
		return;
	}

	memset(preadbuf, 0, CHUNK);

	if (tc->write_off != -1)
		SAFE_PREAD(1, fd, preadbuf, tc->size, tc->write_off);
	else
		SAFE_PREAD(1, fd, preadbuf, tc->size, tc->seek_off);

	for (i = 0; i < tc->size; i++) {
		if (preadbuf[i] != 0x61)
			break;
	}

	if (i != tc->size) {
		tst_res(TFAIL, "buffer wrong at %i have %c expected 'a'",
			 i, preadbuf[i]);
		return;
	}

	tst_res(TPASS, "pwritev2() wrote %zi bytes successfully "
		 "with content 'a' expectedly ", tc->size);
}