From owner-freebsd-bugs Tue Sep 12 6:10:12 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 48C0D37B424 for ; Tue, 12 Sep 2000 06:10:01 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id GAA11495; Tue, 12 Sep 2000 06:10:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from mv.kmost.express.ru (mv.kmost.express.ru [212.24.37.110]) by hub.freebsd.org (Postfix) with ESMTP id 50A0E37B422 for ; 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: Date: Tue, 12 Sep 2000 17:05:39 +0400 From: kmv@express.ru Reply-To: kmv@express.ru To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/21222: wrong behavior of concurrent mmap()s on NFS files Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 21222 >Category: kern >Synopsis: wrong behavior of concurrent mmap()s on NFS files >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Sep 12 06:10:01 PDT 2000 >Closed-Date: >Last-Modified: >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 #include #include #include #include #include #include #include #include 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 #include #include #include #include #include #include #include #include #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: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message