diff --git a/program/src/rrd_open.c b/program/src/rrd_open.c
index 78d517458861a5fac58b5e9e9064fcf43f12e537..9c839a157b9f3ac3a77807dc28195305ed257b4a 100644 (file)
--- a/program/src/rrd_open.c
+++ b/program/src/rrd_open.c
if (rdwr & RRD_READONLY) {
flags |= O_RDONLY;
#ifdef HAVE_MMAP
+# if !defined(AIX)
rrd_simple_file->mm_flags = MAP_PRIVATE;
+# endif
# ifdef MAP_NORESERVE
rrd_simple_file->mm_flags |= MAP_NORESERVE; /* readonly, so no swap backing needed */
# endif
rrd_file->file_len = statb.st_size;
} else {
rrd_file->file_len = newfile_size;
+#ifdef HAVE_POSIX_FALLOCATE
+ if (posix_fallocate(rrd_simple_file->fd, 0, newfile_size) == -1) {
+ rrd_set_error("posix_fallocate '%s': %s", file_name,
+ rrd_strerror(errno));
+ goto out_close;
+ }
+#else
lseek(rrd_simple_file->fd, newfile_size - 1, SEEK_SET);
if ( write(rrd_simple_file->fd, "\0", 1) == -1){ /* poke */
rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
goto out_close;
}
lseek(rrd_simple_file->fd, 0, SEEK_SET);
+#endif
}
#ifdef HAVE_POSIX_FADVISE
/* In general we need no read-ahead when dealing with rrd_files.
*/
#ifdef HAVE_MMAP
+#ifndef HAVE_POSIX_FALLOCATE
+ /* force allocating the file on the underlaying filesystem to prevent any
+ * future bus error when the filesystem is full and attempting to write
+ * trough the file mapping. Filling the file using memset on the file
+ * mapping can also lead some bus error, so we use the old fashioned
+ * write().
+ */
+ if (rdwr & RRD_CREAT) {
+ char buf[4096];
+ unsigned i;
+
+ memset(buf, DNAN, sizeof buf);
+ lseek(rrd_simple_file->fd, offset, SEEK_SET);
+
+ for (i = 0; i < (newfile_size - 1) / sizeof buf; ++i)
+ {
+ if (write(rrd_simple_file->fd, buf, sizeof buf) == -1)
+ {
+ rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
+ goto out_close;
+ }
+ }
+
+ if (write(rrd_simple_file->fd, buf,
+ (newfile_size - 1) % sizeof buf) == -1)
+ {
+ rrd_set_error("write '%s': %s", file_name, rrd_strerror(errno));
+ goto out_close;
+ }
+
+ lseek(rrd_simple_file->fd, 0, SEEK_SET);
+ }
+#endif
+
data = mmap(0, rrd_file->file_len,
rrd_simple_file->mm_prot, rrd_simple_file->mm_flags,
rrd_simple_file->fd, offset);
goto out_close;
}
rrd_simple_file->file_start = data;
- if (rdwr & RRD_CREAT) {
- memset(data, DNAN, newfile_size - 1);
- goto out_done;
- }
#endif
if (rdwr & RRD_CREAT)
goto out_done;
if((rrd_file->pos + count) > old_size)
{
- rrd_set_error("attempting to write beyond end of file");
+ rrd_set_error("attempting to write beyond end of file (%ld + %ld > %ld)",rrd_file->pos, count, old_size);
return -1;
}
memcpy(rrd_simple_file->file_start + rrd_file->pos, buf, count);