Exemplo n.º 1
0
static void validate_file(const char *path, int number,
	uint64_t *ptr_ok, uint64_t *ptr_corrupted, uint64_t *ptr_changed,
	uint64_t *ptr_overwritten, uint64_t *ptr_size, int *ptr_read_all,
	struct timeval *ptr_dt, int progress)
{
	char *full_fn;
	const char *filename;
	const int num_int64 = SECTOR_SIZE >> 3;
	uint64_t sector[num_int64];
	FILE *f;
	int fd;
	size_t sectors_read;
	uint64_t expected_offset;
	int final_errno;
	struct timeval t1, t2;
	/* Progress time. */
	struct timeval pt1 = { .tv_sec = -1000, .tv_usec = 0 };

	*ptr_ok = *ptr_corrupted = *ptr_changed = *ptr_overwritten = 0;

	full_fn = full_fn_from_number(&filename, path, number);
	assert(full_fn);
	printf("Validating file %s ... %s", filename, progress ? BLANK : "");
	fflush(stdout);
#ifdef __CYGWIN__
	/* We don't need write access, but some kernels require that
	 * the file descriptor passed to fdatasync(2) to be writable.
	 */
	f = fopen(full_fn, "rb+");
#else
	f = fopen(full_fn, "rb");
#endif
	if (!f)
		err(errno, "Can't open file %s", full_fn);
	fd = fileno(f);
	assert(fd >= 0);

	/* If the kernel follows our advice, f3read won't ever read from cache
	 * even when testing small memory cards without a remount, and
	 * we should have a better reading-speed measurement.
	 */
	assert(!fdatasync(fd));
	assert(!posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED));

	/* Obtain initial time. */
	assert(!gettimeofday(&t1, NULL));
	/* Help the kernel to help us. */
	assert(!posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL));

	sectors_read = fread(sector, SECTOR_SIZE, 1, f);
	final_errno = errno;
	expected_offset = (uint64_t)number * GIGABYTES;
	while (sectors_read > 0) {
		uint64_t rn;
		int error_count, i;

		assert(sectors_read == 1);

		rn = sector[0];
		error_count = 0;
		for (i = 1; error_count <= TOLERANCE && i < num_int64; i++) {
			rn = random_number(rn);
			if (rn != sector[i])
				error_count++;
		}

		if (expected_offset == sector[0]) {
			if (error_count == 0)
				(*ptr_ok)++;
			else if (error_count <= TOLERANCE)
				(*ptr_changed)++;
			else
				(*ptr_corrupted)++;
		} else if (error_count <= TOLERANCE)
			(*ptr_overwritten)++;
		else
			(*ptr_corrupted)++;

		sectors_read = fread(sector, SECTOR_SIZE, 1, f);
		final_errno = errno;
		expected_offset += SECTOR_SIZE;

		if (progress) {
			struct timeval pt2;
			assert(!gettimeofday(&pt2, NULL));
			/* Avoid often printouts. */
			if (delay_ms(&pt1, &pt2) >= 200) {
				PRINT_STATUS(CLEAR);
				fflush(stdout);
				pt1 = pt2;
			}
		}
	}
	assert(!gettimeofday(&t2, NULL));
	update_dt(ptr_dt, &t1, &t2);

	*ptr_read_all = feof(f);
	*ptr_size = ftell(f);

	PRINT_STATUS(progress ? CLEAR : "");
	if (!*ptr_read_all) {
		assert(ferror(f));
		printf(" - NOT fully read due to \"%s\"",
			strerror(final_errno));
	}
	printf("\n");

	fclose(f);
	free(full_fn);
}

static void report(const char *prefix, uint64_t i)
{
	double f = (double) (i * SECTOR_SIZE);
	const char *unit = adjust_unit(&f);
	printf("%s %.2f %s (%" PRIu64 " sectors)\n", prefix, f, unit, i);
}
Exemplo n.º 2
0
int
add_dt(void *handle, dt_rec_t *addp)
{
	return (update_dt((dt_handle_t *)handle, NULL, addp));
}
Exemplo n.º 3
0
int
modify_dt(void *handle, const dt_rec_t *origp, dt_rec_t *newp)
{
	return (update_dt((dt_handle_t *)handle, origp, newp));
}
Exemplo n.º 4
0
int
delete_dt(void *handle, const dt_rec_t *delp)
{
	return (update_dt((dt_handle_t *)handle, delp, NULL));
}