mirror of
https://github.com/samba-team/samba.git
synced 2025-01-22 22:04:08 +03:00
Added call out to a Linux-compatible fallocate() when we need to extend a file
allocation extent without changing end-of-file size. Autobuild-User: Jeremy Allison <jra@samba.org> Autobuild-Date: Tue Dec 21 02:41:24 CET 2010 on sn-devel-104
This commit is contained in:
parent
09aea03813
commit
8998f4b013
@ -741,6 +741,7 @@ AC_CHECK_HEADERS(sys/syslog.h syslog.h)
|
||||
AC_CHECK_HEADERS(langinfo.h locale.h)
|
||||
AC_CHECK_HEADERS(xfs/libxfs.h)
|
||||
AC_CHECK_HEADERS(netgroup.h)
|
||||
AC_CHECK_HEADERS(linux/falloc.h)
|
||||
|
||||
AC_CHECK_HEADERS(rpcsvc/yp_prot.h,,,[[
|
||||
#if HAVE_RPC_RPC_H
|
||||
@ -1095,6 +1096,7 @@ AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetg
|
||||
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 posix_fallocate posix_fallocate64)
|
||||
AC_CHECK_FUNCS(fallocate fallocate64)
|
||||
AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam)
|
||||
AC_CHECK_FUNCS(opendir64 readdir64 seekdir64 telldir64 rewinddir64 closedir64)
|
||||
AC_CHECK_FUNCS(getpwent_r)
|
||||
@ -2563,6 +2565,39 @@ fi
|
||||
fi
|
||||
# end utmp details
|
||||
|
||||
AC_CACHE_CHECK([for linux fallocate],samba_cv_HAVE_LINUX_FALLOCATE,[
|
||||
AC_TRY_COMPILE([
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
#if defined(HAVE_LINUX_FALLOC_H)
|
||||
#include <linux/falloc.h>
|
||||
#endif],
|
||||
[int ret = fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 10);],
|
||||
samba_cv_HAVE_LINUX_FALLOCATE=yes,samba_cv_HAVE_LINUX_FALLOCATE=no)])
|
||||
if test x"$samba_cv_HAVE_LINUX_FALLOCATE" = x"yes" && test x"$ac_cv_func_fallocate" = x"yes"; then
|
||||
AC_DEFINE(HAVE_LINUX_FALLOCATE,1,[Whether the Linux 'fallocate' function is available])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for linux fallocate64],samba_cv_HAVE_LINUX_FALLOCATE64,[
|
||||
AC_TRY_COMPILE([
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
#if defined(HAVE_LINUX_FALLOC_H)
|
||||
#include <linux/falloc.h>
|
||||
#endif],
|
||||
[int ret = fallocate64(0, FALLOC_FL_KEEP_SIZE, 0, 10);],
|
||||
samba_cv_HAVE_LINUX_FALLOCATE64=yes,samba_cv_HAVE_LINUX_FALLOCATE64=no)])
|
||||
if test x"$samba_cv_HAVE_LINUX_FALLOCATE64" = x"yes" && test x"$ac_cv_func_fallocate64" = x"yes"; then
|
||||
AC_DEFINE(HAVE_LINUX_FALLOCATE64,1,[Whether the Linux 'fallocate64' function is available])
|
||||
fi
|
||||
|
||||
ICONV_LOOK_DIRS="/usr /usr/local /sw /opt"
|
||||
AC_ARG_WITH(libiconv,
|
||||
|
@ -888,6 +888,7 @@ 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);
|
||||
int sys_fallocate(int fd, enum vfs_fallocate_mode mode, 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);
|
||||
|
@ -694,6 +694,41 @@ int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
An fallocate() function that matches the semantics of the Linux one.
|
||||
********************************************************************/
|
||||
|
||||
#ifdef HAVE_LINUX_FALLOC_H
|
||||
#include <linux/falloc.h>
|
||||
#endif
|
||||
|
||||
int sys_fallocate(int fd, enum vfs_fallocate_mode mode, SMB_OFF_T offset, SMB_OFF_T len)
|
||||
{
|
||||
#if defined(HAVE_LINUX_FALLOCATE64) || defined(HAVE_LINUX_FALLOCATE)
|
||||
int lmode;
|
||||
switch (mode) {
|
||||
case VFS_FALLOCATE_EXTEND_SIZE:
|
||||
lmode = 0;
|
||||
break;
|
||||
case VFS_FALLOCATE_KEEP_SIZE:
|
||||
lmode = FALLOC_FL_KEEP_SIZE;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LINUX_FALLOCATE64)
|
||||
return fallocate64(fd, lmode, offset, len);
|
||||
#elif defined(HAVE_LINUX_FALLOCATE)
|
||||
return fallocate(fd, lmode, offset, len);
|
||||
#endif
|
||||
#else
|
||||
/* TODO - plumb in fallocate from other filesysetms like VXFS etc. JRA. */
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
An ftruncate() wrapper that will deal with 64 bit filesizes.
|
||||
********************************************************************/
|
||||
|
@ -965,9 +965,10 @@ static int vfswrap_fallocate(vfs_handle_struct *handle,
|
||||
START_PROFILE(syscall_fallocate);
|
||||
if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
|
||||
result = sys_posix_fallocate(fsp->fh->fd, offset, len);
|
||||
} else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
|
||||
result = sys_fallocate(fsp->fh->fd, mode, offset, len);
|
||||
} else {
|
||||
/* TODO - implement call into Linux fallocate call. */
|
||||
errno = ENOSYS;
|
||||
errno = EINVAL;
|
||||
result = -1;
|
||||
}
|
||||
END_PROFILE(syscall_fallocate);
|
||||
|
@ -501,13 +501,24 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!lp_strict_allocate(SNUM(fsp->conn)))
|
||||
return 0;
|
||||
|
||||
/* Grow - we need to test if we have enough space. */
|
||||
|
||||
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
|
||||
|
||||
/* See if we have a syscall that will allocate beyond end-of-file
|
||||
without changing EOF. */
|
||||
ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
|
||||
|
||||
contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
|
||||
|
||||
if (!lp_strict_allocate(SNUM(fsp->conn)))
|
||||
if (ret == 0) {
|
||||
/* We changed the allocation size on disk, but not
|
||||
EOF - exactly as required. We're done ! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
len -= fsp->fsp_name->st.st_ex_size;
|
||||
len /= 1024; /* Len is now number of 1k blocks needed. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user