Coda File System

Are write()'s on block devices always exact, in Linux ?

From: LEE, Yui-wah <clement_at_cse.cuhk.edu.hk>
Date: Fri, 4 Sep 1998 18:54:25 +0800 (CST)
Hi,

I got a server crash, when the following assertion failed (in
write_dev(), rvm_io.c, line 354) ...

        if ((wrt_len=write((int)dev->handle,src,(int)length)) < 0) {
           ...
        }

    /* update position (raw i/o must be exact) */
=>  ASSERT((dev->raw_io) ? (wrt_len == length) : 1);

The device in question is /dev/hdb1, a rvm log partition, it is set to
be a raw device by set_dev_char() (rvm_io.c, line 134).


(gdb) p *dev
$2 = {name = 0x820c710 "/dev/hdb1", name_len = 10, handle = 3, num_bytes = {
    high = 0, low = 31467008}, raw_io = rvm_true, type = 24576, 
  read_only = rvm_false, iov = 0x82a7c60, iov_len = 7700, iov_cnt = 0, 
  io_length = 768, last_position = {high = 0, low = 456704}, 
  wrt_buf = 0x4016d000 "\001", wrt_buf_len = 262144, ptr = 0x401992d4 "", 
  buf_start = 0x40198fd4 "\034", buf_end = 0x401ad000 "", sync_offset = {
    high = 0, low = 457172}, pad_buf = 0x0, pad_buf_len = 0}

[root_at_xylophone srv]# ls -l /dev/hdb1
brw-rw----   1 root     disk       3,  65 May  6 04:32 /dev/hdb1

in set_dev_char():
    dev->type = mode;
    switch (mode)
        {
      case S_IFCHR:                     /* note raw io */
        dev->raw_io = rvm_true;
        break;
	/* Linux doesn't have BSD style raw character devices.
	   However, one can write to the block device directly.
	   This takes care, since we must sync it as if we 
	   do file IO.  We use dev->type == S_IFBLK 
	   to achieve this. The result could be good, since the
	   buffer cache will flush the blocks to the disk more 
	   efficiently than individual synchronous writes would 
	   take place.
                     */
      case S_IFBLK:  
	dev->raw_io = rvm_true;
	break;

My question is, is it true that write()s on block devices in Linux are
always exact (the number of bytes got written in one call is exactly
the same as what the caller instructs) ?  Or the assertion is too
conservative ? Or we should not let block device in Linux to be
(raw_io == rvm_true) ?

Thanks !

-- Clement

(Full stack trace of crashed codasrv follows)


======================================================================
Yui-wah LEE (Clement)                              Tel: (852)-26098412
Department of Computer Science and Engineering,    Fax: (852)-26035024 
The Chinese University of Hong Kong     Email: clement_at_cse.cuhk.edu.hk
======================================================================


#0  0x400d3684 in __syscall_sigsuspend ()
#1  0x400f7b4c in __DTOR_END__ ()
#2  0x804a634 in zombie (sig=11)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vice/srv.cc:344
#3  0x150739b0 in ?? ()
#4  0x815b043 in incr_write_partition (dev=0x82106a0, offset=0x82106ec, 
    start_addr=0x40198fd4 "\034", end_addr=0x401992d4 "")
    at /usr/src/redhat/BUILD/coda-4.6.1/rvm-src/rvm/../rvm/rvm_io.c:436
#5  0x815b822 in sync_dev (dev=0x82106a0)
    at /usr/src/redhat/BUILD/coda-4.6.1/rvm-src/rvm/../rvm/rvm_io.c:561
#6  0x814a9d7 in flush_log (log=0x8210680, count=0x82107a8)
    at /usr/src/redhat/BUILD/coda-4.6.1/rvm-src/rvm/../rvm/rvm_logflush.c:651
#7  0x8146008 in queue_tid (tid=0x820d440)
    at /usr/src/redhat/BUILD/coda-4.6.1/rvm-src/rvm/../rvm/rvm_trans.c:913
#8  0x8146331 in rvm_end_transaction (rvm_tid=0x15073b60, mode=flush)
    at /usr/src/redhat/BUILD/coda-4.6.1/rvm-src/rvm/../rvm/rvm_trans.c:1018
#9  0x8121338 in VBumpVolumeUsage (vp=0x8284fa8)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vol/volume.cc:1536
#10 0x811be1d in VGetVnode (ec=0x15073bf4, vp=0x8284fa8, vnodeNumber=1, unq=1, 
    locktype=1, ignoreIncon=0, ignoreBarren=0)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vol/cvnode.cc:630
#11 0x80538bd in GrabFsObj (fid=0x15073d94, volptr=0x15073c70, vptr=0x829c8c0, 
    lock=1, ignoreIncon=0, VolumeLock=0)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vice/srvproc.cc:2498
#12 0x8053a15 in GetFsObj (fid=0x15073d94, volptr=0x15073c70, vptr=0x829c8c0, 
    lock=1, VolumeLock=0, ignoreIncon=0, ignoreBQ=0)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vice/srvproc.cc:2538
#13 0x804ee17 in ViceGetAttr (RPCid=131093, Fid=0x15073d94, InconOK=0, 
    Status=0x15073d14, PrimaryHost=2310887903, PiggyBS=0x15073d08)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vice/srvproc.cc:350
#14 0x804e91e in ViceFetch (RPCid=131093, Fid=0x15073d94, BidFid=0x15073d88, 
    Request=FetchNoData, AccessList=0x15073d78, Status=0x15073d14, 
    PrimaryHost=2310887903, PiggyBS=0x15073d08, BD=0x0)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vice/srvproc.cc:204
#15 0x808d371 in _ViceFetch (_cid=131093, _reqbuffer=0x8288ec8, _bd=0x0)
    at vice.server.c:210
#16 0x80b8ecd in srv_ExecuteRequest (_cid=131093, _reqbuffer=0x8288ec8, 
    _bd=0x0) at vice.server.c:17032
#17 0x804b7f1 in ServerLWP (Ident=0xbffffd10)
    at /usr/src/redhat/BUILD/coda-4.6.1/coda-src/vice/srv.cc:693
#18 0x81895e9 in Create_Process_Part2 ()
    at /usr/src/redhat/BUILD/coda-4.6.1/lib-src/mlwp/lwp.c:1107
#19 0x818bad3 in L1 ()
#20 0x805304ec in ?? ()

SrvErr:
Assertion failed: file "/usr/src/redhat/BUILD/coda-4.6.1/rvm-src/rvm/../rvm/rvm_io.c", line 354
Received on 1998-09-04 06:55:49