Bug 91149

Summary: fix man page: read(2) and write(2) can return EINVAL for unaligned access to block devices
Product: Documentation Reporter: Justin T. Gibbs <gibbs>
Component: Manual PagesAssignee: Benedict Reuschling <bcr>
Status: Closed FIXED    
Severity: Affects Only Me CC: bcr, danfe, doc, emaste, mandree, mqudsi
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   

Description Justin T. Gibbs 2005-12-31 18:10:03 UTC
	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.

Fix: 

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.
Comment 1 Matthias Andree freebsd_committer freebsd_triage 2017-08-26 10:44:52 UTC
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
/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
Comment 2 Alexey Dokuchaev freebsd_committer freebsd_triage 2020-04-26 08:50:41 UTC
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?
Comment 3 Benedict Reuschling freebsd_committer freebsd_triage 2020-04-29 15:06:28 UTC
I've started a first attempt at fixing the man pages. My review is here: https://reviews.freebsd.org/D24617
Comment 4 commit-hook freebsd_committer freebsd_triage 2022-10-07 11:39:39 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=1c2be25f6080ee63baeae55e45761e1310d1b756

commit 1c2be25f6080ee63baeae55e45761e1310d1b756
Author:     Benedict Reuschling <bcr@FreeBSD.org>
AuthorDate: 2022-10-07 11:32:37 +0000
Commit:     Benedict Reuschling <bcr@FreeBSD.org>
CommitDate: 2022-10-07 11:32:37 +0000

    Add extra EINVAL information about wrong block size to read(2)/write(2)

    The read system call will return EINVAL if the current file offset is
    not a multiple of the block size. This also applies to write(2). Add an
    entry for EINVAL about this error to both man pages.

    PR:                     91149
    Event:                  Aberdeen Hackathon 2022
    Differential Revision:  https://reviews.freebsd.org/D24617

 lib/libc/sys/read.2  | 4 +++-
 lib/libc/sys/write.2 | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)
Comment 5 Benedict Reuschling freebsd_committer freebsd_triage 2022-10-07 11:41:10 UTC
A fix was committed. Sorry it took so long to commit it. PR closed!
Comment 6 Benedict Reuschling freebsd_committer freebsd_triage 2022-10-07 11:41:34 UTC
A fix was committed. Sorry it took so long to commit it. PR closed!
Comment 7 Mark Linimon freebsd_committer freebsd_triage 2024-01-10 05:04:55 UTC
^Triage: assign to committer that resolved.