On Tue, 1 Jun 1999, Wes Peters wrote: > > ??? > > dd verifies the behavior you report: > > r...@homer# dd if=/dev/rwd0s2b of=/dev/null bs=1 > dd: /dev/rwd0s2b: Invalid argument > ... > r...@homer# dd if=/dev/rwd0s2b of=/dev/null bs=512 > ^C18805+0 records in > ... > > w...@homer$ ls -l /dev/*wd0s2a > crw-r----- 1 root operator 3, 0x00030000 Apr 1 11:10 /dev/rwd0s2a > brw-r----- 1 root operator 0, 0x00030000 Apr 1 11:10 /dev/wd0s2a > > The rwd device is clearly a character-special device, the wd device a > block special. Character devices can always be read byte-at-a-time, > by definition. When did the semantics of this change? >
I have verified the requirement that character device must be read in multiples of 512 from the source code point of view (the disk involved in an IDE drive): When we call read(int d, void *buf, size_t nbytes) system call, the argument nbytes is passed on to the iov_len field of an iov structure (see file sys_generic.c). Later, the routine vn_read() in file vfs_vnops.c is called via the structure fileops, the uio structure is passed along. vn_read() will call spec_read() via VOP_READ() because we are talking about raw device file name. spec_read() will call wdread() via the cdevsw table. wdread() will call physio() where b_bcount of a buffer is set to be iov_len. The routine wdstrategy() invoked by physio() will check if bp->b_bcount % DEV_BSIZE != 0. If it detects an request size that is not a multiple of 512, it will set b_error = EINVAL. This error will be picked up by physio() and returned. Thanks for your help. -Zhihui To Unsubscribe: send mail to majord...@freebsd.org with "unsubscribe freebsd-hackers" in the body of the message