The following are demonstrations of the fsrw.d script.
Here the fsrw.d script was running while a 50 Kbyte file was read,
# ./fsrw.d
Event Device RW Size Offset Path
sc-read . R 8192 0 /extra1/50k
fop_read . R 8192 0 /extra1/50k
disk_io cmdk0 R 8192 0 /extra1/50k
disk_ra cmdk0 R 8192 8 /extra1/50k
sc-read . R 8192 8 /extra1/50k
fop_read . R 8192 8 /extra1/50k
disk_ra cmdk0 R 34816 16 /extra1/50k
sc-read . R 8192 16 /extra1/50k
fop_read . R 8192 16 /extra1/50k
sc-read . R 8192 24 /extra1/50k
fop_read . R 8192 24 /extra1/50k
sc-read . R 8192 32 /extra1/50k
fop_read . R 8192 32 /extra1/50k
sc-read . R 8192 40 /extra1/50k
fop_read . R 8192 40 /extra1/50k
sc-read . R 8192 48 /extra1/50k
fop_read . R 8192 48 /extra1/50k
sc-read . R 8192 50 /extra1/50k
fop_read . R 8192 50 /extra1/50k
^C
By looking closely at the Offset (Kbytes) and Size of each transaction, we
can see how the read() system calls (sc-read) were satisfied by the file
system. There were 8 read() system calls, and 3 disk events - 2 of which were
UFS read-ahead (disk_ra). The final read-ahead was for 34 Kbytes and began
with an offset of 16 Kbytes, which read the remaining file data (34 + 16 = 50
Kbytes). The subsequent read() system calls and corresponding fop_read() calls
returned from the page cache.
The following demonstrates how a logical I/O is broken up into multiple
physical I/O events. Here a dd command was used to read 1 Mbytes from the
/var/sadm/install/contents file while fsrw.d was tracing.
# ./fsrw.d
Event Device RW Size Offset Path
sc-read . R 1048576 0 /var/sadm/install/contents
fop_read . R 1048576 0 /var/sadm/install/contents
disk_ra cmdk0 R 4096 72 /var/sadm/install/contents
disk_ra cmdk0 R 8192 96 <none>
disk_ra cmdk0 R 57344 96 /var/sadm/install/contents
disk_ra cmdk0 R 57344 152 /var/sadm/install/contents
disk_ra cmdk0 R 57344 208 /var/sadm/install/contents
disk_ra cmdk0 R 49152 264 /var/sadm/install/contents
disk_ra cmdk0 R 57344 312 /var/sadm/install/contents
disk_ra cmdk0 R 57344 368 /var/sadm/install/contents
disk_ra cmdk0 R 57344 424 /var/sadm/install/contents
disk_ra cmdk0 R 57344 480 /var/sadm/install/contents
disk_ra cmdk0 R 57344 536 /var/sadm/install/contents
disk_ra cmdk0 R 57344 592 /var/sadm/install/contents
disk_ra cmdk0 R 57344 648 /var/sadm/install/contents
disk_ra cmdk0 R 57344 704 /var/sadm/install/contents
disk_ra cmdk0 R 57344 760 /var/sadm/install/contents
disk_ra cmdk0 R 57344 816 /var/sadm/install/contents
disk_ra cmdk0 R 57344 872 /var/sadm/install/contents
disk_ra cmdk0 R 57344 928 /var/sadm/install/contents
disk_ra cmdk0 R 57344 984 /var/sadm/install/contents
disk_ra cmdk0 R 57344 1040 /var/sadm/install/contents
^C
Both the read() syscall (sc-read) and the fop_read() call asked the file system
for 1048576 bytes, which was then broken into numerous disk I/O events of up to
56 Kbytes in size. The 8192 byte read with a path of "<none>" is likely to be
the file system reading the indirect block pointers for the
/var/sadm/install/contents file (something DTrace could confirm in detail).
The following traces activity as a cp command copies a 50 Kbyte file.
# ./fsrw.d
Event Device RW Size Offset Path
disk_io dad1 R 1024 0 /extra1
disk_io dad1 R 8192 0 <none>
disk_io dad1 R 8192 0 <none>
disk_io dad1 R 2048 0 <none>
disk_io dad1 R 2048 0 <none>
sc-write . W 51200 0 /extra1/outfile
fop_write . W 51200 0 /extra1/outfile
disk_io dad1 R 8192 0 /extra1/50k
disk_ra dad1 R 8192 8 /extra1/50k
disk_ra dad1 R 34816 16 /extra1/50k
disk_io dad1 R 2048 0 <none>
disk_io dad1 W 49152 0 /extra1/outfile
^C
Reads including UFS read-ahead can be seen as the file is read.
The output finishes with disk writes as the new file is flushed to disk.
The syscall write() and fop_write() can be seen to the /extra1/outfile,
however there is no syscall read() or fop_read() to /extra1/50k - which
we may have expected to occur before the writes. This is due to the way
the cp command now works, it uses mmap() to map files in for reading.
This activity can be seen if we also trace fop_getpage() and fop_putpage(),
as the fspaging.d dtrace script does.
# ./fspaging.d
Event Device RW Size Offset Path
disk_io dad1 R 1024 0 /extra1
disk_io dad1 R 8192 0 <none>
disk_io dad1 R 2048 0 <none>
sc-write . W 51200 0 /extra1/outfile
fop_write . W 51200 0 /extra1/outfile
fop_getpage . R 8192 0 /extra1/50k
disk_io dad1 R 8192 0 /extra1/50k
disk_ra dad1 R 8192 8 /extra1/50k
fop_getpage . R 8192 8 /extra1/50k
disk_ra dad1 R 34816 16 /extra1/50k
fop_getpage . R 8192 16 /extra1/50k
fop_getpage . R 8192 24 /extra1/50k
fop_getpage . R 8192 32 /extra1/50k
fop_getpage . R 8192 40 /extra1/50k
fop_getpage . R 8192 48 /extra1/50k
fop_putpage . W 8192 0 /extra1/outfile
fop_putpage . W 8192 8 /extra1/outfile
fop_putpage . W 8192 16 /extra1/outfile
fop_putpage . W 8192 24 /extra1/outfile
fop_putpage . W 8192 32 /extra1/outfile
fop_putpage . W 8192 40 /extra1/outfile
disk_io dad1 W 51200 0 /extra1/outfile