misc/64816: mmap and/or ftruncate does not work correctly on nfs mounted file systems

Patrick Mackinlay patrick at spacesurfer.com
Sat Mar 27 11:00:31 PST 2004


>Number:         64816
>Category:       misc
>Synopsis:       mmap and/or ftruncate does not work correctly on nfs mounted file systems
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 27 11:00:31 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Patrick Mackinlay
>Release:        4.9 (5.2.1 also tried and found not to work)
>Organization:
SpaceSurfer Ltd.
>Environment:
FreeBSD ws3.spacesurfer.com 4.9-STABLE FreeBSD 4.9-STABLE #0: Sat Feb 14 18:01:36 GMT 2004     pim at ws3.uknet.spacesurfer.com:/usr/obj/usr/src/sys/WS3  i386

>Description:
When using a file on an nfs mounted region, that has its last bytes memory mapped with mmap and then using ftruncate to increase the size of the file, the ftruncate call will result in whatever changes you have made via the mmaped area not being synced to disk (unless you use an msync or mmunmp before the ftruncate call).
The c progam below demonstrates the problem. The files tested on where on a linux 2.4 nfs server and the test program worked fine on linux 2.4 nfs clients.

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

void error(char *msg)
 {
 fprintf(stderr, "Error: %s\nSystem error %d: %s\n", msg, errno, strerror(errno));
 exit(-1);
 }

#define SZ 1024 // Less than page size

int main(int argn, char *argv[])
 {
 int fd;
 char buffer[SZ];
 char *map;

 if (argn!=2)
  {
  fprintf(stderr, "Usage:\n %s [filename]\n", argv[0]);
  exit(-1);
  }

 memset(buffer, 0, SZ);

 fd=open(argv[1], O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
 if (fd==-1) error("Could not create file");

 if (write(fd, buffer, SZ)!=SZ) error("Could not write buffer");

 map=mmap(NULL, SZ, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 if (map==MAP_FAILED) error("Map failed");
 map[SZ-1]=1;

 if (ftruncate(fd, SZ+1)!=0) error("Could not truncate file");
 
 if (map[SZ-1]==1)
  printf("Test passed\n");
 else
  printf("Test failed\n");

 exit(0);
 } 

>How-To-Repeat:
      
>Fix:
      
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list