public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* another nfs puzzle
@ 2005-12-06 22:04 Kenny Simpson
  2005-12-07  3:24 ` Trond Myklebust
  2005-12-07 14:01 ` Peter Staubach
  0 siblings, 2 replies; 12+ messages in thread
From: Kenny Simpson @ 2005-12-06 22:04 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 777 bytes --]

Hi again,
  I am seeing some odd behavior with O_DIRECT.  If a file opened with O_DIRECT has a page mmap'd,
and the file is extended via pwrite, then the mmap'd region seems to get lost - i.e. it neither
takes up system memory, nor does it get written out.

The attached file demonstrates this.
Compile with -DABUSE to trigger the bad case.
This behavior does not happen with an ext3 partition.

ethereal shows the behavior to be a large amount of block reads, with single byte writes every so
often.  Viewing the resultant file from other hosts or even the original host shows the file is
grown, but is zero-filled, not 'a'-filled.

-Kenny



		
__________________________________________ 
Yahoo! DSL – Something to write home about. 
Just $16.99/mo. or less. 
dsl.yahoo.com 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 862959384-dtest.c --]
[-- Type: text/x-csrc; name="dtest.c", Size: 1765 bytes --]

#define _GNU_SOURCE

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

#include <stdio.h>
#include <string.h>

/*
 * the 'abusive' case is where we
 *   grow the file via pwrite
 *   unmap the previous mapping,
 *   do the new mapping
 *
 * the non-abusive case we
 *   unmap the previous mapping
 *   grow the file
 *   do the new mapping
 *
 * the difference being that in the abusive case,
 * we maintain a mapping during the pwrite.
 *
 * If we grow the file via pwrite and maintain a
 * mapping, the mapped pages are never written out.
 *
 * If we either grow the file via ftruncate or remove
 * old mappings before growing the file, then all is
 * fine.
 */

#ifdef ABUSE
#define UNMAP_AFTER() munmap(mapping, size)
#define UNMAP_BEFORE() struct eat_semi
#else
#define UNMAP_AFTER() struct eat_semi
#define UNMAP_BEFORE() munmap(mapping, size)
#endif

int main(int argc, char* argv[])
{
  int fd;
  unsigned int const size = 4096 * 1024;
  unsigned int offset = 0;

  if (argc != 2) {
    printf("usage: %s <filename>\n", argv[0]);
    return 0;
  }

  fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE | O_DIRECT, 0644);
  if (fd < 0) {
    perror("open");
    return 0;
  }

  pwrite64(fd, "", 1, offset + size);
  //ftruncate64(fd, offset + size);
  char* mapping = (char*)mmap64(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
  memset(mapping, 'a', size);
  UNMAP_BEFORE();

  for (;;) {
    offset += size;

    pwrite64(fd, "", 1, offset + size);
    //ftruncate64(fd, offset + size);
    UNMAP_AFTER();
    mapping = (char*)mmap64(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
    memset(mapping, 'a', size);
    UNMAP_BEFORE();
  }

  close(fd);

  return 0;
}

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-12-07 16:39 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-06 22:04 another nfs puzzle Kenny Simpson
2005-12-07  3:24 ` Trond Myklebust
2005-12-07 14:50   ` Kenny Simpson
2005-12-07 14:01 ` Peter Staubach
2005-12-07 14:11   ` Trond Myklebust
2005-12-07 14:18     ` Peter Staubach
2005-12-07 14:34       ` Trond Myklebust
2005-12-07 15:34         ` Peter Staubach
2005-12-07 15:41           ` Trond Myklebust
2005-12-07 15:56             ` Peter Staubach
2005-12-07 16:09               ` Trond Myklebust
2005-12-07 16:39                 ` Peter Staubach

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox