Re: new function for libdevstat

2001-05-22 Thread Igor Timkin

Sergey A. Osokin writes:
> I have rewritten devstat_compute_statistics().
> Please see the attachment.

Add ``break'' in each ``case''.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message



Re: new function for libdevstat

2001-05-17 Thread Poul-Henning Kamp


Looks OK to me.

In message <[EMAIL PROTECTED]>, "Sergey A. Osokin" writes:
>
>--9amGYk9869ThD9tj
>Content-Type: text/plain; charset=us-ascii
>Content-Disposition: inline
>
>On Fri, May 11, 2001 at 07:35:50PM +0200, Poul-Henning Kamp wrote:
>> In message <[EMAIL PROTECTED]>, "Sergey A. Osokin" writes:
>> 
>> >Hello.
>> >2 monthes ago I talked in -current about new features for libdevstat.
>> >Here is a new function, which calculate more statistics then 
>> >existing compute_stats(). (compute_stats() calculate only average
>> >results, not read/write results).
>> >Please see my first step. Comments are welcome.
>> 
>> I really don't think this is the way...
>> 
>> I would far rather see:
>> 
>>  enum DEVSTAT_METRIC {
>>  DEVSTAT_BYTES,
>>  DEVSTAT_BYTES_READ,
>>  DEVSTAT_BYTES_WRITE,
>>  ...
>>  }
>> 
>>  int
>>  devstat_compute_statistics(
>>  struct devstat *current,
>>  struct devstat *previous,
>>  enum DEVSTAT_METRIC metric,
>>  double *destination);
>> 
>> Since that can be extended with new metrics without changing
>> the ABI...
>
>OK. Please see attachment.
>Thanks.
>-- 
>
>Rgdz,/"\ 
>Sergey Osokin aka oZZ,   \ /  ASCII RIBBON CAMPAIGN
>[EMAIL PROTECTED]X AGAINST HTML MAIL
>http://freebsd.org.ru/~osa/  / \
>
>--9amGYk9869ThD9tj
>Content-Type: text/plain; charset=us-ascii
>Content-Disposition: attachment; filename="newstat2.c"
>
>enum DEVSTAT_METRIC {
>   DEVSTAT_TOTAL_BYTES,
>   DEVSTAT_TOTAL_BYTES_READ,
>   DEVSTAT_TOTAL_BYTES_WRITE,
>   DEVSTAT_TOTAL_TRANSFERS,
>   DEVSTAT_TOTAL_TRANSFERS_READ,
>   DEVSTAT_TOTAL_TRANSFERS_WRITE,
>   DEVSTAT_TOTAL_TRANSFERS_OTHER,
>   DEVSTAT_TOTAL_BLOCKS,
>   DEVSTAT_TOTAL_BLOCKS_READ,
>   DEVSTAT_TOTAL_BLOCKS_WRITE,
>   DEVSTAT_KB_PER_TRANSFER,
>   DEVSTAT_KB_PER_TRANSFER_READ,
>   DEVSTAT_KB_PER_TRANSFER_WRITE,
>   DEVSTAT_TRANSFERS_PER_SECOND,
>   DEVSTAT_TRANSFERS_PER_SECOND_READ,
>   DEVSTAT_TRANSFERS_PER_SECOND_WRITE,
>   DEVSTAT_TRANSFERS_PER_SECOND_OTHER,
>   DEVSTAT_MB_PER_SECOND,
>   DEVSTAT_MB_PER_SECOND_READ,
>   DEVSTAT_MB_PER_SECOND_WRITE,
>   DEVSTAT_BLOCKS_PER_SECOND,
>   DEVSTAT_BLOCKS_PER_SECOND_READ,
>   DEVSTAT_BLOCKS_PER_SECOND_WRITE,
>   DEVSTAT_MS_PER_TRANSACTION,
>   DEVSTAT_MS_PER_TRANSACTION_READ,
>   DEVSTAT_MS_PER_TRANSACTION_WRITE
>};
>
>int
>devstat_compute_statistics(struct devstat *current, struct devstat *previous,
>   long double etime, enum DEVSTAT_METRIC metric,
>   long double *destination)
>{
>   u_int64_t totalbytes, totalbytes_read, totalbytes_write;
>   u_int64_t totaltransfers, totaltransfers_read, totaltransfers_write, 
>totaltransfers_other;
>   u_int64_t totalblocks, totalblocks_read, totalblocks_write;
>   char *func_name = "devstat_compute_statistics";
>
>   /*
>* current is the only mandatory field.
>*/
>
>   if (current == NULL) {
>   sprintf(devstat_errbuf, "%s: current stats structure was NULL",
>   func_name);
>   return(-1);
>   }
>
>   totalbytes_read = current->bytes_read - ((previous) ? previous->bytes_read : 
>0);
>
>   if (metric == DEVSTAT_TOTAL_BYTES_READ) {
>   *destination = totalbytes_read;
>   return 0;
>   }
>
>   totalbytes_write = current->bytes_written - ((previous) ? 
>previous->bytes_written : 0);
>
>   if (metric == DEVSTAT_TOTAL_BYTES_WRITE) {
>   *destination = totalbytes_write;
>   return 0;
>   }
>
>/*
>   totalbytes = (current->bytes_written + current->bytes_read) -
>   ((previous) ? (previous->bytes_written +
>   previous->bytes_read) : 0);
>*/
>
>   totalbytes = totalbytes_read + totalbytes_write;
>
>   if (metric == DEVSTAT_TOTAL_BYTES) {
>   *destination = totalbytes;
>   return 0;
>   }
>
>   totaltransfers_read = current->num_reads - ((previous) ? (previous->num_reads) 
>: 0);
>
>   if (metric == DEVSTAT_TOTAL_TRANSFERS_READ) {
>   *destination = totaltransfers_read;
>   return 0;
>   }
>
>   totaltransfers_write = current->num_writes - ((previous) ? 
>(previous->num_writes) : 0);
>
>   if (metric == DEVSTAT_TOTAL_TRANSFERS_WRITE) {
>   *destination = totaltransfers_write;
>   return 0;
>   }
>
>   totaltransfers_other = current->num_other - ((previous) ? 
>(previous->num_other) : 0);
>
>   if (metric == DEVSTAT_TOTAL_TRANSFERS_OTHER) {
>   *destination = totaltransfers_other;
>   return 0;
>   }
>/*
>   totaltransfers = (current->num_reads +
> current->num_writes +
> current->num_other) -
>

Re: new function for libdevstat

2001-05-14 Thread Sergey A. Osokin

On Sat, May 12, 2001 at 05:42:01PM +0400, Sergey A. Osokin wrote:
> On Fri, May 11, 2001 at 07:35:50PM +0200, Poul-Henning Kamp wrote:
> > In message <[EMAIL PROTECTED]>, "Sergey A. Osokin" writes:
> > 
> > >Hello.
> > >2 monthes ago I talked in -current about new features for libdevstat.
> > >Here is a new function, which calculate more statistics then 
> > >existing compute_stats(). (compute_stats() calculate only average
> > >results, not read/write results).
> > >Please see my first step. Comments are welcome.
> > 
> > I really don't think this is the way...
> > 
> > I would far rather see:
> > 
> > enum DEVSTAT_METRIC {
> > DEVSTAT_BYTES,
> > DEVSTAT_BYTES_READ,
> > DEVSTAT_BYTES_WRITE,
> > ...
> > }
> > 
> > int
> > devstat_compute_statistics(
> > struct devstat *current,
> > struct devstat *previous,
> > enum DEVSTAT_METRIC metric,
> > double *destination);
> > 
> > Since that can be extended with new metrics without changing
> > the ABI...
> 
> OK. Please see attachment.

I have rewritten devstat_compute_statistics().
Please see the attachment.
If you need a patch-version for libdevstat, just say about.
Thanks.
-- 
 
Rgdz,/"\ 
Sergey Osokin aka oZZ,   \ /  ASCII RIBBON CAMPAIGN
[EMAIL PROTECTED]X AGAINST HTML MAIL
http://freebsd.org.ru/~osa/  / \




enum DEVSTAT_METRIC {
DEVSTAT_TOTAL_BYTES = 1,
DEVSTAT_TOTAL_BYTES_READ,
DEVSTAT_TOTAL_BYTES_WRITE,
DEVSTAT_TOTAL_TRANSFERS,
DEVSTAT_TOTAL_TRANSFERS_READ,
DEVSTAT_TOTAL_TRANSFERS_WRITE,
DEVSTAT_TOTAL_TRANSFERS_OTHER,
DEVSTAT_TOTAL_BLOCKS,
DEVSTAT_TOTAL_BLOCKS_READ,
DEVSTAT_TOTAL_BLOCKS_WRITE,
DEVSTAT_KB_PER_TRANSFER,
DEVSTAT_KB_PER_TRANSFER_READ,
DEVSTAT_KB_PER_TRANSFER_WRITE,
DEVSTAT_TRANSFERS_PER_SECOND,
DEVSTAT_TRANSFERS_PER_SECOND_READ,
DEVSTAT_TRANSFERS_PER_SECOND_WRITE,
DEVSTAT_TRANSFERS_PER_SECOND_OTHER,
DEVSTAT_MB_PER_SECOND,
DEVSTAT_MB_PER_SECOND_READ,
DEVSTAT_MB_PER_SECOND_WRITE,
DEVSTAT_BLOCKS_PER_SECOND,
DEVSTAT_BLOCKS_PER_SECOND_READ,
DEVSTAT_BLOCKS_PER_SECOND_WRITE,
DEVSTAT_MS_PER_TRANSACTION,
DEVSTAT_MS_PER_TRANSACTION_READ,
DEVSTAT_MS_PER_TRANSACTION_WRITE
};

/*
 *  How to use this function?
 *
 *  long double total_bytes;
 *
 *  devstat_compute_statistics(&cur.dinfo->devices[di], &last.dinfo->devices[di],
 *  busy_seconds, DEVSTAT_TOTAL_BYTES, &total_bytes, 0);
 *
 *  DEVSTAT_TOTAL_BYTES - is what you need.
 *  total_bytes - where you need.
 *
 *  Wrapper for
 *  compute_stats(current, previous, etime, total_bytes,
 *  total_transfers, total_blocks,
 *  kb_per_transfer, transfers_per_second,
 *  mb_per_second, blocks_per_second,
 *  ms_per_transaction);
 *
 *  looks like this:
 *
 *  devstat_compute_statistics(current, previous, etime,
 *  DEVSTAT_TOTAL_BYTES, total_bytes,
 *  DEVSTAT_TOTAL_TRANSFERS, total_transfers,
 *  DEVSTAT_TOTAL_BLOCKS, total_blocks,
 *  DEVSTAT_TOTAL_TRANSFER, kb_per_transfer,
 *  DEVSTAT_TRANSFERS_PER_SECOND, transfers_per_second,
 *  DEVSTAT_MB_PER_SECOND, mb_per_second,
 *  DEVSTAT_BLOCKS_PER_SECOND, blocks_per_second,
 *  DEVSTAT_MS_PER_TRANSACTION, ms_per_transaction,
 *  0);
 */

long double
devstat_compute_statistics(struct devstat *current, struct devstat *previous,
long double etime, ...)
{
u_int64_t totalbytes, totalbytes_read, totalbytes_write;
u_int64_t totaltransfers, totaltransfers_read, totaltransfers_write, 
totaltransfers_other;
u_int64_t totalblocks, totalblocks_read, totalblocks_write;
char *func_name = "devstat_compute_statistics";
va_list ap;
enum DEVSTAT_METRIC metric;
long double *destination;

/*
 * current is the only mandatory field.
 */

if (current == NULL) {
sprintf(devstat_errbuf, "%s: current stats structure was NULL",
func_name);
return(-1);
}

totalbytes_read = current->bytes_read - ((previous) ? (previous->bytes_read) : 
0);

totalbytes_write = current->bytes_written - ((previous) ? 
(previous->bytes_written) : 0);

totalbytes = totalbytes_read + totalbytes_write;

totaltransfers_read = current->num_reads - ((previous) ? (previous->num_reads) 
: 0);

totaltransfers_write = current->num_writes - ((previous) ? 
(previous->num_writes) : 0);

totaltransfers_other = current->num_other - ((previous) ? 
(previous->num_other) : 0);

totaltransfers = totaltransfers_read + totaltransfers_write + 
totaltransfers_o

Re: new function for libdevstat

2001-05-12 Thread Sergey A. Osokin

On Fri, May 11, 2001 at 07:35:50PM +0200, Poul-Henning Kamp wrote:
> In message <[EMAIL PROTECTED]>, "Sergey A. Osokin" writes:
> 
> >Hello.
> >2 monthes ago I talked in -current about new features for libdevstat.
> >Here is a new function, which calculate more statistics then 
> >existing compute_stats(). (compute_stats() calculate only average
> >results, not read/write results).
> >Please see my first step. Comments are welcome.
> 
> I really don't think this is the way...
> 
> I would far rather see:
> 
>   enum DEVSTAT_METRIC {
>   DEVSTAT_BYTES,
>   DEVSTAT_BYTES_READ,
>   DEVSTAT_BYTES_WRITE,
>   ...
>   }
> 
>   int
>   devstat_compute_statistics(
>   struct devstat *current,
>   struct devstat *previous,
>   enum DEVSTAT_METRIC metric,
>   double *destination);
> 
> Since that can be extended with new metrics without changing
> the ABI...

OK. Please see attachment.
Thanks.
-- 

Rgdz,/"\ 
Sergey Osokin aka oZZ,   \ /  ASCII RIBBON CAMPAIGN
[EMAIL PROTECTED]X AGAINST HTML MAIL
http://freebsd.org.ru/~osa/  / \


enum DEVSTAT_METRIC {
DEVSTAT_TOTAL_BYTES,
DEVSTAT_TOTAL_BYTES_READ,
DEVSTAT_TOTAL_BYTES_WRITE,
DEVSTAT_TOTAL_TRANSFERS,
DEVSTAT_TOTAL_TRANSFERS_READ,
DEVSTAT_TOTAL_TRANSFERS_WRITE,
DEVSTAT_TOTAL_TRANSFERS_OTHER,
DEVSTAT_TOTAL_BLOCKS,
DEVSTAT_TOTAL_BLOCKS_READ,
DEVSTAT_TOTAL_BLOCKS_WRITE,
DEVSTAT_KB_PER_TRANSFER,
DEVSTAT_KB_PER_TRANSFER_READ,
DEVSTAT_KB_PER_TRANSFER_WRITE,
DEVSTAT_TRANSFERS_PER_SECOND,
DEVSTAT_TRANSFERS_PER_SECOND_READ,
DEVSTAT_TRANSFERS_PER_SECOND_WRITE,
DEVSTAT_TRANSFERS_PER_SECOND_OTHER,
DEVSTAT_MB_PER_SECOND,
DEVSTAT_MB_PER_SECOND_READ,
DEVSTAT_MB_PER_SECOND_WRITE,
DEVSTAT_BLOCKS_PER_SECOND,
DEVSTAT_BLOCKS_PER_SECOND_READ,
DEVSTAT_BLOCKS_PER_SECOND_WRITE,
DEVSTAT_MS_PER_TRANSACTION,
DEVSTAT_MS_PER_TRANSACTION_READ,
DEVSTAT_MS_PER_TRANSACTION_WRITE
};

int
devstat_compute_statistics(struct devstat *current, struct devstat *previous,
long double etime, enum DEVSTAT_METRIC metric,
long double *destination)
{
u_int64_t totalbytes, totalbytes_read, totalbytes_write;
u_int64_t totaltransfers, totaltransfers_read, totaltransfers_write, 
totaltransfers_other;
u_int64_t totalblocks, totalblocks_read, totalblocks_write;
char *func_name = "devstat_compute_statistics";

/*
 * current is the only mandatory field.
 */

if (current == NULL) {
sprintf(devstat_errbuf, "%s: current stats structure was NULL",
func_name);
return(-1);
}

totalbytes_read = current->bytes_read - ((previous) ? previous->bytes_read : 
0);

if (metric == DEVSTAT_TOTAL_BYTES_READ) {
*destination = totalbytes_read;
return 0;
}

totalbytes_write = current->bytes_written - ((previous) ? 
previous->bytes_written : 0);

if (metric == DEVSTAT_TOTAL_BYTES_WRITE) {
*destination = totalbytes_write;
return 0;
}

/*
totalbytes = (current->bytes_written + current->bytes_read) -
((previous) ? (previous->bytes_written +
previous->bytes_read) : 0);
*/

totalbytes = totalbytes_read + totalbytes_write;

if (metric == DEVSTAT_TOTAL_BYTES) {
*destination = totalbytes;
return 0;
}

totaltransfers_read = current->num_reads - ((previous) ? (previous->num_reads) 
: 0);

if (metric == DEVSTAT_TOTAL_TRANSFERS_READ) {
*destination = totaltransfers_read;
return 0;
}

totaltransfers_write = current->num_writes - ((previous) ? 
(previous->num_writes) : 0);

if (metric == DEVSTAT_TOTAL_TRANSFERS_WRITE) {
*destination = totaltransfers_write;
return 0;
}

totaltransfers_other = current->num_other - ((previous) ? 
(previous->num_other) : 0);

if (metric == DEVSTAT_TOTAL_TRANSFERS_OTHER) {
*destination = totaltransfers_other;
return 0;
}
/*
totaltransfers = (current->num_reads +
  current->num_writes +
  current->num_other) -
((previous) ?
 (previous->num_reads +
  previous->num_writes +
  previous->num_other) : 0);
*/

totaltransfers = totaltransfers_read + totaltransfers_write + 
totaltransfers_other;

if (metric == DEVSTAT_TOTAL_TRANSFERS) {
*destination = 

Re: new function for libdevstat

2001-05-11 Thread Poul-Henning Kamp

In message <[EMAIL PROTECTED]>, "Sergey A. Osokin" writes:

>Hello.
>2 monthes ago I talked in -current about new features for libdevstat.
>Here is a new function, which calculate more statistics then 
>existing compute_stats(). (compute_stats() calculate only average
>results, not read/write results).
>Please see my first step. Comments are welcome.

I really don't think this is the way...

I would far rather see:

enum DEVSTAT_METRIC {
DEVSTAT_BYTES,
DEVSTAT_BYTES_READ,
DEVSTAT_BYTES_WRITE,
...
}

int
devstat_compute_statistics(
struct devstat *current,
struct devstat *previous,
enum DEVSTAT_METRIC metric,
double *destination);

Since that can be extended with new metrics without changing
the ABI...

Poul-Henning

>-- 
>
>Rgdz,/"\ 
>Sergey Osokin aka oZZ,   \ /  ASCII RIBBON CAMPAIGN
>[EMAIL PROTECTED]X AGAINST HTML MAIL
>http://freebsd.org.ru/~osa/  / \
>
>--/04w6evG8XlLl3ft
>Content-Type: text/plain; charset=us-ascii
>Content-Disposition: attachment; filename="newstat.c"
>
>int
>devstat_compute_statistics(struct devstat *current, struct devstat *previous,
>   long double etime,
>   u_int64_t *total_bytes,
>   u_int64_t *total_bytes_read,
>   u_int64_t *total_bytes_write,
>   u_int64_t *total_transfers,
>   u_int64_t *total_transfers_read,
>   u_int64_t *total_transfers_write,
>   u_int64_t *total_transfers_other,
>   u_int64_t *total_blocks,
>   u_int64_t *total_blocks_read,
>   u_int64_t *total_blocks_write,
>   long double *kb_per_transfer,
>   long double *kb_per_transfer_read,
>   long double *kb_per_transfer_write,
>   long double *transfers_per_second,
>   long double *transfers_per_second_read,
>   long double *transfers_per_second_write,
>   long double *transfers_per_second_other,
>   long double *mb_per_second,
>   long double *mb_per_second_read,
>   long double *mb_per_second_write,
>   long double *blocks_per_second,
>   long double *blocks_per_second_read,
>   long double *blocks_per_second_write,
>   long double *ms_per_transaction,
>   long double *ms_per_transaction_read,
>   long double *ms_per_transaction_write)
>   
>{
>   u_int64_t totalbytes, totalbytes_read, totalbytes_write;
>   u_int64_t totaltransfers, totaltransfers_read, totaltransfers_write, 
>totaltransfers_other;
>   u_int64_t totalblocks, totalblocks_read, totalblocks_write;
>   char *func_name = "devstat_compute_statistics";
>
>   /*
>* current is the only mandatory field.
>*/
>   if (current == NULL) {
>   sprintf(devstat_errbuf, "%s: current stats structure was NULL",
>   func_name);
>   return(-1);
>   }
>/*
>   totalbytes = (current->bytes_written + current->bytes_read) -
>   ((previous) ? (previous->bytes_written +
>   previous->bytes_read) : 0);
>
>   if (total_bytes)
>   *total_bytes = totalbytes;
>*/
>
>   totalbytes_read = current->bytes_read - ((previous) ? previous->bytes_read) : 
>0);
>
>   if (total_bytes_read)
>   *total_bytes_read = totalbytes_read;
>
>   totalbytes_write = current->bytes_written - ((previous) ? 
>(previous->bytes_written) : 0);
>
>   if (total_bytes_write)
>   *total_bytes_write = totalbytes_write;
>
>   totalbytes = totalbytes_read + totalbytes_write;
>
>   if (total_bytes)
>   *total_bytes = totalbytes;
>
>/*
>   totaltransfers = (current->num_reads +
> current->num_writes +
> current->num_other) -
>   ((previous) ?
>(previous->num_reads +
> previous->num_writes +
> previous->num_other) : 0);
>
>   if (total_transfers)
>   *total_transfers = totaltransfers;
>*/
>
>   totaltransfers_read = current->num_reads - ((previous) ? (previous->num_reads) 
>: 0);
>
>   if (total_transfers_read)
>   *total_transfers_read = totaltransfers_read;
>
>   totaltransfers_write = current->num_writes - ((previous) ? 
>(previous->num_writes) : 0);
>
>   if (total_transfers_write)
>   *total_transfers_write = totaltransfers_write;
>
>   totaltransfers_other = current->num_other - ((previous) ? 
>(previous->num_other) : 0);
>
>   if (total_transfers_other)
>   *total_transfers_other = totaltransfers_other;
>
>   totaltransfers = totaltransfers_rea

new function for libdevstat

2001-05-11 Thread Sergey A. Osokin

Hello.
2 monthes ago I talked in -current about new features for libdevstat.
Here is a new function, which calculate more statistics then 
existing compute_stats(). (compute_stats() calculate only average
results, not read/write results).
Please see my first step. Comments are welcome.
-- 

Rgdz,/"\ 
Sergey Osokin aka oZZ,   \ /  ASCII RIBBON CAMPAIGN
[EMAIL PROTECTED]X AGAINST HTML MAIL
http://freebsd.org.ru/~osa/  / \


int
devstat_compute_statistics(struct devstat *current, struct devstat *previous,
long double etime,
u_int64_t *total_bytes,
u_int64_t *total_bytes_read,
u_int64_t *total_bytes_write,
u_int64_t *total_transfers,
u_int64_t *total_transfers_read,
u_int64_t *total_transfers_write,
u_int64_t *total_transfers_other,
u_int64_t *total_blocks,
u_int64_t *total_blocks_read,
u_int64_t *total_blocks_write,
long double *kb_per_transfer,
long double *kb_per_transfer_read,
long double *kb_per_transfer_write,
long double *transfers_per_second,
long double *transfers_per_second_read,
long double *transfers_per_second_write,
long double *transfers_per_second_other,
long double *mb_per_second,
long double *mb_per_second_read,
long double *mb_per_second_write,
long double *blocks_per_second,
long double *blocks_per_second_read,
long double *blocks_per_second_write,
long double *ms_per_transaction,
long double *ms_per_transaction_read,
long double *ms_per_transaction_write)

{
u_int64_t totalbytes, totalbytes_read, totalbytes_write;
u_int64_t totaltransfers, totaltransfers_read, totaltransfers_write, 
totaltransfers_other;
u_int64_t totalblocks, totalblocks_read, totalblocks_write;
char *func_name = "devstat_compute_statistics";

/*
 * current is the only mandatory field.
 */
if (current == NULL) {
sprintf(devstat_errbuf, "%s: current stats structure was NULL",
func_name);
return(-1);
}
/*
totalbytes = (current->bytes_written + current->bytes_read) -
((previous) ? (previous->bytes_written +
previous->bytes_read) : 0);

if (total_bytes)
*total_bytes = totalbytes;
*/

totalbytes_read = current->bytes_read - ((previous) ? previous->bytes_read) : 
0);

if (total_bytes_read)
*total_bytes_read = totalbytes_read;

totalbytes_write = current->bytes_written - ((previous) ? 
(previous->bytes_written) : 0);

if (total_bytes_write)
*total_bytes_write = totalbytes_write;

totalbytes = totalbytes_read + totalbytes_write;

if (total_bytes)
*total_bytes = totalbytes;

/*
totaltransfers = (current->num_reads +
  current->num_writes +
  current->num_other) -
((previous) ?
 (previous->num_reads +
  previous->num_writes +
  previous->num_other) : 0);

if (total_transfers)
*total_transfers = totaltransfers;
*/

totaltransfers_read = current->num_reads - ((previous) ? (previous->num_reads) 
: 0);

if (total_transfers_read)
*total_transfers_read = totaltransfers_read;

totaltransfers_write = current->num_writes - ((previous) ? 
(previous->num_writes) : 0);

if (total_transfers_write)
*total_transfers_write = totaltransfers_write;

totaltransfers_other = current->num_other - ((previous) ? 
(previous->num_other) : 0);

if (total_transfers_other)
*total_transfers_other = totaltransfers_other;

totaltransfers = totaltransfers_read + totaltransfers_write + 
totaltransfers_other;

if (total_transfers)
*total_transfers = totaltransfers;

if (transfers_per_second) {
if (etime > 0.0) {
*transfers_per_second = totaltransfers;
*transfers_per_second /= etime;
} else
*transfers_per_second = 0.0;
}

if (transfers_per_second_read) {
if (etime > 0.0) {
*transfers_per_second_read = totaltransfers_read;
*transfers_per_second_read /= etime;
} else
*transfers_per_second_read = 0.0;
}

if (transfers_per_s