The read system call will return EINVAL if the current file
offset is not a multiple of the block size. The read(2) man
page should be updated to reflect this.
Update man page so an examination of kernel code is not required
to determine why EINVAL is being returned. :-)
How-To-Repeat: Run /usr/ports/security/bcwipe. It attempts to determine a
block device's size vi a binary lseek search. The current code
does not round down the address passed to lseek to a multiple
of the device block size. Notice that subsequent read calls
fail with EINVAL.
This should also be added to write(2); I have recently received a truss report from FreeBSD 12 running e2fsck that showed this fragment:
lseek(4,0x430,SEEK_SET) = 1072 (0x430)
write(4,"\^F0\M-!Y\0\0",6) ERR#22 'Invalid argument'
where fd 4 is /dev/da0s1, an external 2015 Western Digital My Passport Ultra USB hard disk of 1 TB with this diskinfo (identifying information removed):
# diskinfo -v /dev/da0
512 # sectorsize
1000170586112 # mediasize in bytes (931G)
1953458176 # mediasize in sectors
4096 # stripesize
0 # stripeoffset
121597 # Cylinders according to firmware.
255 # Heads according to firmware.
63 # Sectors according to firmware.
WD My Passport 0830 # Disk descr.
[REMOVED] # Disk ident.
Not_Zoned # Zone Mode
I've just got bitten by this as well. Please fix the manpage. This bug had been reported in 2005 and still not fixed, how come?
I've started a first attempt at fixing the man pages. My review is here: https://reviews.freebsd.org/D24617