1c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee/* 2c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Copyright 2010 by Garmin Ltd. or its subsidiaries 3c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * 4c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Licensed under the Apache License, Version 2.0 (the "License"); 5c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * you may not use this file except in compliance with the License. 6c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * You may obtain a copy of the License at 7c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * 8c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * http://www.apache.org/licenses/LICENSE-2.0 9c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * 10c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Unless required by applicable law or agreed to in writing, software 11c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * distributed under the License is distributed on an "AS IS" BASIS, 12c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * See the License for the specific language governing permissions and 14c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * limitations under the License. 15c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * 16c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Performs a simple write/readback test to verify correct functionality 17c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * of direct i/o on a block device node. 18c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee */ 19c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 20c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee/* For large-file support */ 21c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#define _FILE_OFFSET_BITS 64 22c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#define _LARGEFILE_SOURCE 23c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#define _LARGEFILE64_SOURCE 24c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 25c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee/* For O_DIRECT */ 26c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#define _GNU_SOURCE 27c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 28c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#include <ctype.h> 29c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#include <errno.h> 30c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#include <fcntl.h> 318942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <inttypes.h> 328942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <limits.h> 338942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <stdint.h> 348942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <stdio.h> 358942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <stdlib.h> 368942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <string.h> 37c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#include <sys/ioctl.h> 38c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#include <sys/mman.h> 398942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <sys/stat.h> 408942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <sys/types.h> 418942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn#include <unistd.h> 42c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 43c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#include <linux/fs.h> 44c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 45c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee#define NUM_TEST_BLKS 128 46c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 47c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee/* 48c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Allocate page-aligned memory. Could use posix_memalign(3), but some 49c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * systems don't support it. Also pre-faults memory since we'll be using 50c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * it all right away anyway. 51c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee */ 52c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic void *pagealign_alloc(size_t size) 53c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 54c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee void *ret = mmap(NULL, size, PROT_READ | PROT_WRITE, 55c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_LOCKED, 56c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee -1, 0); 57c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (ret == MAP_FAILED) { 58c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("mmap"); 59c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ret = NULL; 60c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 61c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return ret; 62c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 63c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 64c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic void pagealign_free(void *addr, size_t size) 65c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 66c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int ret = munmap(addr, size); 67c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (ret == -1) 68c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("munmap"); 69c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 70c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 71c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic ssize_t do_read(int fd, void *buf, off64_t start, size_t count) 72c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 73c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ssize_t ret; 74c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee size_t bytes_read = 0; 75c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 76c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee lseek64(fd, start, SEEK_SET); 77c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 78c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee do { 79c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ret = read(fd, (char *)buf + bytes_read, count - bytes_read); 80c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (ret == -1) { 81c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("read"); 82c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return -1; 83c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } else if (ret == 0) { 84c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fprintf(stderr, "Unexpected end-of-file\n"); 85c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return -1; 86c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 87c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee bytes_read += ret; 88c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } while (bytes_read < count); 89c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 90c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return bytes_read; 91c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 92c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 93c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic ssize_t do_write(int fd, const void *buf, off64_t start, size_t count) 94c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 95c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ssize_t ret; 96c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee size_t bytes_out = 0; 97c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 98c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee lseek64(fd, start, SEEK_SET); 99c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 100c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee do { 101c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ret = write(fd, (char *)buf + bytes_out, count - bytes_out); 102c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (ret == -1) { 103c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("write"); 104c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return -1; 105c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } else if (ret == 0) { 106c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fprintf(stderr, "write returned 0\n"); 107c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return -1; 108c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 109c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee bytes_out += ret; 110c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } while (bytes_out < count); 111c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 112c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return bytes_out; 113c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 114c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 115c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee/* 116c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Initializes test buffer with locally-unique test pattern. High 16-bits of 117c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * each 32-bit word contain first disk block number of the test area, low 118c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * 16-bits contain word offset into test area. The goal is that a given test 119c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * area should never contain the same data as a nearby test area, and that the 120c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * data for a given test area be easily reproducable given the start block and 121c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * test area size. 122c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee */ 123c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic void init_test_buf(void *buf, uint64_t start_blk, size_t len) 124c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 125c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee uint32_t *data = buf; 126c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee size_t i; 127c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 128c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee len /= sizeof(uint32_t); 129c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee for (i = 0; i < len; i++) 130c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee data[i] = (start_blk & 0xFFFF) << 16 | (i & 0xFFFF); 131c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 132c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 133c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic void dump_hex(const void *buf, int len) 134c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 135c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee const uint8_t *data = buf; 136c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int i; 137c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee char ascii_buf[17]; 138c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 139c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ascii_buf[16] = '\0'; 140c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 141c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee for (i = 0; i < len; i++) { 142c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int val = data[i]; 143c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int off = i % 16; 144c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 145c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (off == 0) 146c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("%08x ", i); 147c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("%02x ", val); 148c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ascii_buf[off] = isprint(val) ? val : '.'; 149c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (off == 15) 150c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf(" %-16s\n", ascii_buf); 151c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 152c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 153c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee i %= 16; 154c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (i) { 155c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ascii_buf[i] = '\0'; 156c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee while (i++ < 16) 157c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf(" "); 158c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf(" %-16s\n", ascii_buf); 159c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 160c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 161c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 162c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheestatic void update_progress(int current, int total) 163c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 164c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee double pct_done = (double)current * 100 / total; 165c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("Testing area %d/%d (%6.2f%% complete)\r", current, total, 166c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee pct_done); 167c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fflush(stdout); 168c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 169c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 170c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheeint main(int argc, const char *argv[]) 171c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee{ 172c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int ret = 1; 173c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee const char *path; 174c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int fd; 175c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee struct stat stat; 176c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee void *read_buf = NULL, *write_buf = NULL; 177c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int blk_size; 178c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee uint64_t num_blks; 179c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee size_t test_size; 180c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee int test_areas, i; 181c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 182c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (argc != 2) { 183c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("Usage: directiotest blkdev_path\n"); 184c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee exit(1); 185c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 186c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 187c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee path = argv[1]; 188c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fd = open(path, O_RDWR | O_DIRECT | O_LARGEFILE); 189c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (fd == -1) { 190c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("open"); 191c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee exit(1); 192c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 193c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (fstat(fd, &stat) == -1) { 194c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("stat"); 195c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 196c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } else if (!S_ISBLK(stat.st_mode)) { 197c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fprintf(stderr, "%s is not a block device\n", path); 198c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 199c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 200c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 201c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (ioctl(fd, BLKSSZGET, &blk_size) == -1) { 202c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("ioctl"); 203c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 204c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 205c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (ioctl(fd, BLKGETSIZE64, &num_blks) == -1) { 206c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee perror("ioctl"); 207c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 208c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 209c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee num_blks /= blk_size; 210c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 211c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee test_size = (size_t)blk_size * NUM_TEST_BLKS; 212c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee read_buf = pagealign_alloc(test_size); 213c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee write_buf = pagealign_alloc(test_size); 214c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (!read_buf || !write_buf) { 215c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fprintf(stderr, "Error allocating test buffers\n"); 216c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 217c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 218c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 219c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee /* 220c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * Start the actual test. Go through the entire device, writing 221c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * locally-unique patern to each test block and then reading it 222c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee * back. 223c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee */ 224c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (num_blks / NUM_TEST_BLKS > INT_MAX) { 225c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("Warning: Device too large for test variables\n"); 226c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("Entire device will not be tested\n"); 227c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee test_areas = INT_MAX; 228c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } else { 229c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee test_areas = num_blks / NUM_TEST_BLKS; 230c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 231c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 232c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("Starting test\n"); 233c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 234c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee for (i = 0; i < test_areas; i++) { 235c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee uint64_t cur_blk = (uint64_t)i * NUM_TEST_BLKS; 236c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 237c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee update_progress(i + 1, test_areas); 238c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 239c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee init_test_buf(write_buf, cur_blk, test_size); 240c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 241c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (do_write(fd, write_buf, cur_blk * blk_size, test_size) != 242c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee (ssize_t)test_size) { 243c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fprintf(stderr, "write failed, aborting test\n"); 244c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 245c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 246c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (do_read(fd, read_buf, cur_blk * blk_size, test_size) != 247c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee (ssize_t)test_size) { 248c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee fprintf(stderr, "read failed, aborting test\n"); 249c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 250c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 251c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 252c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (memcmp(write_buf, read_buf, test_size)) { 2538942eef218b451ecb07fa01d3fde1ec681ad8932Mark Salyzyn printf("Readback verification failed at block %" PRIu64 "\n\n", 254c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee cur_blk); 255c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("Written data:\n"); 256c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee dump_hex(write_buf, test_size); 257c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("\nRead data:\n"); 258c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee dump_hex(read_buf, test_size); 259c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee goto cleanup; 260c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 261c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee } 262c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 263c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee printf("\nTest complete\n"); 264c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee ret = 0; 265c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee 266c610219fe9441f673e3aee12cf9479ae57feae25Seth Forsheecleanup: 267c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (read_buf) 268c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee pagealign_free(read_buf, test_size); 269c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee if (write_buf) 270c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee pagealign_free(write_buf, test_size); 271c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee close(fd); 272c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee return ret; 273c610219fe9441f673e3aee12cf9479ae57feae25Seth Forshee} 274