Here is what I could research for this topic.
Wiping clean a 4GB USB 2.0 stick on macOS, using raw-disk round1:
Code:
root@demomac ~ # date;dd if=/dev/zero of=/dev/rdisk2 bs=4m;date
Sun Aug 16 18:57:16 CEST 2020
dd: /dev/rdisk2: short write on character device
dd: /dev/rdisk2: Input/output error
963+0 records in
962+1 records out
4034969600 bytes transferred in 586.373191 secs (6881231 bytes/sec)
Sun Aug 16 19:07:04 CEST 2020
This took about 10 minutes.
Let me do that one more time, to confirm that the speed/time is consistent.
macOS raw-disk round2:
Code:
root@demomac ~ # date;dd if=/dev/zero of=/dev/rdisk2 bs=4m;date
Sun Aug 16 19:07:44 CEST 2020
dd: /dev/rdisk2: short write on character device
dd: /dev/rdisk2: Input/output error
963+0 records in
962+1 records out
4034969600 bytes transferred in 570.989026 secs (7066632 bytes/sec)
Sun Aug 16 19:17:15 CEST 2020
Again, took about 10 minutes.
Now the same task, but instead of dev/rdisk use dev/disk.
Note the lack of the initial "r" letter in the device name!
macOS std-disk round1:
Code:
root@demomac ~ # date;dd if=/dev/zero of=/dev/disk2 bs=4m;date
Sun Aug 16 19:29:18 CEST 2020
dd: /dev/disk2: end of device
963+0 records in
962+1 records out
4034973696 bytes transferred in 8379.199622 secs (481546 bytes/sec)
Sun Aug 16 21:48:59 CEST 2020
This took about 140 minutes.
macOS std-disk round2:
Code:
root@demomac ~ # date;dd if=/dev/zero of=/dev/disk2 bs=4m;date
Sun Aug 16 22:09:46 CEST 2020
dd: /dev/disk2: end of device
963+0 records in
962+1 records out
4034973696 bytes transferred in 8439.354806 secs (478114 bytes/sec)
Mon Aug 17 00:30:27 CEST 2020
Again, took about 140 minutes.
So zeroing out the entire storage area of a 4GB USB 2.0 stick takes 10 minutes when access through the directIO /dev/
rdisk device, compared to 140 minutes using the standard /dev/disk bufferedIO device. Therefore using dev/rdisk for this particular kind of task is 14-times faster than using dev/disk. That is significant.
And I was hoping to zero out my drives at this significantly higher speed on FreeBSD too, where there is no dev/rdisk equivalent
(imagine something like dev/rada0 or dev/rda0). Hence my original post, asking for a way to use directIO on FreeBSD disk devices instead of the standard bufferedIO devices.
I went on investigating Ralph's suggestion, writing my own block-copy tool which uses the "O_DIRECT" option of
open(2)(), and ended up wasting a lot of time building something that does not work properly.
Then I spent a lot of time browsing through the ports collection in the hope of finding an existing tool that I can modify. And I found one which does the job well and does not even need any modificacion. Behold
misc/cstream.
==== FreeBSD ====
Messages on console when the USB stick is plugged in.
This is the very same 4GB USB 2.0 stick I used with the Mac tests above.
Code:
ugen0.2: <AI210 Mass Storage> at usbus0
umass0 on uhub1
umass0: <AI210 Mass Storage, class 0/0, rev 2.00/1.00, addr 1> on usbus0
umass0: SCSI over Bulk-Only; quirks = 0xc100
umass0:2:0: Attached to scbus2
da0 at umass-sim0 bus 0 scbus2 target 0 lun 0
da0: <AI Mass Storage > Removable Direct Access SPC-2 SCSI device
da0: 40.000MB/s transfers
da0: 3848MB (7880800 512 byte sectors)
da0: quirks=0x2<NO_6_BYTE>
BSD dd round1:
Code:
root@demobsd:~ # date;dd if=/dev/zero of=/dev/da0 bs=4m;date
Mon Aug 17 08:04:11 CEST 2020
dd: /dev/da0: short write on character device
dd: /dev/da0: end of device
963+0 records in
962+1 records out
4034969600 bytes transferred in 608.828416 secs (6627433 bytes/sec)
Mon Aug 17 08:14:20 CEST 2020
This took about 10 minutes. What? I expected more, around 140 minutes.
BSD dd round2:
Code:
root@demobsd:~ # date ; dd if=/dev/zero of=/dev/da0 bs=4m ; date
Mon Aug 17 08:23:14 CEST 2020
dd: /dev/da0: short write on character device
dd: /dev/da0: end of device
963+0 records in
962+1 records out
4034969600 bytes transferred in 606.762631 secs (6649997 bytes/sec)
Mon Aug 17 08:33:21 CEST 2020
Again, took about 10 minutes.
That is what I was hoping to achieve in the first place.
Turns out, I did not need any jiggery-pokery for that.
For comparison, here is what cstream can do.
FreeBSD cstream with direct
output:
Code:
root@demobsd:~ # date ; cstream -i /dev/zero -b 4m -o /dev/da0 -OD -n 4034969600 ; date
Mon Aug 17 22:50:30 CEST 2020
Mon Aug 17 23:00:36 CEST 2020
This took about 10 minutes. So far so good.
FreeBSD cstream
without direct output:
Code:
root@demobsd:~ # date ; cstream -i /dev/zero -b 4m -o /dev/da0 -n 4034969600 ; date
Mon Aug 17 23:01:11 CEST 2020
Mon Aug 17 23:11:17 CEST 2020
Also took about 10 minutes.
So direct output
(or the lack of it) makes no difference here.
FreeBSD cstream with direct
input:
Code:
root@demobsd:~ # date ; cstream -i /dev/zero -ID -b 1m -o /dev/da0 -n 4034969600 ; date
Tue Aug 18 00:07:09 CEST 2020
Tue Aug 18 00:17:15 CEST 2020
Yet again, 10 minutes. Not faster, not slower.
Conclusion:
I falsely assumed that the FreeBSD
dev/adaN or
dev/daN devices give similarly slow write speeds with dd to macOS's
dev/diskN devices compared to the much faster
dev/rdisk devices. Turns out, writing
dev/daN and
dev/adaN with
dd on FreeBSD actually gives the performance equal to using
dev/rdisk on my Mac. Meaning, I can wipe my USB sticks under FreeBSD without taking over 10 times more than what it would on OSX.