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

📄 dtaio.c

📁 Linux磁盘测试的源代码,测试磁盘的读写性能
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (error) return (error);		goto retry;	    }	} else if (eei_flag) {	    (void) get_eei_status(dip->di_fd, dip->di_mt);	}    }#endif /* defined(EEI) */    acbp->aio_fildes = AIO_NotQed;    errno = error;    if (volumes_flag && (multi_volume >= volume_limit) &&	      (dip->di_volume_records == volume_records)) {	return (SUCCESS);    }    if (count == FAILURE) {	/*	 * End of media is handled below.	 */#if defined(SCO) || defined(HP_UX)	if ( (error != ENOSPC) && (error != ENXIO) ) {#else /* !defined(SCO) && !defined(HP_UX) */	if (error != ENOSPC) {#endif /* defined(SCO) || defined(HP_UX) */	    report_error ("aio_return", TRUE);	    ReportDeviceInfo (dip, acbp->aio_nbytes, 0, (errno == EIO));	    return (FAILURE);	}    } else if (error) {	count = FAILURE;    }    bsize = acbp->aio_nbytes;    data_buffer = (u_char *)acbp->aio_buf;    if (min_size) {	dsize = bsize;    } else {	dsize = block_size;    }    /*     * Adjust for short records or no data transferred.     */    if (count == FAILURE) {	aio_data_bytes -= bsize;	aio_file_bytes -= bsize;    } else if (adjust = (bsize - count)) {	if (debug_flag) {	    Printf("Adjusting byte counts by %d bytes...\n", adjust);	}	aio_data_bytes -= adjust;	aio_file_bytes -= adjust;    }    /*     * Process end of file/media conditions and handle multi-volume.     */    if ( is_Eof (dip, count, &status) ) {	if (multi_flag) {	    if ( (dip->di_dtype->dt_dtype == DT_TAPE) &&		 !dip->di_end_of_logical ) {		return (status);	/* Expect two file marks @ EOM. */	    }	    status = HandleMultiVolume (dip);	    aio_record_count = dip->di_records_read;	    /*aio_file_bytes = dip->di_dbytes_read;*/	    aio_offset = (off_t) 0;	}	return (status);    } else {	dip->di_end_of_file = FALSE;	/* Reset saved end of file state. */	if (count > (ssize_t) 0) {	    dip->di_dbytes_read += count;	    dip->di_fbytes_read += count;	    dip->di_vbytes_read += count;	    if (count == dsize) {		records_processed++;	    } else {		partial_records++;	    }	    dip->di_offset = (acbp->aio_offset + count);	}	if ((status = check_read (dip, count, bsize)) == FAILURE) {	    if (error_count >= error_limit) return (status);	} else if (io_mode == COPY_MODE) {	    status = copy_record (output_dinfo, data_buffer, count);	    if ( (error_count >= error_limit) || end_of_file) return (status);	} else if (io_mode == VERIFY_MODE) {	    status = verify_record (output_dinfo, data_buffer, count);	    if ( (error_count >= error_limit) || end_of_file) return (status);	}    }    /*     * Verify the data (unless disabled).     */    if ( (status != FAILURE) && compare_flag && (io_mode == TEST_MODE)) {	ssize_t vsize = count;	if (lbdata_flag || iot_pattern) {	    aio_lba = make_lbdata(dip, (dip->di_volume_bytes + acbp->aio_offset));	    if (iot_pattern) {		aio_lba = init_iotdata (vsize, aio_lba, lbdata_size);	    }	}	status = (*dtf->tf_verify_data)(dip, data_buffer, vsize, pattern, &aio_lba);	/*	 * Verify the pad bytes (if enabled).	 */	if ( (status == SUCCESS) && pad_check) {	    (void) verify_padbytes (dip, data_buffer, vsize, ~pattern, bsize);	}    }    dip->di_records_read++;    dip->di_volume_records++;    if ( ((io_dir == REVERSE) && (acbp->aio_offset == (off_t) file_position)) ||	 (step_offset && ((acbp->aio_offset - step_offset) <= (off_t) file_position)) ) {	set_Eof(dip);    }    return (status);}/************************************************************************ *									* * dtaio_write_data() - Write specified data to the output file.	* *									* * Inputs:	dip = The device information pointer.			* *									* * Outputs:	Returns SUCCESS/FAILURE = Ok/Error.			* *									* ************************************************************************/intdtaio_write_data (struct dinfo *dip){    register struct aiocb *acbp;    int error, status = SUCCESS;    register size_t bsize, dsize;    u_int32 lba = lbdata_addr;    if (dip->di_random_access) {	if (io_dir == REVERSE) {	    (void)set_position(dip, (off_t)rdata_limit);	}	aio_lba = lba = get_lba(dip);	aio_offset = get_position(dip);    } else {	aio_offset = dip->di_offset;	aio_lba = lba = make_lbdata (dip, aio_offset);    }    aio_data_bytes = aio_file_bytes = aio_record_count = 0;    /*     * For variable length records, initialize to minimum record size.     */    if (min_size) {	dsize = min_size;    } else {	dsize = block_size;    }    /*     * Now write the specifed number of records.     */    while ( (error_count < error_limit) &&	    (dip->di_fbytes_written < data_limit) &&	    (dip->di_records_written < record_limit) ) {	if (volumes_flag && (multi_volume >= volume_limit) &&		  (dip->di_volume_records >= volume_records)) {	    dip->di_volume_records = volume_records;	    break;	}	/*	 * Two loops are used with AIO.  The inner loop queues requests up	 * tto the requested amount, and the outer loop checks the actual	 * data processed.  This is done to handle short reads, which can	 * happen frequently with random I/O and large block sizes.	 */	while ( (error_count < error_limit) &&		(aio_record_count < record_limit) &&		(aio_file_bytes < data_limit) ) {	    if (volumes_flag && (multi_volume >= volume_limit) &&		      (dip->di_volume_records >= volume_records)) {		break;	    }	    if (wdelay_count) {			/* Optional write delay	*/		mySleep (wdelay_count);	    }	    /*	     * If data limit was specified, ensure we don't exceed it.	     */	    if ( (aio_file_bytes + dsize) > data_limit) {		bsize = (data_limit - aio_file_bytes);	    } else {		bsize = dsize;	    }	    acbp = &acbs[aio_index];	    /*	     * If requested, rotate the data buffer through ROTATE_SIZE bytes	     * to force various unaligned buffer accesses.	     */	    if (rotate_flag) {		data_buffer = aiobufs[aio_index];		data_buffer += (rotate_offset++ % ROTATE_SIZE);		acbp->aio_buf = data_buffer;	    } else {		data_buffer = (u_char *) acbp->aio_buf;	    }	    acbp->aio_fildes = dip->di_fd;	    if (io_dir == REVERSE) {		/*debug*/ if (!aio_offset) abort(); /*debug*/		bsize = MIN((aio_offset-file_position), bsize);		aio_offset = (off_t)(aio_offset - bsize);	    }            acbp->aio_nbytes = bsize;            if (debug_flag && (bsize != dsize) && !variable_flag) {                Printf ("Record #%lu, Writing a partial record of %d bytes...\n",                                    (aio_record_count + 1), bsize);            }	    if (io_type == RANDOM_IO) {		acbp->aio_offset = do_random (dip, FALSE, bsize);	    } else {		acbp->aio_offset = aio_offset;	    }	    if (iot_pattern || lbdata_flag) {		lba = make_lbdata (dip, (dip->di_volume_bytes + acbp->aio_offset));	    }	    /*	     * Initialize the data buffer with a pattern.	     */	    if ((io_mode == TEST_MODE) && compare_flag) {	        if (iot_pattern) {		    lba = init_iotdata(bsize, lba, lbdata_size);		}		fill_buffer (data_buffer, bsize, pattern);	    }	    /*	     * Initialize the logical block data (if enabled).	     */	    if (lbdata_flag && lbdata_size && !iot_pattern) {		lba = winit_lbdata (dip, (dip->di_volume_bytes + acbp->aio_offset),					data_buffer, bsize, lba, lbdata_size);	    }	    if (Debug_flag) {		u_int32 lba = NO_LBA;		if (dip->di_random_access || lbdata_flag || iot_pattern) {		    lba = make_lbdata(dip, (dip->di_volume_bytes + acbp->aio_offset));		}		report_record(dip, (dip->di_files_written + 1), (aio_record_count + 1),			lba, WRITE_MODE, (void *)acbp->aio_buf, acbp->aio_nbytes);	    }	    if ( (error = aio_write (acbp)) == FAILURE) {		acbp->aio_fildes = AIO_NotQed;		report_error ("aio_write", TRUE);		return (error);	    }	    /*	     * Must adjust record/data counts here to avoid writing	     * too much data, even though the writes are incomplete.	     */	    aio_data_bytes += bsize;	    aio_file_bytes += bsize;	    aio_record_count++;	    if (io_dir == FORWARD) {		aio_offset += bsize;	    } 	    if (step_offset) {		if (io_dir == FORWARD) {		    aio_offset += step_offset;		} else if ((aio_offset -= step_offset) <= (off_t) file_position) {		    aio_offset = (off_t) file_position;		}	    }	    /*	     * 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;		}	    }	    /*	     * Always ensure the next control block has completed.	     */	    if (++aio_index == aio_bufs) aio_index = 0;	    if ( (io_dir == REVERSE) && (aio_offset == (off_t) file_position) ) {		break;	    }	    acbp = &acbs[aio_index];	    if (acbp->aio_fildes == AIO_NotQed) continue; /* Never Q'ed. */	    if ( (status = dtaio_process_write (dip, acbp)) == FAILURE) {		return (status);	    }	    if (end_of_file) break;	}	/*	 * We get to this point after we've Q'ed enough requests to	 * fulfill the requested record and/or data limit.  We now	 * wait for these Q'ed requests to complete, adjusting the	 * global transfer statistics appropriately which reflects	 * the actual data processed.	 */	status = dtaio_wait_writes(dip);	if (end_of_file) break;    }    return (status);}/************************************************************************ *									* * dtaio_process_write() - Process AIO write requests.			* *									* * Description:								* *	This function does waits for the requested AIO write request	* * and checks the completion status.					* *									* * Inputs:	dip = The device info pointer.				* *		acbp = The AIO control block.				* *									* * Outputs:	Returns SUCCESS/FAILURE/WARNING = Ok/Error/Partial.	* *									* ************************************************************************/static intdtaio_process_write (struct dinfo *dip, struct aiocb *acbp){    register size_t bsize, dsize;    register ssize_t count;    ssize_t adjust;    int error, status = SUCCESS;#if defined(EEI)retry:#endif    current_acb = acbp;    error = dtaio_wait (dip, acbp);    count = aio_return (acbp);#if defined(EEI)    if (dip->di_dtype->dt_dtype == DT_TAPE) {	if ( (errno == EIO) && eei_resets) {	    if ( HandleTapeResets(dip) ) {		dtaio_restart(dip, acbp);		goto retry;	    }	} else if (eei_flag) {	    (void) get_eei_status(dip->di_fd, dip->di_mt);	}    }#endif /* defined(EEI) */    acbp->aio_fildes = AIO_NotQed;    errno = error;    if (volumes_flag && (multi_volume >= volume_limit) &&	      (dip->di_volume_records == volume_records)) {	return (SUCCESS);    }    if (count == FAILURE) {#if defined(SCO) || defined(HP_UX)	if ( (error != ENOSPC) && (error != ENXIO) ) {#else /* !defined(SCO) && !defined(HP_UX) */	if (error != ENOSPC) {#endif /* defined(SCO) || defined(HP_UX) */	    report_error ("aio_return", TRUE);	    ReportDeviceInfo (dip, acbp->aio_nbytes, 0, (errno == EIO));	    return (FAILURE);	}    } else if (error) {	count = FAILURE;    }    bsize = acbp->aio_nbytes;    if (min_size) {	dsize = bsize;	/* Can lead to wrong partial record count :-) */    } else {	dsize = block_size;    }    /*     * Adjust for short records or no data transferred.     */    if (count == FAILURE) {	aio_data_bytes -= bsize;	aio_file_bytes -= bsize;    } else if (adjust = (bsize - count)) {	aio_data_bytes -= adjust;	aio_file_bytes -= adjust;    }    if (count > (ssize_t) 0) {	dip->di_dbytes_written += count;	dip->di_fbytes_written += count;	dip->di_vbytes_written += count;    }    /*     * Process end of file/media conditions and handle multi-volume.     */    if ( is_Eof (dip, count, &status) ) {	if (multi_flag) {	    status = HandleMultiVolume (dip);	    aio_record_count = dip->di_records_written;	    /*aio_file_bytes = dip->di_dbytes_written;*/	    aio_offset = (off_t) 0;	}	return (status);    }    if (count > (ssize_t) 0) {	if (count == dsize) {	    records_processed++;	} else {	    partial_records++;	}	dip->di_offset = (acbp->aio_offset + count);    }    if ((status = check_write (dip, count, bsize)) == FAILURE) {	if (error_count >= error_limit) return (status);    }    if ( (status != FAILURE) && raw_flag) {	status = write_verify(dip, (u_char *)acbp->aio_buf, count, dsize, acbp->aio_offset);	if ( (status == FAILURE) && (error_count >= error_limit) ) {	    return (status);	}    }    dip->di_records_written++;    dip->di_volume_records++;    if ( ((io_dir == REVERSE) && (acbp->aio_offset == (off_t) file_position)) ||	 (step_offset && ((acbp->aio_offset - step_offset) <= (off_t) file_position)) ) {	set_Eof(dip);    }    return (status);}#endif /* defined(AIO) */

⌨️ 快捷键说明

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