Reputation: 23
I am trying to create a memory mapped file using MAP_SHARED. I run into issues when the file size reaches 2gb. The code pasted below is what I am using (as a test).
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#define MY_FILE "/dev/shm/mmap_test"
#define BLOCK_SIZE (1024*1024)
#define NUM_FILES 1
void mk_file(int f_num)
{
uint64_t len = 0;
int fd, j, k;
char tmp_file[1024], *x, *rr_addr;
// Open file in /dev/shm
sprintf(tmp_file, "%s%d", MY_FILE, f_num);
fd = open(tmp_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd == -1)
{
perror("file open");
exit(-1);
}
// 16Gb file
len = 16UL * 1024 * 1024 * 1024;
printf("len: %ld Gb\n", len/(1024*1024*1024));
printf("Mapping %ld blocks\n", len/BLOCK_SIZE);
for (j = 0; j < len/BLOCK_SIZE; j++) {
// Increase the file size
ftruncate(fd, ((j + 1) * BLOCK_SIZE));
// Just mmap memory... don't have file backing
//rr_addr = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
// MMAP a region to the file at a given offset
rr_addr = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd, (j * BLOCK_SIZE));
if (rr_addr == MAP_FAILED) {
perror("mmap error");
printf("INDEX: %d\n", j);
exit(-1);
}
// Write to every byte of allocated memory
x = (char *) rr_addr;
for (k = 0; k < BLOCK_SIZE; k++)
{
*x = '1';
x++;
}
}
return;
}
int main(int argc, char **argv)
{
uint64_t i;
for (i = 0; i < NUM_FILES; i++)
mk_file(i);
return 0;
}
In the code above, I get a bus error when the offset in the file reaches 2gb. These are the things I have tried:
I am wondering if this is an issue in the linux kernel? Has anyone tried mmap'ing a single file using MAP_SHARED greater than 2gb and used (read/write to) it successfully?
Upvotes: 2
Views: 2288
Reputation: 20163
I believe the problem is that j
is an int
. When j
hits large values, (j + 1) * BLOCK_SIZE
overflows and your ftruncate
call does not do what you intend. Checking the return value from ftruncate
should confirm this.
The mmap man page specifically calls out SIGBUS
as meaning that the attempted access is not backed by the file.
Upvotes: 2
Reputation: 7472
I am not sure if this helps in your case. When we had problems with big files the following helped. We have put the macro:
#define _FILE_OFFSET_BITS 64
before including standard headers. You can define it also on command line when invoking gcc.
Upvotes: 0