Skip site navigation (1)Skip section navigation (2)
Date:      Sat,  4 Mar 1995 21:07:43 +0300
From:      "Andrey A. Chernov, Black Mage" <ache@astral.msk.su>
To:        current@FreeBSD.org, David Greenman <davidg@Root.COM>, dyson@FreeBSD.org
Cc:        Andy Vasiliev <andy@demos.su>
Subject:   Msync() is double broken
Message-ID:  <MHlnAMl484@astral.msk.su>

next in thread | raw e-mail | index | archive | help
Here small test program to demonstrate two bugs with msync:

1) msync(..., 0) is broken
2) msync() don't update file times, as manpage sayd:
       The  msync system  call writes any modified pages back to
       the filesystem and updates the file modification time.
			  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

---------------------------------- cut here ----------------------------
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <stdio.h>

static char             ICDactpath[] = "testfile";
static char             *ICDactpointer;
static int              ICDactfd;
static int              ICDactsize;

#if	defined(MAP_FILE)
#define MAP__ARG	(MAP_FILE | MAP_SHARED)
#else
#define MAP__ARG	(MAP_SHARED)
#endif	/* defined(MAP_FILE) */

char *
ICDread()
{
    struct stat		Sb;
    int i;

    if ((ICDactfd = open(ICDactpath, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
	perror("open");
	fprintf(stderr, "read: cant open %s\n", ICDactpath);
	exit(1);
    }
    for (i = 0; i < 7; i++)
	write(ICDactfd, "1234567890", 10);
    if (close(ICDactfd) < 0) {
	perror("close");
	fprintf(stderr, "Close: cant close %s\n", ICDactpath);
	exit(1);
    }

    if ((ICDactfd = open(ICDactpath, O_RDWR)) < 0) {
	perror("open");
	fprintf(stderr, "read: cant open %s\n", ICDactpath);
	exit(1);
    }

    if (fstat(ICDactfd, &Sb) < 0) {
	perror("fstat");
	fprintf(stderr, "read: cant fstat %d %s\n", ICDactfd, ICDactpath);
	exit(1);
    }
    ICDactsize = Sb.st_size;
    ICDactpointer = mmap((caddr_t)0, ICDactsize, PROT_READ|PROT_WRITE,
			MAP__ARG, ICDactfd, (off_t)0);
    if (ICDactpointer == (char *)-1) {
	perror("mmap");
	fprintf(stderr, "read: cant mmap %d %s\n", ICDactfd, ICDactpath);
	exit(1);
    }

    return ICDactpointer;
}

ICDclose()
{
    if (ICDactpointer) {
	if (msync(ICDactpointer, ICDactsize) < 0) {
	    perror("msync");
	    fprintf(stderr, "Close: cant msync %s in closeactive()\n",  ICDactpath);
	}

	if (munmap(ICDactpointer, ICDactsize) < 0) {
	    perror("munmap");
	    fprintf(stderr, "Close: cant munmap\n", ICDactpath);
	}
	ICDactpointer = NULL;
	if (close(ICDactfd) < 0) {
	   perror("close");
	   fprintf(stderr, "Close: cant close %s\n", ICDactpath);
	   exit(1);
	}
    }
}

ICDwrite()
{
    /* No-op. */
		    /* ICDactsize */
    if (msync(ICDactpointer, 0) < 0) {
	perror("msync");
	fprintf(stderr, "Write: cant msync %s\n", ICDactpath);
    }
}

spy() {
	system("cat testfile; echo; ls -l testfile");
}

main()
{
	char *file_p;
	int to_sleep = 2;

	file_p = ICDread();

	fprintf(stderr, "Original file and time\n");
	spy();
	*(file_p + 20) = '\n';
#if 0
	fprintf(stderr, "After 1st write to mapped region\n");
	spy();
#endif
	sleep(to_sleep);
	*(file_p + 30) = '\n';
#if 0
	fprintf(stderr, "After 2nd write to mapped region and sleep()\n");
	spy();
#endif
	ICDwrite();
	fprintf(stderr, "After msync(..., 0)\n");
	spy();
	sleep(to_sleep);
	ICDclose();
	fprintf(stderr, "After sleep(), msync(..., size) and close()\n");
	spy();
	unlink(ICDactpath);
}
---------------------------------- cut here ----------------------------


Here FreeBSD 1.x results:

Original file and time
1234567890123456789012345678901234567890123456789012345678901234567890
-rw-rw-r--    1 ache           70 Mar  4 20:50 testfile
After msync(..., 0)
12345678901234567890
234567890
234567890123456789012345678901234567890
-rw-rw-r--    1 ache           70 Mar  4 20:50 testfile
After sleep(), msync(..., size) and close()
12345678901234567890
234567890
234567890123456789012345678901234567890
-rw-rw-r--    1 ache           70 Mar  4 20:50 testfile

As you can see, msync(..., 0) works, but modification times
_not_ updated. It can affects some programs which expects it.

Here FreeBSD-current results (even worse):

Original file and time
1234567890123456789012345678901234567890123456789012345678901234567890
-rw-r--r--  1 ache  wheel  70 Mar  4 20:50 testfile
msync: Invalid argument
Write: cant msync testfile
After msync(..., 0)
12345678901234567890
234567890
234567890123456789012345678901234567890
-rw-r--r--  1 ache  wheel  70 Mar  4 20:50 testfile
After sleep(), msync(..., size) and close()
12345678901234567890
234567890
234567890123456789012345678901234567890
-rw-r--r--  1 ache  wheel  70 Mar  4 20:50 testfile

As you can see, msync(..., 0) works, but returns -1 and EINVAL
in -current. File modification times not updated too.

Any ideas how to fight it?

-- 
Andrey A. Chernov        : And I rest so composedly,  /Now, in my bed,
ache@astral.msk.su       : That any beholder  /Might fancy me dead -
FidoNet: 2:5020/230.3    : Might start at beholding me,  /Thinking me dead.
RELCOM Team,FreeBSD Team :         E.A.Poe         From "For Annie" 1849



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?MHlnAMl484>