From: Timo Sirainen Date: Wed, 20 Oct 2010 16:50:03 +0000 (+0100) Subject: Added file_preallocate() to preallocate space to a file without changing its size. X-Git-Tag: 2.0.6~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=54fc3887b43fac7cb0a62babcff6234b9517e302;p=thirdparty%2Fdovecot%2Fcore.git Added file_preallocate() to preallocate space to a file without changing its size. Implemented for Linux. Doesn't look like other OSes support this. --- diff --git a/configure.in b/configure.in index 680f190ba6..74ecb32505 100644 --- a/configure.in +++ b/configure.in @@ -273,7 +273,7 @@ AC_CHECK_HEADERS(strings.h stdint.h unistd.h dirent.h malloc.h inttypes.h \ sys/quota.h sys/fs/ufs_quota.h ufs/ufs/quota.h jfs/quota.h sys/fs/quota_common.h \ mntent.h sys/mnttab.h sys/event.h sys/time.h sys/mkdev.h linux/dqblk_xfs.h \ xfs/xqm.h execinfo.h ucontext.h malloc_np.h sys/utsname.h sys/vmount.h \ - sys/utsname.h glob.h) + sys/utsname.h glob.h linux/falloc.h) dnl * gcc specific options if test "x$ac_cv_c_compiler_gnu" = "xyes"; then @@ -369,7 +369,7 @@ AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \ setrlimit setproctitle seteuid setreuid setegid setresgid \ strtoull strtoll strtouq strtoq \ setpriority quotactl getmntent kqueue kevent backtrace_symbols \ - walkcontext dirfd clearenv malloc_usable_size glob) + walkcontext dirfd clearenv malloc_usable_size glob fallocate) AC_CHECK_LIB(rt, clock_gettime, [ AC_DEFINE(HAVE_CLOCK_GETTIME,, Define if you have the clock_gettime function) diff --git a/src/lib/file-set-size.c b/src/lib/file-set-size.c index 88b1e02c06..8908cc25e3 100644 --- a/src/lib/file-set-size.c +++ b/src/lib/file-set-size.c @@ -7,12 +7,16 @@ #ifdef HAVE_POSIX_FALLOCATE # define _XOPEN_SOURCE 600 /* Required by glibc, breaks Solaris 9 */ #endif +#define _GNU_SOURCE /* for fallocate() */ #include "lib.h" #include "file-set-size.h" #include #include #include +#ifdef HAVE_LINUX_FALLOC_H +# include +#endif int file_set_size(int fd, off_t size) { @@ -76,3 +80,15 @@ int file_set_size(int fd, off_t size) } return 0; } + +int file_preallocate(int fd ATTR_UNUSED, off_t size ATTR_UNUSED) +{ +#if defined(HAVE_FALLOCATE) && defined(FALLOC_FL_KEEP_SIZE) + /* Linux */ + if (fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, size) < 0) + return errno == ENOSYS ? 0 : -1; + return 1; +#else + return 0; +#endif +} diff --git a/src/lib/file-set-size.h b/src/lib/file-set-size.h index 65f10d803d..6752d32ec6 100644 --- a/src/lib/file-set-size.h +++ b/src/lib/file-set-size.h @@ -5,5 +5,9 @@ be zeros. The file offset may be anywhere after this call. Returns -1 if failed, 0 if successful. */ int file_set_size(int fd, off_t size); +/* Preallocate file to given size, without actually changing the size + reported by stat(). Returns 1 if ok, 0 if not supported by this filesystem, + -1 if error. */ +int file_preallocate(int fd, off_t size); #endif