Phanomen with using write() function on AIX when no space left

Phanomen with using write() function on AIX when no space left

Post by Markus Aigne » Fri, 21 Mar 2003 16:02:49



Hello,

I want to use mmap() on AIX 4.3.3

When no space lefts on device I get a buserror.

Following you can see my testprogram:

***************************************************************

#include <stdio.h>
#include <errno.h>
#include <stropts.h>
#include <memory.h>

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc, char* argv[])
{
        int fdout;
        FILE *fdoutFile;
        void *dst;

        int length = 4000;

        umask(0);

        /* open file */
        if((fdout = open("./tempfile", O_RDWR | O_CREAT | O_TRUNC, 0644)) <
0)
        {
                return 1;
        }

        /* open a FILE from the int value */
        fdoutFile = fdopen(fdout,"w+");

        /* set buffering to 0 */
        setvbuf(fdoutFile,NULL,_IONBF,0);

        /* set position of file to length */
        if(fseek(fdoutFile,length,SEEK_SET) != NULL)
        {
                fprintf(stderr,"FSEEK ERROR\n");
                return 1;
        }

        /* write one byte to check if some space is left */
        if(fwrite("",1,1,fdoutFile) < 1)
        {
                fprintf(stderr,"FWRITE ERROR\n");
                return 1;
        }

        /* set position of file to length */
        if(lseek(fdout, length, SEEK_SET) == -1)
        {
                fprintf(stderr,"LSEEK ERROR\n");
                return 1;
        }

        /* write one byte to check if some space is left */
        if(write(fdout,"",1) != 1)
        {
                fprintf(stderr,"WRITE ERROR\n");
                fprintf(stderr,"errno: %d\n",errno);
                return 1;
        }

        if((dst=mmap(0,length, PROT_READ | PROT_WRITE, MAP_SHARED, fdout,0))
==(caddr_t)-1)
        {
                fprintf(stderr,"MMAP ERROR\n");
                return 1;
        }

        char * temp = new char[length];
        memset(temp,0,length);
        memcpy(dst,temp,length);

        return 0;

Quote:}

*************************************************************************

The programm checks this Phanomen with write() and fwrite().
When length is 4000, both write functions came back with an error (that is
what I want).

When length is 4100, both write functions came back with ok. The problem is,
that the memcpy at the end of the program terminates with a buserror.

When length is 8000, both write functinos came back with an error (that is
what I want).

Can anybody tell me if this is a bug in my program, or a bug in the
operating system? Have anybody an idea for a workaround?

Thanks,

Aignerma

 
 
 

Phanomen with using write() function on AIX when no space left

Post by Andrew Giert » Fri, 21 Mar 2003 18:35:12


 Markus> Hello,
 Markus> I want to use mmap() on AIX 4.3.3

 Markus> When no space lefts on device I get a buserror.

this is correct behaviour (it's one of the reasons why writing files
via mmap requires significant care).

What's happening is this: by writing the last byte of the file you
extend the file to the desired length, but you _don't_ allocate blocks
for all the intermediate space that you have skipped over. You have
effectively created a file with a "hole" at the beginning. (The initial
writes will only fail if there isn't sufficient space to allocate the
one block required at the end of the file.)

Then, when you write to the file via the mapped region, the system
allocates space for those pages that you actually write on. But it has
no way of returning an error code to your program when it runs out of
space to do so, so instead it generates a SIGBUS when it's unable to
produce a valid backing page for a page you've referenced via the
mapping.

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>