diff options
Diffstat (limited to 'source3/modules/vfs_default.c')
-rw-r--r-- | source3/modules/vfs_default.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 9abf792769..da775d160b 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -922,8 +922,6 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs 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; @@ -936,7 +934,28 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs 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; @@ -956,8 +975,6 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs 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; |