From kmv@mv.kmost.express.ru  Tue Sep 12 06:05:44 2000
Return-Path: <kmv@mv.kmost.express.ru>
Received: from mv.kmost.express.ru (mv.kmost.express.ru [212.24.37.110])
	by hub.freebsd.org (Postfix) with ESMTP id 50A0E37B422
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 12 Sep 2000 06:05:42 -0700 (PDT)
Received: from kmv by mv.kmost.express.ru with local (Exim 3.10 #7)
	id 13Ypkp-000NHB-00
	for FreeBSD-gnats-submit@freebsd.org; Tue, 12 Sep 2000 17:05:39 +0400
Message-Id: <E13Ypkp-000NHB-00@mv.kmost.express.ru>
Date: Tue, 12 Sep 2000 17:05:39 +0400
From: kmv@express.ru
Sender: Maxim Katargin <kmv@mv.kmost.express.ru>
Reply-To: kmv@express.ru
To: FreeBSD-gnats-submit@freebsd.org
Subject: wrong behavior of concurrent mmap()s on NFS files
X-Send-Pr-Version: 3.2

>Number:         21222
>Category:       kern
>Synopsis:       [nfs] wrong behavior of concurrent mmap()s on NFS files
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 12 06:10:01 PDT 2000
>Closed-Date:    Fri Nov 16 18:30:10 UTC 2007
>Last-Modified:  Fri Nov 16 18:30:10 UTC 2007
>Originator:     Maxim Katargin
>Release:        FreeBSD 4.0-RELEASE i386
>Organization:
>Environment:

    client  : FreeBSD 4.0-RELEASE i386,
    servers : 3.5-STABLE FreeBSD i386, 4.0-STABLE FreeBSD i386

	

>Description:

    The following sequence of moves gets quite different results when performed
on local filesystem and when performed on NFS:
   1. process_1 opens a file read-only, does mmap() call on it (readonly).
   2. process_2 opens the same file read-write, uses ftruncate() on it to
      increase file length, does mmap() call on it (read-write), writes
      certain data into the memory mapped area near the end of the file, does
      munmap() and exits.
   3. process_1 does munmap() and exits.

    If the mmap()-ed file is on local filesystem, everything works just as we
would expect it to: after the mentioned above sequence, the file appeares to be
longer (correctly increased by process_2) and contains the data written by
process_2 near the end of file. But if the mmap()-ed file is on NFS-mounted
filesystem, the result is quite different: the file length appears to be correct
(increased by process_2), but the data, written by the process_2 into the area
near the end of file, seems to be (partially) nullified.
    Experiments show that data loss occures in the area between the the end of
initial file (before ftruncate()) and the nearest 4k-block boundary above.

>How-To-Repeat:

	

    Compile both of the supplied programs. Run first program; it will perform
step (1) from the above sequence and wait for the input. Meanwhile, run the
second program; it will perform step (2). Then, give some input to the first
program, and it will terminate [step (3)].

The first program:
----------------------------
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <sys/types.h>
#include <sys/mman.h>

#include <stdio.h>

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

char *filename = "testfile";

int main() {

  int hdl;
  int filesize;
  char *mapedfile;
  struct stat filestat; 

  hdl = open(filename,O_RDONLY);
  if (hdl < 0) {
    perror("Cannot open file");
    exit (1);
  }

  if (fstat(hdl,&filestat) == -1) {
    perror("Cannot get file status");
    exit (1);
  };
  
  filesize = filestat.st_size;

  printf("filename: %s\nfilesize: %d\n",filename,filesize);

  mapedfile = (char *)mmap((caddr_t)0, filesize, PROT_READ, MAP_PRIVATE, hdl, 0); 
  if (mapedfile == MAP_FAILED) {
    perror("Cannot map file");
    exit (1);
  }
  
  write(1,mapedfile,filesize);

  getchar();

  if (munmap(mapedfile, filesize) == -1) {
    perror("Cannot unmap file");
    exit (1);
  }

  close (hdl);
  exit (0);
}
------------------------------ 

The second program:
-----------------------------
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <sys/types.h>
#include <sys/mman.h>

#include <stdio.h>

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

#define TAIL 256

char *filename = "testfile";

int main() {

  int hdl;
  int filesize, newfilesize;
  char *mapedfile;
  struct stat filestat; 

  hdl = open(filename,O_RDWR);
  if (hdl < 0) {
    perror("Cannot open file");
    exit (1);
  }

  if (fstat(hdl,&filestat) == -1) {
    perror("Cannot get file status");
    exit (1);
  };
  
  filesize    = filestat.st_size;
  newfilesize = filesize + TAIL;

  printf("filename: %s\nfilesize: %d\nnewfilesize: %d\n",filename,filesize,newfilesize);

  if (ftruncate(hdl,newfilesize) == -1) {
    perror("Cannot extend a file");
    exit (1);
  }
  
  mapedfile = (char *)mmap((caddr_t)0, newfilesize, PROT_READ|PROT_WRITE, MAP_SHARED, hdl, 0); 
  if (mapedfile == MAP_FAILED) {
    perror("Cannot map file");
    exit (1);
  }
  
  memset(mapedfile+filesize,'X',TAIL);

  if (munmap(mapedfile, newfilesize) == -1) {
    perror("Cannot unmap file");
    exit (1);
  }

  close (hdl);
  exit (0);
}
---------------------------------

>Fix:

	
    Unknown.


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->dillon 
Responsible-Changed-By: silby 
Responsible-Changed-When: Tue Jan 8 17:59:13 PST 2002 
Responsible-Changed-Why:  
Over to Mr. NFS, Dillon 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=21222 
Responsible-Changed-From-To: dillon->freebsd-bugs 
Responsible-Changed-By: keramida 
Responsible-Changed-When: Sat Feb 22 18:15:39 PST 2003 
Responsible-Changed-Why:  
Back to the free pool. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=21222 
State-Changed-From-To: open->feedback 
State-Changed-By: kmacy 
State-Changed-When: Fri Nov 16 18:28:07 UTC 2007 
State-Changed-Why:  

This sounds like a bug fsx would catch. Are you still seeing this? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=21222 
State-Changed-From-To: feedback->closed 
State-Changed-By: kmacy 
State-Changed-When: Fri Nov 16 18:29:40 UTC 2007 
State-Changed-Why:  

This hasn't been seen recently and submitter mail bounces. 

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