From ache@deep-thought.demos.su  Mon Mar 20 17:27:59 1995
Received: from deep-thought.demos.su (deep-thought.demos.su [192.91.186.133]) by freefall.cdrom.com (8.6.10/8.6.6) with ESMTP id RAA19903 for <FreeBSD-gnats-submit@freebsd.org>; Mon, 20 Mar 1995 17:27:42 -0800
Received: by deep-thought.demos.su id EAA13069;
  (8.6.11/D) Tue, 21 Mar 1995 04:27:14 +0300
Message-Id: <199503210127.EAA13069@deep-thought.demos.su>
Date: Tue, 21 Mar 1995 04:27:14 +0300
From: ache@astral.msk.su
Reply-To: ache@astral.msk.su
To: FreeBSD-gnats-submit@freebsd.org
Subject: msync & munmap don't update mod times
X-Send-Pr-Version: 3.2

>Number:         260
>Category:       kern
>Synopsis:       msync and munmap don't bother to update mod times
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    asmodai
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Mar 20 17:30:01 1995
>Closed-Date:    Sun Jun 11 02:15:49 PDT 2000
>Last-Modified:  Sun Jun 11 02:20:11 PDT 2000
>Originator:     Andrey A. Chernov;  Black Mage
>Release:        FreeBSD 2.1.0-Development i386
>Organization:
Ha-olahm Yetzirah
>Environment:

	-current

>Description:

1) msync() & munmap()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.
			  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>How-To-Repeat:

---------------------------------- 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 = 60;

	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-current results:

Original file and time
1234567890123456789012345678901234567890123456789012345678901234567890
-rw-r--r--  1 ache  wheel  70 Mar  4 20:50 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

in -current. File modification times not updated at all.

>Fix:
	
	Unknown

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: davidg 
State-Changed-When: Mon Mar 20 19:02:04 PST 1995 
State-Changed-Why:  
The bug with msync(..., 0) was has been fixed, and the modification time 
is properly updated if anything is actually written to the file (just as it 
is supposed to work). 
State-Changed-From-To: closed->open 
State-Changed-By: ache 
State-Changed-When: Tue Mar 21 06:43:13 PST 1995 
State-Changed-Why:  
Sorry, David, you fix only one part of bug report, modification times 
still not updated by msync & munmap even with actual changes in the file 
present. Please, run test coming with this report. 
State-Changed-From-To: open->analyzed 
State-Changed-By: davidg 
State-Changed-When: Tue Mar 21 14:55:32 PST 1995 
State-Changed-Why:  
I ran the test program, and it's results indicated that the time is correct 
(to within one minute, which is all that ls reports). I have since looked 
carefully at the code and determined that the VOP_UPDATE call in the vnode 
pager is not be sufficient to update the time. I just spoke with Kirk on the 
phone about this...after a half hour of talking about how the VFS layer could 
be changed to better implement our vnode paging, the conclusion about how to 
solve this problem in the short term was to use VOP_SETATTR() at unmap time 
(if the file had been written to) to update the modification time. 
Responsible-Changed-From-To: freebsd-bugs->davidg 
Responsible-Changed-By: wollman 
Responsible-Changed-When: Thu Feb 8 08:46:52 PST 1996 
Responsible-Changed-Why:  
David did the analysis.  Is this problem still extant? 

From: Nick Hibma <nick.hibma@jrc.it>
To: freebsd-gnats-submit@freebsd.org, davidg@freebsd.org
Cc:  
Subject: Re: kern/260: msync and munmap don't bother to update mod times
Date: Mon, 19 Jul 1999 11:10:23 +0200

 Prod: has this been resolved, or been overtaken by 3.x/4.0 ?
 
 Description
 
 1) msync() & munmap()don't update file times, as manpage says:
 "The  msync system  call writes any modified pages back to the
 filesystem and updates the file modification time. "
 
 	http://www.freebsd.org/cgi/query-pr.cgi?pr=260
 
 
 Nick
 
 -- 
 Paranoid:
    perl -e 'use strict;' -e ...
 
 ISIS/STA, T.P.270, Joint Research Centre, 21020 Ispra, Italy
 
State-Changed-From-To: analyzed->suspended 
State-Changed-By: n_hibma 
State-Changed-When: Mon Jul 19 05:49:09 PDT 1999 
State-Changed-Why:  
According to David Greenman: 
It has not been resolved and there are no immediate plans to do anything 
about it. 

State-Changed-From-To: suspended->analyzed 
State-Changed-By: n_hibma 
State-Changed-When: Mon Jul 19 05:53:15 PDT 1999 
State-Changed-Why:  
David Greenman (the other one) says: 

Hmmm, let me contadict what I last said...I'm not actually sure that this 
is still an issue in 3.x/4.0. Better not update the PR. 

So, if someone could have a look whether or not the problem still is a problem, that would be appreciated. 
Responsible-Changed-From-To: davidg->asmodai 
Responsible-Changed-By: asmodai 
Responsible-Changed-When: Sun Jun 11 02:14:07 PDT 2000 
Responsible-Changed-Why:  
I'm verifying this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=260 
State-Changed-From-To: analyzed->closed 
State-Changed-By: asmodai 
State-Changed-When: Sun Jun 11 02:15:49 PDT 2000 
State-Changed-Why:  
This seems to have been fixed on 4.0 and onwards: 

msync with MS_ASYNC: 

[11:11] [asmodai@daemon] (16) $ ./a.out  
Original file and time 
1234567890123456789012345678901234567890123456789012345678901234567890 
-rw-r--r--  1 asmodai  asmodai  70 Jun 11 11:11 testfile 
After msync(..., 0) 
12345678901234567890 
234567890 
234567890123456789012345678901234567890 
-rw-r--r--  1 asmodai  asmodai  70 Jun 11 11:12 testfile 
After sleep(), msync(..., size) and close() 
12345678901234567890 
234567890 
234567890123456789012345678901234567890 
-rw-r--r--  1 asmodai  asmodai  70 Jun 11 11:12 testfile 

msync with MS_SYNC: 

[11:17] [asmodai@daemon] (19) $ ./a.out  
Original file and time 
1234567890123456789012345678901234567890123456789012345678901234567890 
-rw-r--r--  1 asmodai  asmodai  70 Jun 11 11:17 testfile 
After msync(..., 0) 
12345678901234567890 
234567890 
234567890123456789012345678901234567890 
-rw-r--r--  1 asmodai  asmodai  70 Jun 11 11:18 testfile 
After sleep(), msync(..., size) and close() 
12345678901234567890 
234567890 
234567890123456789012345678901234567890 
-rw-r--r--  1 asmodai  asmodai  70 Jun 11 11:18 testfile 

Looks good to me. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=260 
>Unformatted:





