Sad story: AdvFS "showstopper" (2)

From: Bernt Christandl <beb_at_rosat.mpe-garching.mpg.de>
Date: Mon, 17 Mar 1997 09:37:01 +0100

Okay managers,

several of you asked me for more details about "our" AdvFS-Bug.

So i'll send you this piece of code, that you can verify the problem
with AdvFS under digital unix 4.0* on your systems. Then you may
decide yourself, whether this is critical for you or not...

As you can see, only system-calls are used and the problem occurs
with "lseek(2)" and "write(2)".

With regards,

Bernt Christandl

-----------------------------------------------------------------------
- Bernt Christandl / Max Planck Institut f. Extraterrestrische Physik -
- D-85740 Garching / Phone: +49/89/3299-3342 / Fax: +49/89/3299-3569 -
- Internet: beb_at_xray.mpe.mpg.de -
-----------------------------------------------------------------------


----------- To see the bug do the following: -------------------

Please note: NOTHING dangerous will happen;
             "only" the contents of an example-file, that this
             program will create, is corrupted.


extract the following c-program and save it (e.g. as osftest.c);
then to compile and link this program do:

> cc -std -O -c osftest.c
> cc osftest.o -o advfs_bug

and to execute

> advfs_bug


This program uses only system calls, it creates a file of 18944 bytes,
fills the first blocks with 1.1 and then writes from address 6656 on
12000 bytes (representing 3000 floating point values going from 0.0 to 29.99
in steps of 0.01).

All system calls execute successfully. But when you do

> od -f veria.bdf

you see that the last value written is only: 2.4309999e+01.
This happens on any du-4.0*-directory

If you do the same in any UFS-Filessystem (e.g. /tmp) the program
works o.k. (last value = 2.9990000e+01)


/* ---------- begin of osftest.c ------------------------------------- */
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define O_write O_RDWR


long oskseek(fid, address)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE moves the file pointer.
         The argument fid is the file identification
         obtained from osdopen. The address defines
         the pointer position in bytes relative to:
         start of the file, current position or end of the file as
         defined by the variable mode (FILE_START, FILE_CURRENT, FILE_END).
         (see midas/osparms.h). (i.e. : an address=0 and OS_START set means
         first byte of the file).
.RETURNS Upon successful completion, the resulting pointer position
.RETURNS measured in bytes is returned, in case of error -1L.
.REMARKS System dependencies:
 -- UNIX: lseek(2)
------------------------------------------------------------*/
int fid; /* file identification */
long address; /* file pointer */
{
int mode;
off_t ret;

mode = SEEK_SET;

if ((ret = lseek(fid, (off_t)address, mode)) == (off_t)-1)
   printf("oskseek: error...\n");
else
   printf("oskseek: addr = %ld, retpntr = %ld\n",address,(long)ret);

return((long)ret);
}


main()

{
char *mypntr;
char *cbuf;

int size, status, kk;
int fid, nr, n, allbytes;
long int addr;

float *fpntr, fbuf[512];


for (nr=0; nr<512; nr++) fbuf[nr] = 1.1;
cbuf = (char *)fbuf;

/* create file on disk with size = 18944 bytes */

fid = creat("veria.bdf",0666);
if (fid < 0)
   printf("creat: problems with creat...\n");
n = 18944;
addr = n - 1; /* move to last byte */
status = oskseek(fid,addr);
if (status != -1)
   {
   char c;

   c = ' ';
   n = 1; /* write 1 byte */
   if ((kk = write(fid,&c,(unsigned int)n)) == -1)
      printf("write failed...\n");
   else
      printf("write: nobyt = %d, ret = %d\n",n,kk);
   }
if (close(fid) < 0) printf("'roblems with close...\n");


fid = open("veria.bdf",O_write,0666);


allbytes = 12000;

mypntr = (char *) malloc((size_t) allbytes);
printf("mypntr = %x\n",mypntr);

fpntr = (float *) mypntr;
for (nr=0; nr<3000; nr++)
   {
   *fpntr++ = 0.01 * nr;
   }



addr = 0;
n = 512;
status = oskseek(fid,addr);
if (status != -1)
   {
   if ((kk = write(fid,cbuf,(unsigned int)n)) == -1)
      printf("write failed...\n");
   else
      printf("write: nobyt = %d, ret = %d\n",n,kk);
   }

addr += 512; /* 512 */
n = 2048;
status = oskseek(fid,addr);
if (status != -1)
   {
   if ((kk = write(fid,cbuf,(unsigned int)n)) == -1)
      printf("write failed...\n");
   else
      printf("write: nobyt = %d, ret = %d\n",n,kk);
   }

addr +=2048; /* 2560 */
n = 2048;
status = oskseek(fid,addr);
if (status != -1)
   {
   if ((kk = write(fid,cbuf,(unsigned int)n)) == -1)
      printf("write failed...\n");
   else
      printf("write: nobyt = %d, ret = %d\n",n,kk);
   }

addr +=2048; /* 4608 */
n = 2048;
status = oskseek(fid,addr);
if (status != -1)
   {
   if ((kk = write(fid,cbuf,(unsigned int)n)) == -1)
      printf("write failed...\n");
   else
      printf("write: nobyt = %d, ret = %d\n",n,kk);
   }

addr +=2048; /* 6656 */
status = oskseek(fid,addr);
if (status != -1)
   {
   if ((kk = write(fid,mypntr,(unsigned int)allbytes)) == -1)
      printf("write failed...\n");
   else
      printf("write: nobyt = %d, ret = %d\n",allbytes,kk);
   }

close(fid);

}
/* ------------ end of osftest.c ------------------------------------- */
Received on Mon Mar 17 1997 - 10:17:04 NZST

This archive was generated by hypermail 2.4.0 : Wed Nov 08 2023 - 11:53:36 NZDT