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

📄 dtread.c

📁 Linux磁盘测试的源代码,测试磁盘的读写性能
💻 C
📖 第 1 页 / 共 2 页
字号:
    if ((size_t)count != size) {	if (count == FAILURE) {	    report_error ("read", FALSE);	    ReportDeviceInfo (dip, 0, 0, (bool)(errno == EIO));	} else {	    /*	     * For reads at end of file or reads at end of block	     * devices, we'll read less than the requested count.	     * In this case, we'll treat this as a warning since	     * this is to be expected.  In the case of tape, the	     * next read will indicate end of tape (in my driver).	     *	     * NOTE:  The raw device should be used for disks.	     */	    if ( (debug_flag || verbose_flag || ((size_t)count > size)) &&		 (io_mode == TEST_MODE) /*&& (io_type == SEQUENTIAL_IO)*/ ) {		Printf(	"WARNING: Record #%lu, attempted to read %lu bytes, read only %lu bytes.\n",						(dip->di_records_read + 1), size, count);	    }	    if ((size_t)count < size) {	/* Partial read is a warning. */		warning_errors++;		return (WARNING);	    }	    ReportDeviceInfo (dip, count, 0, FALSE);	}	(void)RecordError();	dip->di_read_errors++;	status = FAILURE;    }    return (status);}/* * This function is envoked when reading multiple tape files, to * position past an expected file mark.  This is especially important * when using the lbdata or iot options, since encountering an expected * EOF throws off the offset being maintained, resulting in an lba error. */intread_eof(struct dinfo *dip){    ssize_t count;    size_t bsize = block_size;    int status = SUCCESS;    if (debug_flag) {	Printf("Processing end of file... [file #%lu, record #%lu]\n",			(dip->di_files_read + 1), (dip->di_records_read + 1));    }    dip->di_eof_processing = TRUE;    count = read_record (dip, data_buffer, bsize, bsize, &status);    dip->di_eof_processing = FALSE;    if (!end_of_file) {	Fprintf("ERROR: File %lu, Record %lu, expected EOF was NOT detected!\n",		(dip->di_files_read + 1), (dip->di_records_read + 1));	ReportDeviceInfo (dip, count, 0, FALSE);	(void)RecordError();	dip->di_read_errors++;	status = FAILURE;    }    return (status);}/* * This function is called after EOF is detected, to read the next record * which checks for reaching the end of logical tape (i.e. two successive * file marks).  For multi-volume tapes, the user will be prompted for the * next volume via read_record(), and the end of file flag gets reset when * the tape is re-open'ed. */intread_eom(struct dinfo *dip){    ssize_t count;    size_t bsize = block_size;    int status = SUCCESS;    if (debug_flag) {	Printf("Processing end of media... [file #%lu, record #%lu]\n",			(dip->di_files_read + 1), (dip->di_records_read + 1));    }    dip->di_eom_processing = TRUE;    count = read_record (dip, data_buffer, bsize, bsize, &status);    dip->di_eom_processing = FALSE;    if (multi_flag) {	if (end_of_file) {	    Fprintf("ERROR: File %lu, Record %lu, expected EOM was NOT detected!\n",			(dip->di_files_read + 1), (dip->di_records_read + 1));	    ReportDeviceInfo (dip, count, 0, FALSE);	    (void)RecordError();	    return (FAILURE);	}    } else if ( !dip->di_end_of_logical ) {	Fprintf("ERROR: File %lu, Record %lu, expected EOM was NOT detected!\n",		(dip->di_files_read + 1), (dip->di_records_read + 1));	ReportDeviceInfo (dip, count, 0, FALSE);	(void)RecordError();	dip->di_read_errors++;	return (FAILURE);    }    return (SUCCESS);	/* We don't care about the read status! */}/************************************************************************ *									* * read_record() - Read record from device or file.			* *									* * Inputs:	dip = The device information pointer.			* *		buffer = The data buffer to read into.			* *		bsize = The number of bytes read.			* *		dsize = The users' requested size.			* *		status = Pointer to status variable.			* *									* * Outputs:	status = SUCCESS/FAILURE/WARNING = Ok/Error/Warning	* *		Return value is number of bytes from read() request.	* *									* ************************************************************************/ssize_tread_record (	struct dinfo	*dip,		u_char		*buffer,		size_t		bsize,		size_t		dsize,		int		*status ){    ssize_t count;retry:    *status = SUCCESS;    count = read (dip->di_fd, buffer, bsize);#if defined(EEI)    if ( (count == FAILURE) &&	 (dip->di_dtype->dt_dtype == DT_TAPE) ) {	if ( (errno == EIO) && eei_resets) {	    if ( HandleTapeResets(dip) ) {		goto retry;	    }	} else if (eei_flag) {	    (void) get_eei_status(dip->di_fd, dip->di_mt);	}    }#endif /* defined(EEI) */    /*     * Allow terminal reads to continue on end of file (eof).     * [ NOTE: This allows reads with timeouts to continue. ]     */    if ( count || (dip->di_dtype->dt_dtype != DT_TERMINAL) ) {	if ( is_Eof (dip, count, status) ) {	    if (multi_flag &&		(!stdin_flag || (dip->di_ftype == OUTPUT_FILE)) ) {		if ( (dip->di_dtype->dt_dtype == DT_TAPE) &&		     !dip->di_end_of_logical ) {		    return (count);	/* Expect two file marks @ EOM. */		}		*status = HandleMultiVolume (dip);		dip->di_offset = (off_t) 0;		if ( !dip->di_eof_processing && !dip->di_eom_processing ) {		    if (*status == SUCCESS) goto retry;		}	    }	    return (count);	/* Stop reading at end of file. */	}    }    if ( dip->di_eof_processing || dip->di_eom_processing ) {	return (count);    }    dip->di_end_of_file = FALSE;	/* Reset saved end of file state. */    /*     * If something was read, adjust counts and statistics.     */    if (count > (ssize_t) 0) {	dip->di_dbytes_read += count;	dip->di_fbytes_read += count;	dip->di_vbytes_read += count;	if ((size_t)count == dsize) {	    records_processed++;	} else {	    partial_records++;	}    }    *status = check_read (dip, count, bsize);    return (count);}/************************************************************************ *									* * verify_record() - Verify record with selected output device/file.	* *									* * Inputs:	dip = The device information pointer.			* *		buffer = The data buffer to compare.			* *		bsize = The number of bytes read.			* *									* * Outputs:	Returns SUCCESS/FAILURE/WARNING = Ok/Error/Warning	* *									* ************************************************************************/intverify_record (	struct dinfo	*dip,		u_char		*buffer,		size_t		bsize ){    struct dtfuncs *dtf = dip->di_funcs;    ssize_t count;    int status;    u_int32 lba = lbdata_addr;    /*     * TODO: Re-write this using the verify buffer (when I have time).     */    count = read_record (dip, pattern_buffer, bsize, bsize, &status);    if ( (status == FAILURE) || end_of_file) return (status);    /*     * I realize this is real ugly, but I wanted to use existing code.     */    patbuf_size = count;    pattern_bufptr = pattern_buffer;    pattern_bufend = pattern_buffer + count;    status = (*dtf->tf_verify_data)(dip, buffer, count, pattern, &lba);    /* TODO: Get this into read_record() where it belongs! */    dip->di_records_read++;    return (status);}/************************************************************************ *									* * FindCapacity() - Find capacity of a random access device.		* *									* * Inputs:	dip = The device information pointer.			* *									* * Outputs:	Fills in device capacity and data limit on success.	* *									* * Return Value: Returns SUCCESS/FAILURE/WARNING = Ok/Error/Warning	* *									* ************************************************************************/intFindCapacity (struct dinfo *dip){    u_int32 dsize = dip->di_dsize;    off_t lba, max_seek = (MAX_SEEK - dsize);    long adjust = ((250 * MBYTE_SIZE) / dsize);    int attempts = 0;    ssize_t count, last;    u_char *buffer;    int fd, saved_fd = NoFd, status = SUCCESS;    bool temp_fd = FALSE;    /*     * Use the user specified capacity (if specified).     */    if (user_capacity) {	lba = (off_t)(user_capacity / dsize);	goto set_capacity;    } else if (dip->di_data_limit) {	return (status);    }    if (debug_flag || Debug_flag || rDebugFlag) {	Printf ("Attempting to calculate capacity via seek/read algorithm...\n");    }    /*     * If the device is open in write mode, open another     * file descriptor for reading.     */    if ( (dip->di_fd == NoFd) || (dip->di_mode == WRITE_MODE) ) {	temp_fd = TRUE;	saved_fd = dip->di_fd;#if defined(__WIN32__)	if ( (fd = open (dip->di_dname, (O_RDONLY|O_BINARY))) < 0) {#else /* !defined(__WIN32__) */	if ( (fd = open (dip->di_dname, O_RDONLY)) < 0) {#endif /* defined(__WIN32__) */	    report_error ("FindCapacity() open", FALSE);	    return (FAILURE);	}	dip->di_fd = fd;    }    buffer = (u_char *) malloc (dsize);    if (buffer == NULL) return (FAILURE);    /*     * Algorthim:     *	There maybe a better may, but this works...     */    lba = adjust;    adjust /= 2;    while (TRUE) {	attempts++;#if defined(DEBUG)	Printf("lba = " LUF ", adjust = %lu\n", lba, adjust);#endif	/*	 * We cannot seek past the maximum allowable file position,	 * otherwise lseek() fails, and 'dt' exits.  So, we must	 * limit seeks appropriately, and break out of this loop	 * if we hit the upper seek limit.	 */	if ( (off_t)(lba * dsize) < (off_t) 0 ) {	    lba = (max_seek / dsize);	}	(void) set_position (dip, (off_t)(lba * dsize));	if ( (count = read (dip->di_fd, buffer, dsize)) == (ssize_t)dsize) {	    if (lba == (off_t)(max_seek / dsize)) break;	    lba += adjust;	    if (adjust == 1) break;#if defined(SCO) || defined(HP_UX) || defined(AIX)	} else if ( (count == 0) ||		    ( (count < 0) &&		      ((errno == ENOSPC) || (errno == ENXIO)) ) ) {#elif defined(BrokenEOF)	} else if ( (count == 0) ||		    ( (count < 0) &&		      ((errno == ENOSPC) || (errno == EIO)) ) ) {#else /* !defined(SCO) */	} else if ( (count == 0) ||		    ( (count < 0) && (errno == ENOSPC) ) ) {#endif /* defined(SCO) || defined(HP_UX) || defined(AIX) */	    if (last) adjust /= 2;	    if (!adjust) adjust++;	    lba -= adjust;	} else {	    report_error ("FindCapacity() read", FALSE);	    status = FAILURE;	    break;	}	last = count;    }    free (buffer);    if (temp_fd) {	(void) close (dip->di_fd);	dip->di_fd = saved_fd;    } else {	(void) set_position (dip, (off_t) 0);    }    /*     * If the read failed, set the lba to the last successful read,     * and continue.  Won't be perfect, but at least we can run.     * Note: Workaround for problem seen on Linux w/ATAPI CD-ROM's.     */    if (status == FAILURE) {#if 1#if defined(DEBUG)	Printf("failed, last good lba was " LUF ", adjust was %ld\n",							 lba, adjust);#endif /* defined(DEBUG) */	lba -= adjust;	exit_status = SUCCESS;#else	return (status);	/* Return the failure! */#endif    }#if defined(DEBUG)    Printf ("read attempts was %d, the max lba is " LUF "\n", attempts, lba);#endif /* defined(DEBUG) */set_capacity:    dip->di_capacity = lba;    dip->di_data_limit = (large_t)(lba * dsize);    if (!record_limit) record_limit = INFINITY;    if (data_limit == INFINITY) data_limit = dip->di_data_limit;    /*     * The proper data limit is necessary for random I/O processing.     */    if ( (io_dir == REVERSE) || (io_type == RANDOM_IO) ) {	if ( (rdata_limit == (large_t)0) || (rdata_limit > dip->di_data_limit) ) {	    rdata_limit = dip->di_data_limit;	}	if (debug_flag || Debug_flag || rDebugFlag || (status == FAILURE)) {/* TODO: Cleanup this mess! */#if !defined(__GNUC__) && defined(_NT_SOURCE)    /* Avoid:  error C2520: conversion from unsigned __int64 to double not implemented, use signed __int64 */	    Printf ("Random data limit set to " LUF " bytes (%.3f Mbytes), " LUF " blocks.\n",		     rdata_limit, ((double)(slarge_t)rdata_limit/(double)MBYTE_SIZE), (rdata_limit / dsize));#else /* !defined(_NT_SOURCE) */	    Printf ("Random data limit set to " LUF " bytes (%.3f Mbytes), " LUF " blocks.\n",		rdata_limit, ((double)rdata_limit/(double)MBYTE_SIZE), (rdata_limit / dsize));#endif /* !defined(__GNUC__) && defined(_NT_SOURCE) */	}	if (rdata_limit <= file_position) {	    LogMsg (efp, logLevelCrit, 0,		    "Please specify a random data limit > file position!\n");	    exit (FATAL_ERROR);	}    } else if (debug_flag || Debug_flag || (status == FAILURE)) {#if !defined(__GNUC__) && defined(_NT_SOURCE)    /* Avoid:  error C2520: conversion from unsigned __int64 to double not implemented, use signed __int64 */	    Printf ("Data limit set to " LUF " bytes (%.3f Mbytes), " LUF " blocks.\n",			dip->di_data_limit,			((double)(slarge_t)dip->di_data_limit / (double)MBYTE_SIZE),			 (dip->di_data_limit / dsize));#else /* !defined(_NT_SOURCE) */	    Printf ("Data limit set to " LUF " bytes (%.3f Mbytes), " LUF " blocks.\n",		dip->di_data_limit, ((double)dip->di_data_limit/(double)MBYTE_SIZE),				     (dip->di_data_limit / dsize));#endif /* !defined(__GNUC__) && defined(_NT_SOURCE) */	if (file_position > dip->di_data_limit) {	    LogMsg (efp, logLevelCrit, 0,		    "Please specify a file position < media capacity!\n");	    exit (FATAL_ERROR);	}    }    return (SUCCESS);}

⌨️ 快捷键说明

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