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>
