AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent)
AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf)
AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf stat64 fstat64)
-AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt lseek64 ftruncate64)
+AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt lseek64 ftruncate64 posix_fallocate posix_fallocate64)
AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam)
AC_CHECK_FUNCS(opendir64 readdir64 seekdir64 telldir64 rewinddir64 closedir64)
AC_CHECK_FUNCS(getpwent_r)
int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf,
bool fake_dir_create_times);
int sys_ftruncate(int fd, SMB_OFF_T offset);
+int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len);
SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence);
int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence);
SMB_OFF_T sys_ftell(FILE *fp);
return ret;
}
+/*******************************************************************
+ An posix_fallocate() wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+#if defined(HAVE_POSIX_FALLOCATE64) || defined(HAVE_POSIX_FALLOCATE)
+int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_POSIX_FALLOCATE64)
+ return posix_fallocate64(fd, offset, len);
+#else
+ return posix_fallocate(fd, offset, len);
+#endif
+}
+#endif
+
/*******************************************************************
An ftruncate() wrapper that will deal with 64 bit filesizes.
********************************************************************/
if (SMB_VFS_FSTAT(fsp, &st) == -1)
return -1;
- space_to_write = len - st.st_ex_size;
-
#ifdef S_ISFIFO
if (S_ISFIFO(st.st_ex_mode))
return 0;
if (st.st_ex_size > len)
return sys_ftruncate(fsp->fh->fd, len);
+ /* for allocation try posix_fallocate first. This can fail on some
+ platforms e.g. when the filesystem doesn't support it and no
+ emulation is being done by the libc (like on AIX with JFS1). In that
+ case we do our own emulation. posix_fallocate implementations can
+ return ENOTSUP or EINVAL in cases like that. */
+#if defined(HAVE_POSIX_FALLOCATE)
+ {
+ int ret = sys_posix_fallocate(fsp->fh->fd, 0, len);
+ if (ret == ENOSPC) {
+ errno = ENOSPC;
+ return -1;
+ }
+ if (ret == 0) {
+ return 0;
+ }
+ DEBUG(10,("strict_allocate_ftruncate: sys_posix_fallocate "
+ "failed with error %d. "
+ "Falling back to slow manual allocation\n", ret));
+ }
+#endif
/* available disk space is enough or not? */
+ space_to_write = len - st.st_ex_size;
if (lp_strict_allocate(SNUM(fsp->conn))){
uint64_t space_avail;
uint64_t bsize,dfree,dsize;
if (SMB_VFS_LSEEK(fsp, st.st_ex_size, SEEK_SET) != st.st_ex_size)
return -1;
- space_to_write = len - st.st_ex_size;
-
memset(zero_space, '\0', sizeof(zero_space));
while ( space_to_write > 0) {
SMB_OFF_T retlen;