X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_open.c;h=46a5fcf412b6b0a2beb41990e49ac97c528d500b;hb=2f811c28462aa8079c8a0ed4f9962265f217b113;hp=5f3723f30cef086d44c6bab4a3c434b1d74e6507;hpb=9d7aa8ddae065b774fe4eb1df76a3242b9db2d53;p=rrdtool.git diff --git a/src/rrd_open.c b/src/rrd_open.c index 5f3723f..46a5fcf 100644 --- a/src/rrd_open.c +++ b/src/rrd_open.c @@ -222,12 +222,20 @@ rrd_file_t *rrd_open( 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. @@ -248,6 +256,40 @@ rrd_file_t *rrd_open( */ #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); @@ -259,10 +301,6 @@ rrd_file_t *rrd_open( 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; @@ -584,9 +622,11 @@ off_t rrd_seek( int whence) { off_t ret = 0; +#ifndef HAVE_MMAP rrd_simple_file_t *rrd_simple_file; rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt; - +#endif + #ifdef HAVE_MMAP if (whence == SEEK_SET) rrd_file->pos = off; @@ -671,7 +711,7 @@ ssize_t rrd_write( 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);