⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtread.c

📁 Linux磁盘测试的源代码,测试磁盘的读写性能
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************** *									    * *			  COPYRIGHT (c) 1990 - 2004			    * *			   This Software Provided			    * *				     By					    * *			  Robin's Nest Software Inc.			    * *									    * * Permission to use, copy, modify, distribute and sell this software and   * * its documentation for any purpose and without fee is hereby granted,	    * * provided that the above copyright notice appear in all copies and that   * * both that copyright notice and this permission notice appear in the	    * * supporting documentation, and that the name of the author not be used    * * in advertising or publicity pertaining to distribution of the software   * * without specific, written prior permission.				    * *									    * * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 	    * * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN	    * * NO EVENT SHALL HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL   * * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR    * * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS  * * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF   * * THIS SOFTWARE.							    * *									    * ****************************************************************************//* * Module:	dtread.c * Author:	Robin T. Miller * * Description: *	Read routines for generic data test program. */#include "dt.h"#if !defined(_QNX_SOURCE)#  include <sys/file.h>#endif /* !defined(_QNX_SOURCE) */#include <sys/stat.h>/* * Modification History: * * February 13th, 2004 by Robin Miller. *      Factor in the file position when doing reverse I/O, to avoid * reading into that area (which is now deemed protected). * * November 17th, 2003 by Robin Miller. *	Breakup output to stdout or stderr, rather than writing * all output to stderr.  If output file is stdout ('-') or a log * file is specified, then all output reverts to stderr. * * October 8th, 2003 by Robin Miller. *	On AIX, accept ENXIO for I/O's pass EOF. * * March 4th, 2003 by Robin Miller. *      Add EOF support for older SunOS release.  This means reads * past EOF return EIO, but continue on this to find real capacity. * * November 20th, 2002 by Robin Miller. *	Updated FindCapacity() to expect ENXIO for reads past EOM. * * June 25th, 2001 by Robin Miller. *	Restructured code associated with Tru64 Unix EEI, so we obtain * the EEI status for all tape errors, not just EIO errors. * * January 28th, 2001 by Robin Miller. *	Allow FindCapacity() to be called prior to the file being opened * The device capacity is necessary early on for the new slices option. * * January 26th, 2001 by Robin Miller. *	Added support for reverse reading. * * January 24th, 2001 by Robin Miller. *	Add support for variable I/O requests sizes. * * January 14th, 2001 by Robin Miller. *	Added support for multiple volumes option. * * January 2nd, 2001 by Robin Miller. *	Remove check for block or character device in FindCapacity(), since * that check is already done in mainline code, so it's a duplicate check. * * December 30th, 2000 by Robin Miller. *	Make changes to build using MKS/NuTCracker product. * * October 2nd, 2000 by Robin Miller. *	Update FindCapacity() to accept ENXIO for reads at EOM on * SCO UnixWare systems. * * April 2nd, 2000 by Robin Miller. *	Updated FindCapacity(): printf -> Fprintf so messages go to * log file, and add/change casts on large_t values (nothing big :-). * * March 28th, 2000 by Robin Miller. *	Modified calls to file position functions which now accept a * device information parameter. * * March 27th, 2000 by Robin Miller. *	Modified FindCapacity() to continue on read() errors, to handle * broken Linux ATAPI (IDE) driver, which returns EIO on errors past the * end of media (damn!). * * February 18th, 2000 by Robin Miller. *	Fix a problem where the records read value was not updated * when the data limit was reached first. * * February 17th, 2000 by Robin Miller. *	Adding better support for multi-volume tape testing.  Mainly, * make it work with writing multiple tape files, rather than one file. * * January 17th, 2000 by Robin Miller. *	Added checks @ EOF with/multi-volume enabled, so Copy/Verify * operations properly prompt for the next volume.  This allows 'dt' * to be used as a general purpose multi-volume tool w/other utilities. * * January 6th, 2000 by Robin Miller. *	Added support for multi-volume media. * * December 30th, 1999 by Robin Miller. *	Modify call to do_random() to pass the transfer size. *	Fix lbdata problem when using step option (wrong lba). * * August 6th, 1999 by Robin Miller. *      Better parameterizing of "long long" printf formatting. * * July 22nd, 1999 by Robin Miller. *	Added support for IOT (DJ's) test pattern. *  * May 27, 1999 by Robin Miller. *	Adding support for micro-second delays. * * March 1, 1999 by Robin Miller. *	For tapes when Debug is enabled, report the file number. * * December 21, 1998 by Robin Miller. *	Add hooks to handle tape device resets (DUNIX specific). * * October 29, 1998 by Robin Miller. *	Implement a random I/O data limit, instead of using the normal * data limit variable (not good to dual purpose this value). * * October 26, 1998 by Robin Miller. *	When random I/O and lbdata options are both enabled, use the * file offset seeked to as the starting lbdata address. * * April 28, 1998 by Robin Miller. *	For WIN32/NT, or in O_BINARY into open flags to force binary *	mode (the default is text mode). * * February 29, 1996 by Robin Miller. *	Added FindCapacity() function to obtain capacity for random *	access devices.  Must set limits for random I/O. * * February 28, 1996 by Robin Miller. *	Added support for copying and verifying device/files. *	Modified logic so read errors honor users' error limit. * * February 23, 1996 by Robin Miller. *	Only report partial record warning for sequential I/O testing. *	Random I/O can position us towards the end of media often, and *	partial transfers are likely especially with large block sizes. * * November 11, 1995 by Robin Miller. *	Fix bug with init'ing and performing pad byte verification. *	This caused variable length reads with small increment values *	to report an (invalid) pad byte data compare error. e.g.: * *	% dt of=/dev/rmt0h min=10k max=64k incr=1 pattern=incr * * July 15, 1995 by Robin Miller. *	Fix end of media error handling (ENOSPC), and cleanup code. * * January 20, 1994 by Robin Miller. *	When initializing the data buffer, don't do the entire buffer since * init'ing large buffer (e.g. 100m) using min, max, and incr options cause * excessive paging and VERY poor performance. * * September 17, 1993 by Robin Miller. *	Report record number on warning errors (for debug). * * September 4, 1993 by Robin Miller. *	Moved memory mapped I/O logic to seperate module. * * Septemeber 1, 1993 by Robin Miller. *	Add ability to read variable record sizes. * * August 31, 1993 by Robin Miller. *	Rotate starting data buffer address through sizeof(long). * * August 27, 1993 by Robin MIller. *	Added support for DEC OSF/1 POSIX Asynchronous I/O (AIO). * * August 18, 1992 by Robin Miller. *	If "step=" option was specified, then seek that many bytes *	before the next read request (for disks). * * August 10, 1993 by Robin Miller. *	Added initializing and checking of buffer pad bytes to ensure *	data corruption does *not* occur at the end of read buffers. * * August 5, 1993 by Robin Miller. *	Added support for reading multiple tape files. * * September 11, 1992 by Robin Miller. *	Ensure data limit specified by user is not exceeded, incase *	the block size isn't modulo the data limit. * * September 5, 1992 by Robin Miller. *	Initial port to QNX 4.1 Operating System. * * August 21, 1990 by Robin Miller. *	Changed exit status so scripts can detect and handle errors *	based on the exit code.  If not success, fatal error, or end *	of file/tape, the exit code is the error number (errno). * * August 7, 1990 by Robin Miller. *	If "seek=n" option is specified, then seek that many records *	before starting to read.  The "skip=n" option skips records *	by reading, while "seek=n" seeks past records. *//************************************************************************ *									* * read_data() - Read and optionally verify data read.			* *									* * Inputs:	dip = The device information pointer.			* *									* * Outputs:	Returns SUCCESS/FAILURE = Ok/Error.			* *									* ************************************************************************/intread_data (struct dinfo *dip){    register ssize_t count;    register size_t bsize, dsize;    int status = SUCCESS;    struct dtfuncs *dtf = dip->di_funcs;    u_int32 lba;    /*     * For variable length records, initialize to minimum record size.     */    if (min_size) {	dsize = min_size;    } else {	dsize = block_size;    }    if (dip->di_random_access) {	if (io_dir == REVERSE) {	    (void)set_position(dip, (off_t)rdata_limit);	}	lba = get_lba(dip);	dip->di_offset = get_position(dip);    } else {	lba = make_lbdata (dip, dip->di_offset);    }    /*     * Now read and optionally verify the input records.     */    while ( (error_count < error_limit) &&	    (dip->di_fbytes_read < data_limit) &&	    (dip->di_records_read < record_limit) ) {	if (volumes_flag && (multi_volume >= volume_limit) &&		  (dip->di_volume_records >= volume_records)) {	    break;	}	if (rdelay_count) {			/* Optional read delay.	*/	    mySleep (rdelay_count);	}	/*	 * If data limit was specified, ensure we don't exceed it.	 */	if ( (dip->di_fbytes_read + dsize) > data_limit) {	    bsize = (size_t)(data_limit - dip->di_fbytes_read);	} else {	    bsize = dsize;	}	if (io_dir == REVERSE) {	    bsize = MIN((dip->di_offset-file_position), bsize);	    dip->di_offset = set_position(dip, (off_t)(dip->di_offset - bsize));	} else if (io_type == RANDOM_IO) {	    dip->di_offset = do_random (dip, TRUE, bsize);	}        if (debug_flag && (bsize != dsize) && !variable_flag) {            Printf ("Record #%lu, Reading a partial record of %lu bytes...\n",                                    (dip->di_records_read + 1), bsize);        }	if (iot_pattern || lbdata_flag) {	    lba = make_lbdata (dip, (off_t)(dip->di_volume_bytes + dip->di_offset));	}	/*	 * If requested, rotate the data buffer through ROTATE_SIZE bytes	 * to force various unaligned buffer accesses.	 */	if (rotate_flag) {	    data_buffer = (base_buffer + (rotate_offset++ % ROTATE_SIZE));	}	/*	 * If we'll be doing a data compare after the read, then	 * fill the data buffer with the inverted pattern to ensure	 * the buffer actually gets written into (driver debug mostly).	 */	if ((io_mode == TEST_MODE) && compare_flag) {	    init_buffer (data_buffer, bsize, ~pattern);	    init_padbytes (data_buffer, bsize, ~pattern);	    if (iot_pattern) {		lba = init_iotdata (bsize, lba, lbdata_size);	    }	}	if (Debug_flag) {	    u_int32 iolba = NO_LBA;	    if (dip->di_random_access) {		iolba = (get_position(dip) / dip->di_dsize);	    } else if (lbdata_flag || iot_pattern) {		iolba = make_lbdata (dip, (off_t)(dip->di_volume_bytes + dip->di_offset));	    }	    report_record(dip, (dip->di_files_read + 1), (dip->di_records_read + 1),				iolba, READ_MODE, data_buffer, bsize);	}	count = read_record (dip, data_buffer, bsize, dsize, &status);	if (end_of_file) break;		/* Stop reading at end of file. */	if (status == FAILURE) {	    if (error_count >= error_limit) break;	} else if (io_mode == COPY_MODE) {	    status = copy_record (output_dinfo, data_buffer, count);	    if ( (error_count >= error_limit) || end_of_file) break;	} else if (io_mode == VERIFY_MODE) {	    status = verify_record (output_dinfo, data_buffer, count);	    if ( (error_count >= error_limit) || end_of_file) break;	}	/*	 * Verify the data (unless disabled).	 */	if ( (status != FAILURE) && compare_flag && (io_mode == TEST_MODE) ) {	    ssize_t vsize = count;	    status = (*dtf->tf_verify_data)(dip, data_buffer, vsize, pattern, &lba);	    /*	     * Verify the pad bytes (if enabled).	     */	    if ( (status == SUCCESS) && pad_check) {		(void) verify_padbytes (dip, data_buffer, vsize, ~pattern, bsize);	    }	}	/*	 * If we had a partial transfer, perhaps due to an error, adjust	 * the logical block address in preparation for the next request.	 */	if (iot_pattern && ((size_t)count < bsize)) {	    size_t resid = (bsize - count);	    lba -= howmany(resid, lbdata_size);	}	/*	 * For variable length records, adjust the next record size.	 */	if (min_size) {	    if (variable_flag) {		dsize = get_variable (dip);	    } else {		dsize += incr_count;	        if (dsize > max_size) dsize = min_size;	    }	}	dip->di_records_read++;	dip->di_volume_records++;	if (io_dir == FORWARD) {	    dip->di_offset += count;	/* Maintain our own position too! */	} else if ( (io_type == SEQUENTIAL_IO) &&		    (dip->di_offset == (off_t) file_position) ) {	    set_Eof(dip);	    break;	}	if (step_offset) {	    if (io_dir == FORWARD) {		dip->di_offset = incr_position (dip, step_offset);	    } else if ((dip->di_offset -= step_offset) <= (off_t) file_position) {		set_Eof(dip);		break;	    }	}    }    return (status);}/************************************************************************ *									* * check_read() - Check status of last read operation.			* *									* * Inputs:	dip = The device information pointer.			* *		count = Number of bytes read.				* *		size  = Number of bytes expected.			* *									* * Outputs:	Returns SUCCESS/FAILURE/WARNING = Ok/Error/Warning	* *									* ************************************************************************/intcheck_read (struct dinfo *dip, ssize_t count, size_t size){    int status = SUCCESS;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -