xfs
[Top] [All Lists]

XFS bug with ftruncate, mmap and holes.

To: linux-xfs@xxxxxxxxxxx
Subject: XFS bug with ftruncate, mmap and holes.
From: Keith Owens <kaos@xxxxxxx>
Date: Mon, 28 Jan 2002 15:27:54 +1100
Cc: lm@xxxxxxxxxxxx
Sender: owner-linux-xfs@xxxxxxxxxxx
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.


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