xfs
[Top] [All Lists]

Re: XFS bug with ftruncate, mmap and holes.

To: Keith Owens <kaos@xxxxxxx>
Subject: Re: XFS bug with ftruncate, mmap and holes.
From: Stephen Lord <lord@xxxxxxx>
Date: Mon, 28 Jan 2002 07:11:17 -0600
Cc: linux-xfs@xxxxxxxxxxx, lm@xxxxxxxxxxxx
References: <3615.1012192074@xxxxxxxxxxxxxxxxxxxxx>
Sender: owner-linux-xfs@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.7) Gecko/20011226
Keith Owens wrote:

2.4.17-xfs t-o-t ptools (Mon Jan 28 04:15:18 UTC 2002). gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-81)
glibc-2.2.2-10

This program mimics the behaviour of BitKeeper mdbm code when expanding
the database, it hits a bug on XFS.

== xfs-bug.c

#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>

#define size 4096
static const char name[] = "db_main";

int main(void)
{
        int fd;
        void *m;
        time_t t;
        struct tm tm;
        fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0666);
        // write(fd, name, 1);          /* 1 */
        // lseek(fd, size, SEEK_SET);   /* 2 */
        // write(fd, name, 1);          /* 3 */
        ftruncate(fd, size);
        m = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        memset(m, 'A', size);
        t = time(NULL);
        tm = *localtime(&t);
        strcpy(m, asctime(&tm));
        fsync(fd);
        munmap(m, size);
        close(fd);
        return(0);
}

gcc xfs-bug.c -o xfs-bug
../xfs-bug
cat db_main

Make a note of the timestamp then do a clean shutdown and reboot.  cat
db_main, it will be garbage or it will contain data from a previous
run.

Expanding a file with ftruncate is undefined behaviour,
http://www.db.opengroup.org/cgi-bin/dbcgi?TPL=sd_fileframe&dir=xsh&file=ftruncate&TOKEN=EWJO&vendor1=1&EWJO=1.

 "If the file previously was larger than length, the extra data is
 discarded. If it was previously shorter than length, some systems
 that conform to the Single UNIX Specification, Version 2 may change
 the file or increase its size. If the file is extended, the extended
 area appears as if it were zero-filled."

Note "may change the file or increase its size", ftruncate upwards is
not guaranteed to work.  The mdbm code is violating standards.

Uncomment lines 2 and 3 so the file is extended first then truncated
down.  The code now conforms to standards but XFS still has a bug.  The
file on disk is valid but after a clean shutdown and reboot it contains
other data (check the timestamp).

Only after uncommenting line 1 as well as 2,3 does XFS generate clean
data after a reboot.  Looks like a nasty interaction between mmap and
files with holes in them.  What is strange is that without lines 1,2,3
the code writes valid data.  After a long delay or a clean shutdown the
data suddenly gets changed.

Do we have any indication if this is something which has 'appeared' at some point, or has been around for a while? Looks like a page dirtied only by mmap is not getting flushed by this code. Other user's of mmap (such as the loader) appear not
to have problems like this.

I will take a look, but I suspect an msync before unmap will work around this for
now (not tested yet).

Steve



<Prev in Thread] Current Thread [Next in Thread>