Example #1
0
static void dotest(int testers, int me, int fd)
{
	char *bits, *buf;
	char val, val0;
	int count, collide, chunk, whenmisc, xfr, i;

	/* Stuff for the readv call */
	struct iovec r_iovec[MAXIOVCNT];
	int r_ioveclen;

	/* Stuff for the writev call */
	struct iovec val0_iovec[MAXIOVCNT];
	struct iovec val_iovec[MAXIOVCNT];
	int w_ioveclen;

	nchunks = max_size / (testers * csize);
	whenmisc = 0;

	if ((bits = malloc((nchunks + 7) / 8)) == NULL) {
		tst_resm(TBROK, "\tmalloc failed(bits)");
		tst_exit();
	}

	if ((buf = (malloc(csize))) == NULL) {
		tst_resm(TBROK, "\tmalloc failed(buf)");
		tst_exit();
	}

	/* Allocate memory for the iovec buffers and init the iovec arrays */
	r_ioveclen = w_ioveclen = csize / MAXIOVCNT;

	/* Please note that the above statement implies that csize
	 * be evenly divisible by MAXIOVCNT.
	 */
	for (i = 0; i < MAXIOVCNT; i++) {
		if ((r_iovec[i].iov_base = malloc(r_ioveclen)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(iov_base)");
			tst_exit();
		}
		r_iovec[i].iov_len = r_ioveclen;

		/* Allocate unused memory areas between all the buffers to
		 * make things more diffult for the OS.
		 */
		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}

		if ((val0_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(val0_iovec)");
			tst_exit();
		}

		val0_iovec[i].iov_len = w_ioveclen;

		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}

		if ((val_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(iov_base)");
			tst_exit();
		}
		val_iovec[i].iov_len = w_ioveclen;

		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(((i+1)*8)");
			tst_exit();
		}
	}

	/*
	 * No init sectors; file-sys makes 0 to start.
	 */
	val = (64 / testers) * me + 1;
	val0 = 0;

	/*
	 * For each iteration:
	 *      zap bits array
	 *      loop:
	 *              pick random chunk, read it.
	 *              if corresponding bit off {
	 *                      verify == 0. (sparse file)
	 *                      ++count;
	 *              } else
	 *                      verify == val.
	 *              write "val" on it.
	 *              repeat until count = nchunks.
	 *      ++val.
	 */
	srand(getpid());

	if (misc_intvl)
		whenmisc = NEXTMISC;

	while (iterations-- > 0) {
		for (i = 0; i < NMISC; i++)
			misc_cnt[i] = 0;
		memset(bits, 0, (nchunks + 7) / 8);
		/* Have to fill the val0 and val iov buffers in a different manner
		 */
		for (i = 0; i < MAXIOVCNT; i++) {
			memset(val0_iovec[i].iov_base, val0,
			       val0_iovec[i].iov_len);
			memset(val_iovec[i].iov_base, val,
			       val_iovec[i].iov_len);

		}

		count = 0;
		collide = 0;

		while (count < nchunks) {
			chunk = rand() % nchunks;
			/*
			 * Read it.
			 */
			if (lseek64(fd, CHUNK(chunk), 0) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: lseek64(0) fail at %"
					 PRIx64 "x, errno = %d.", me,
					 CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: readv fail at %" PRIx64
					 "x, errno = %d.", me, CHUNK(chunk),
					 errno);
				tst_exit();
			}
			/*
			 * If chunk beyond EOF just write on it.
			 * Else if bit off, haven't seen it yet.
			 * Else, have.  Verify values.
			 */
			if (xfr == 0) {
				bits[chunk / 8] |= (1 << (chunk % 8));
			} else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) {
				if (xfr != csize) {
					tst_resm(TFAIL,
						 "\tTest[%d]: xfr=%d != %d, zero read.",
						 me, xfr, csize);
					tst_exit();
				}
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp
					    (r_iovec[i].iov_base,
					     val0_iovec[i].iov_base,
					     r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
							 "\tTest[%d] bad verify @ 0x%"
							 PRIx64
							 " for val %d count %d xfr %d.",
							 me, CHUNK(chunk), val0,
							 count, xfr);
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits,
							    (nchunks + 7) / 8);
						tst_exit();
					}
				}
				bits[chunk / 8] |= (1 << (chunk % 8));
				++count;
			} else {
				if (xfr != csize) {
					tst_resm(TFAIL,
						 "\tTest[%d]: xfr=%d != %d, val read.",
						 me, xfr, csize);
					tst_exit();
				}
				++collide;
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp
					    (r_iovec[i].iov_base,
					     val_iovec[i].iov_base,
					     r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
							 "\tTest[%d] bad verify @ 0x%"
							 PRIx64
							 " for val %d count %d xfr %d.",
							 me, CHUNK(chunk), val,
							 count, xfr);
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits,
							    (nchunks + 7) / 8);
						tst_exit();
					}
				}
			}
			/*
			 * Write it.
			 */
			if (lseek64(fd, -xfr, 1) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: lseek64(1) fail at %"
					 PRIx64 ", errno = %d.", me,
					 CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr =
			     writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
				if (errno == ENOSPC) {
					tst_resm(TFAIL,
						 "\tTest[%d]: no space, exiting.",
						 me);
					fsync(fd);
					tst_exit();
				}
				tst_resm(TFAIL,
					 "\tTest[%d]: writev fail at %" PRIx64
					 "x xfr %d, errno = %d.", me,
					 CHUNK(chunk), xfr, errno);
				tst_exit();
			}
			/*
			 * If hit "misc" interval, do it.
			 */
			if (misc_intvl && --whenmisc <= 0) {
				domisc(me, fd);
				whenmisc = NEXTMISC;
			}
			if (count + collide > 2 * nchunks)
				break;
		}

		/*
		 * End of iteration, maybe before doing all chunks.
		 */

		if (count < nchunks) {
			//tst_resm(TINFO, "\tTest{%d} val %d stopping @ %d, collide = {%d}.",
			//              me, val, count, collide);
			for (i = 0; i < nchunks; i++) {
				if ((bits[i / 8] & (1 << (i % 8))) == 0) {
					if (lseek64(fd, CHUNK(i), 0) <
					    (off64_t) 0) {
						tst_resm(TFAIL,
							 "\tTest[%d]: lseek64 fail at %"
							 PRIx64
							 "x, errno = %d.", me,
							 CHUNK(i), errno);
						tst_exit();
					}
					if (writev(fd, &val_iovec[0], MAXIOVCNT)
					    != csize) {
						tst_resm(TFAIL,
							 "\tTest[%d]: writev fail at %"
							 PRIx64
							 "x, errno = %d.", me,
							 CHUNK(i), errno);
						tst_exit();
					}
				}
			}
		}

		fsync(fd);
		++misc_cnt[m_fsync];
		//tst_resm(TINFO, "\tTest[%d] val %d done, count = %d, collide = %d.",
		//              me, val, count, collide);
		//for (i = 0; i < NMISC; i++)
		//      tst_resm(TINFO, "\t\tTest[%d]: %d %s's.", me, misc_cnt[i], m_str[i]);
		val0 = val++;
	}
}
Example #2
0
static void dotest(int testers, int me, int fd)
{
	char *bits, *hold_bits;
	char val;
	int chunk, whenmisc, xfr, count, collide, i;

	/* Stuff for the readv call */
	struct iovec r_iovec[MAXIOVCNT];
	int r_ioveclen;

	/* Stuff for the writev call */
	struct iovec val_iovec[MAXIOVCNT];
	struct iovec zero_iovec[MAXIOVCNT];
	int w_ioveclen;

	nchunks = max_size / csize;
	whenmisc = 0;

	if ((bits = malloc((nchunks + 7) / 8)) == 0) {
		tst_resm(TBROK, "\tmalloc failed");
		tst_exit();
	}

	if ((hold_bits = malloc((nchunks + 7) / 8)) == 0) {
		tst_resm(TBROK, "\tmalloc failed");
		tst_exit();
	}

	/*Allocate memory for the iovec buffers and init the iovec arrays */
	r_ioveclen = w_ioveclen = csize / MAXIOVCNT;

	/* Please note that the above statement implies that csize
	 * be evenly divisible by MAXIOVCNT.
	 */
	for (i = 0; i < MAXIOVCNT; i++) {
		if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == 0) {
			tst_brkm(TBROK, NULL, "\tmalloc failed");
			/* tst_exit(); */
		}
		r_iovec[i].iov_len = r_ioveclen;

		/* Allocate unused memory areas between all the buffers to
		 * make things more diffult for the OS.
		 */
		if (malloc((i + 1) * 8) == NULL) {
			tst_brkm(TBROK, NULL, "\tmalloc failed");
		}

		if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == 0) {
			tst_resm(TBROK, "\tmalloc failed");
			tst_exit();
		}

		val_iovec[i].iov_len = w_ioveclen;

		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed");
			tst_exit();
		}

		if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == 0) {
			tst_resm(TBROK, "\tmalloc failed");
			tst_exit();
		}

		zero_iovec[i].iov_len = w_ioveclen;

		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed");
			tst_exit();
		}
	}
	/*
	 * No init sectors; allow file to be sparse.
	 */
	val = (64 / testers) * me + 1;

	/*
	 * For each iteration:
	 *      zap bits array
	 *      loop
	 *              pick random chunk, read it.
	 *              if corresponding bit off {
	 *                      verify = 0. (sparse file)
	 *                      ++count;
	 *              } else
	 *                      verify = val.
	 *              write "val" on it.
	 *              repeat unitl count = nchunks.
	 *      ++val.
	 */

	srand(getpid());

	if (misc_intvl)
		whenmisc = NEXTMISC;

	while (iterations-- > 0) {

		for (i = 0; i < NMISC; i++)
			misc_cnt[i] = 0;

		ftruncate(fd, 0);
		file_max = 0;
		memset(bits, 0, (nchunks + 7) / 8);
		memset(hold_bits, 0, (nchunks + 7) / 8);

		/* Have to fill the val and zero iov buffers in a different manner
		 */
		for (i = 0; i < MAXIOVCNT; i++) {
			memset(val_iovec[i].iov_base, val,
			       val_iovec[i].iov_len);
			memset(zero_iovec[i].iov_base, 0,
			       zero_iovec[i].iov_len);

		}

		count = 0;
		collide = 0;

		while (count < nchunks) {
			chunk = rand() % nchunks;
			/*
			 * Read it.
			 */
			if (lseek(fd, CHUNK(chunk), 0) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: lseek(0) fail at %x, errno = %d.",
					 me, CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: readv fail at %x, errno = %d.",
					 me, CHUNK(chunk), errno);
				tst_exit();
			}
			/*
			 * If chunk beyond EOF just write on it.
			 * Else if bit off, haven't seen it yet.
			 * Else, have.  Verify values.
			 */
			if (CHUNK(chunk) >= file_max) {
				bits[chunk / 8] |= (1 << (chunk % 8));
				++count;
			} else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) {
				if (xfr != csize) {
					tst_resm(TFAIL,
						 "\tTest[%d]: xfr=%d != %d, zero read.",
						 me, xfr, csize);
					tst_exit();
				}
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp
					    (r_iovec[i].iov_base,
					     zero_iovec[i].iov_base,
					     r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
							 "\tTest[%d] bad verify @ 0x%x for val %d count %d xfr %d file_max 0x%x, should be 0.",
							 me, CHUNK(chunk), val,
							 count, xfr, file_max);
						tst_resm(TINFO,
							 "\tTest[%d]: last_trunc = 0x%x.",
							 me, last_trunc);
						sync();
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits,
							    (nchunks + 7) / 8);
						ft_orbits(hold_bits, bits,
							  (nchunks + 7) / 8);
						tst_resm(TINFO, "\tHold ");
						ft_dumpbits(hold_bits,
							    (nchunks + 7) / 8);
						tst_exit();
					}
				}
				bits[chunk / 8] |= (1 << (chunk % 8));
				++count;
			} else {
				if (xfr != csize) {
					tst_resm(TFAIL,
						 "\tTest[%d]: xfr=%d != %d, val read.",
						 me, xfr, csize);
					tst_exit();
				}
				++collide;
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp
					    (r_iovec[i].iov_base,
					     val_iovec[i].iov_base,
					     r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
							 "\tTest[%d] bad verify @ 0x%x for val %d count %d xfr %d file_max 0x%x.",
							 me, CHUNK(chunk), val,
							 count, xfr, file_max);
						tst_resm(TINFO,
							 "\tTest[%d]: last_trunc = 0x%x.",
							 me, last_trunc);
						sync();
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits,
							    (nchunks + 7) / 8);
						ft_orbits(hold_bits, bits,
							  (nchunks + 7) / 8);
						tst_resm(TINFO, "\tHold ");
						ft_dumpbits(hold_bits,
							    (nchunks + 7) / 8);
						tst_exit();
					}
				}
			}
			/*
			 * Writev it.
			 */
			if (lseek(fd, -xfr, 1) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: lseek(1) fail at %x, errno = %d.",
					 me, CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr =
			     writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
				if (errno == ENOSPC) {
					tst_resm(TFAIL,
						 "\tTest[%d]: no space, exiting.",
						 me);
					fsync(fd);
					tst_exit();
				}
				tst_resm(TFAIL,
					 "\tTest[%d]: writev fail at %x xfr %d, errno = %d.",
					 me, CHUNK(chunk), xfr, errno);
				tst_exit();
			}
			if (CHUNK(chunk) + csize > file_max)
				file_max = CHUNK(chunk) + csize;
			/*
			 * If hit "misc" interval, do it.
			 */
			if (misc_intvl && --whenmisc <= 0) {
				ft_orbits(hold_bits, bits, (nchunks + 7) / 8);
				domisc(me, fd, bits);
				whenmisc = NEXTMISC;
			}
			if (count + collide > 2 * nchunks)
				break;
		}

		/*
		 * End of iteration, maybe before doing all chunks.
		 */

		fsync(fd);
		++misc_cnt[m_fsync];
		//tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}",
		//              me, val, count, collide);
		//for (i = 0; i < NMISC; i++)
		//      tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]);
		++val;
	}
}