title: Why does mmap() fail with ENOMEM on a 1TB sparse file?
body: <p>I've been working with large sparse files on openSUSE 11.2 x86_64. When I try to mmap() a 1TB sparse file, it fails with ENOMEM. I would have thought that the 64 bit address space would be adequate to map in a terabyte, but it seems not. Experimenting further, a 1GB file works fine, but a 2GB file (and anything bigger) fails. I'm guessing there might be a setting somewhere to tweak, but an extensive search turns up nothing.</p>
  
  <p>Here's some sample code that shows the problem - any clues?</p>
  
  <pre><code>#include &lt;errno.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/mman.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  
  int main(int argc, char *argv[]) {
      char * filename = argv[1];
      int fd;
      off_t size = 1UL &lt;&lt; 40; // 30 == 1GB, 40 == 1TB
  
      fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
      ftruncate(fd, size);
      printf("Created %ld byte sparse file\n", size);
  
      char * buffer = (char *)mmap(NULL, (size_t)size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
      if ( buffer == MAP_FAILED ) {
          perror("mmap");
          exit(1);
      }
      printf("Done mmap - returned 0x0%lx\n", (unsigned long)buffer);
  
      strcpy( buffer, "cafebabe" );
      printf("Wrote to start\n");
  
      strcpy( buffer + (size - 9), "deadbeef" );
      printf("Wrote to end\n");
  
      if ( munmap(buffer, (size_t)size) &lt; 0 ) {
          perror("munmap");
          exit(1);
      }
      close(fd);
  
      return 0;
  }
  </code></pre>