Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 01 Jun 1999 12:49:39 -0600
From:      Wes Peters <wes@softweyr.com>
To:        Julian Elischer <julian@whistle.com>
Cc:        Zhihui Zhang <zzhang@cs.binghamton.edu>, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Accessing special device files
Message-ID:  <37542B43.FD1CFFF3@softweyr.com>
References:  <Pine.BSF.3.95.990601090301.12924A-100000@current1.whistle.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Julian Elischer wrote:
> 
> Bzzzt!
> 
> On Tue, 1 Jun 1999, Wes Peters wrote:
> 
> > Zhihui Zhang wrote:
> > >
> > > I write a small program to read/write each FreeBSD partition via special
> > > device file names, e.g. /dev/wd0s2e, /dev/rwd0s2e, etc. I have two
> > > questions about doing this:
> > >
> > > (1) If I try to read() on these files, the buffer size must be given in
> > > multiples of 512 (sector size).  Otherwise, I will get an EINVAL error.
> > > Why is this the case?  Does the same thing happen to the write() system
> > > call?
> > >
> > > (2) I use lseek() on these device files, it returns the correct offset for
> > > me.  But actually it does not work. I read in a recent posting saying that
> > > you can't expect lseek(fd, 0, SEEK_END) to work unless the file descriptor
> > > is associated with a regular file because file size information is not
> > > available at that level.  Does this apply to all kinds of lseek(), include
> > > SEEK_SET and SEEK_CUR?  Or maybe the offset must also given in a multiple
> > > of 512 for some reason.  If I give lseek(fd, 8193, SEEK_SET), it will
> > > actually do lseek(fd, 8192, SEEK_SET)?
> >
> > They're block devices, they can only be read, written, and seeked in
> > terms of their native block size.  The block size is typically 512
> > bytes for disks, other types of media (like CD-ROM) may vary greatly
> > from this.
> >
> > If you want to read, write, or seek to arbitrary ranges, use the "raw"
> > devices, i.e. rwd0s2e.  These are character devices that will allow
> > you to read, write, and seek to arbitrary byte locations on the device;
> > the kernel handles the buffering and blocking for you.
> 
> I know this is confusing but you are 100% backwards..
> 
> the RAW device can only be accesses in units supported by the hardware..
> i.e. usually 512 byte chunks..
> however the Buffered device (e.g. wd0s1a) may be accessed on any boundary
> as it buffers the data, (at least for reads).
> it accesses the device in 512 byte chunks but this is hidden from you..
> this is why it's a buffered device....

???

dd verifies the behavior you report:

root@homer# dd if=/dev/rwd0s2b of=/dev/null bs=1
dd: /dev/rwd0s2b: Invalid argument
...
root@homer# dd if=/dev/rwd0s2b of=/dev/null bs=512
^C18805+0 records in
...

wes@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?

-- 
       "Where am I, and what am I doing in this handbasket?"

Wes Peters                                                 Softweyr LLC
http://www.softweyr.com/~softweyr                      wes@softweyr.com


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?37542B43.FD1CFFF3>