It turns out we need the fallocate operations to be able to both
allocate and extend filesize, and to allocate and not extend
filesize, and posix_fallocate can only do the former. So by defining
the vfs op as posix_fallocate we lose the opportunity to use any
underlying syscalls (like Linux fallocate) that can do the latter
as well.
We don't currently use the non-extending filesize call, but now
I've changed the vfs op definition we can in the future. For the
moment simply map the fallocate op onto posix_fallocate for the
VFS_FALLOCATE_EXTEND_SIZE case and return ENOSYS for the
VFS_FALLOCATE_KEEP_SIZE case.
Jeremy.
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Sat Dec 18 08:59:27 CET 2010 on sn-devel-104
-static int skel_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+static int skel_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset, SMB_OFF_T len)
{
errno = ENOSYS;
SMB_OFF_T offset, SMB_OFF_T len)
{
errno = ENOSYS;
.getwd = skel_getwd,
.ntimes = skel_ntimes,
.ftruncate = skel_ftruncate,
.getwd = skel_getwd,
.ntimes = skel_ntimes,
.ftruncate = skel_ftruncate,
- .posix_fallocate = skel_posix_fallocate,
+ .fallocate = skel_fallocate,
.lock = skel_lock,
.kernel_flock = skel_kernel_flock,
.linux_setlease = skel_linux_setlease,
.lock = skel_lock,
.kernel_flock = skel_kernel_flock,
.linux_setlease = skel_linux_setlease,
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
}
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
}
-static int skel_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+static int skel_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+ enum vfs_fallocate_mode,
SMB_OFF_T offset,
SMB_OFF_T len)
{
SMB_OFF_T offset,
SMB_OFF_T len)
{
- return SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+ return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
}
static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
}
static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
.getwd = skel_getwd,
.ntimes = skel_ntimes,
.ftruncate = skel_ftruncate,
.getwd = skel_getwd,
.ntimes = skel_ntimes,
.ftruncate = skel_ftruncate,
- .posix_fallocate = skel_posix_fallocate,
+ .fallocate = skel_fallocate,
.lock = skel_lock,
.kernel_flock = skel_kernel_flock,
.linux_setlease = skel_linux_setlease,
.lock = skel_lock,
.kernel_flock = skel_kernel_flock,
.linux_setlease = skel_linux_setlease,
#define syscall_ftruncate_count __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, count)
#define syscall_ftruncate_time __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, time)
#define syscall_ftruncate_count __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, count)
#define syscall_ftruncate_time __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, time)
- PR_VALUE_SYSCALL_POSIX_FALLOCATE,
-#define syscall_posix_fallocate_count __profile_stats_value(PR_VALUE_SYSCALL_POSIX_FALLOCATE, count)
-#define syscall_posix_fallocate_time __profile_stats_value(PR_VALUE_SYSCALL_POSIX_FALLOCATE, time)
+ PR_VALUE_SYSCALL_FALLOCATE,
+#define syscall_fallocate_count __profile_stats_value(PR_VALUE_SYSCALL_FALLOCATE, count)
+#define syscall_fallocate_time __profile_stats_value(PR_VALUE_SYSCALL_FALLOCATE, time)
PR_VALUE_SYSCALL_FCNTL_LOCK,
#define syscall_fcntl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, count)
PR_VALUE_SYSCALL_FCNTL_LOCK,
#define syscall_fcntl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, count)
malloc'ed path. JRA. */
/* Leave at 28 - not yet released. Move posix_fallocate into the VFS
where it belongs. JRA. */
malloc'ed path. JRA. */
/* Leave at 28 - not yet released. Move posix_fallocate into the VFS
where it belongs. JRA. */
+/* Leave at 28 - not yet released. Rename posix_fallocate to fallocate
+ to split out the two possible uses. JRA. */
#define SMB_VFS_INTERFACE_VERSION 28
#define SMB_VFS_INTERFACE_VERSION 28
vfs_translate_to_windows
};
vfs_translate_to_windows
};
+enum vfs_fallocate_mode {
+ VFS_FALLOCATE_EXTEND_SIZE = 0,
+ VFS_FALLOCATE_KEEP_SIZE = 1
+};
+
/*
Available VFS operations. These values must be in sync with vfs_ops struct
(struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops).
/*
Available VFS operations. These values must be in sync with vfs_ops struct
(struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops).
const struct smb_filename *smb_fname,
struct smb_file_time *ft);
int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset);
const struct smb_filename *smb_fname,
struct smb_file_time *ft);
int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset);
- int (*posix_fallocate)(struct vfs_handle_struct *handle,
+ int (*fallocate)(struct vfs_handle_struct *handle,
struct files_struct *fsp,
struct files_struct *fsp,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len);
bool (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
SMB_OFF_T offset,
SMB_OFF_T len);
bool (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
struct smb_file_time *ft);
int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
struct files_struct *fsp, SMB_OFF_T offset);
struct smb_file_time *ft);
int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
struct files_struct *fsp, SMB_OFF_T offset);
-int smb_vfs_call_posix_fallocate(struct vfs_handle_struct *handle,
+int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
struct files_struct *fsp,
struct files_struct *fsp,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len);
bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
SMB_OFF_T offset,
SMB_OFF_T len);
bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
#define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset) \
smb_vfs_call_ftruncate((handle)->next, (fsp), (offset))
#define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset) \
smb_vfs_call_ftruncate((handle)->next, (fsp), (offset))
-#define SMB_VFS_POSIX_FALLOCATE(fsp, offset, len) \
- smb_vfs_call_posix_fallocate((fsp)->conn->vfs_handles, (fsp), (offset), (len))
-#define SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len) \
- smb_vfs_call_posix_fallocate((handle)->next, (fsp), (offset), (len))
+#define SMB_VFS_FALLOCATE(fsp, mode, offset, len) \
+ smb_vfs_call_fallocate((fsp)->conn->vfs_handles, (fsp), (mode), (offset), (len))
+#define SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len) \
+ smb_vfs_call_fallocate((handle)->next, (fsp), (mode), (offset), (len))
#define SMB_VFS_LOCK(fsp, op, offset, count, type) \
smb_vfs_call_lock((fsp)->conn->vfs_handles, (fsp), (op), (offset), (count), (type))
#define SMB_VFS_LOCK(fsp, op, offset, count, type) \
smb_vfs_call_lock((fsp)->conn->vfs_handles, (fsp), (op), (offset), (count), (type))
space_to_write = len - pst->st_ex_size;
space_to_write = len - pst->st_ex_size;
- /* for allocation try posix_fallocate first. This can fail on some
+ /* for allocation try 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
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
+ case we do our own emulation. fallocate implementations can
return ENOTSUP or EINVAL in cases like that. */
return ENOTSUP or EINVAL in cases like that. */
- ret = SMB_VFS_POSIX_FALLOCATE(fsp, pst->st_ex_size, space_to_write);
+ ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
+ pst->st_ex_size, space_to_write);
if (ret == ENOSPC) {
errno = ENOSPC;
return -1;
if (ret == ENOSPC) {
errno = ENOSPC;
return -1;
if (ret == 0) {
return 0;
}
if (ret == 0) {
return 0;
}
- DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_POSIX_FALLOCATE failed with "
+ DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
"error %d. Falling back to slow manual allocation\n", ret));
/* available disk space is enough or not? */
"error %d. Falling back to slow manual allocation\n", ret));
/* available disk space is enough or not? */
-static int vfswrap_posix_fallocate(vfs_handle_struct *handle,
+static int vfswrap_fallocate(vfs_handle_struct *handle,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len)
{
int result;
SMB_OFF_T offset,
SMB_OFF_T len)
{
int result;
- START_PROFILE(syscall_posix_fallocate);
- result = sys_posix_fallocate(fsp->fh->fd, offset, len);
- END_PROFILE(syscall_posix_fallocate);
+ START_PROFILE(syscall_fallocate);
+ if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
+ result = sys_posix_fallocate(fsp->fh->fd, offset, len);
+ } else {
+ /* TODO - implement call into Linux fallocate call. */
+ errno = ENOSYS;
+ result = -1;
+ }
+ END_PROFILE(syscall_fallocate);
.getwd = vfswrap_getwd,
.ntimes = vfswrap_ntimes,
.ftruncate = vfswrap_ftruncate,
.getwd = vfswrap_getwd,
.ntimes = vfswrap_ntimes,
.ftruncate = vfswrap_ftruncate,
- .posix_fallocate = vfswrap_posix_fallocate,
+ .fallocate = vfswrap_fallocate,
.lock = vfswrap_lock,
.kernel_flock = vfswrap_kernel_flock,
.linux_setlease = vfswrap_linux_setlease,
.lock = vfswrap_lock,
.kernel_flock = vfswrap_kernel_flock,
.linux_setlease = vfswrap_linux_setlease,
SMB_VFS_OP_GETWD,
SMB_VFS_OP_NTIMES,
SMB_VFS_OP_FTRUNCATE,
SMB_VFS_OP_GETWD,
SMB_VFS_OP_NTIMES,
SMB_VFS_OP_FTRUNCATE,
- SMB_VFS_OP_POSIX_FALLOCATE,
SMB_VFS_OP_LOCK,
SMB_VFS_OP_KERNEL_FLOCK,
SMB_VFS_OP_LINUX_SETLEASE,
SMB_VFS_OP_LOCK,
SMB_VFS_OP_KERNEL_FLOCK,
SMB_VFS_OP_LINUX_SETLEASE,
{ SMB_VFS_OP_GETWD, "getwd" },
{ SMB_VFS_OP_NTIMES, "ntimes" },
{ SMB_VFS_OP_FTRUNCATE, "ftruncate" },
{ SMB_VFS_OP_GETWD, "getwd" },
{ SMB_VFS_OP_NTIMES, "ntimes" },
{ SMB_VFS_OP_FTRUNCATE, "ftruncate" },
- { SMB_VFS_OP_POSIX_FALLOCATE,"posix_fallocate" },
+ { SMB_VFS_OP_FALLOCATE,"fallocate" },
{ SMB_VFS_OP_LOCK, "lock" },
{ SMB_VFS_OP_KERNEL_FLOCK, "kernel_flock" },
{ SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" },
{ SMB_VFS_OP_LOCK, "lock" },
{ SMB_VFS_OP_KERNEL_FLOCK, "kernel_flock" },
{ SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" },
-static int smb_full_audit_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+static int smb_full_audit_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len)
{
int result;
SMB_OFF_T offset,
SMB_OFF_T len)
{
int result;
- result = SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+ result = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
- do_log(SMB_VFS_OP_POSIX_FALLOCATE, (result >= 0), handle,
+ do_log(SMB_VFS_OP_FALLOCATE, (result >= 0), handle,
"%s", fsp_str_do_log(fsp));
return result;
"%s", fsp_str_do_log(fsp));
return result;
.getwd = smb_full_audit_getwd,
.ntimes = smb_full_audit_ntimes,
.ftruncate = smb_full_audit_ftruncate,
.getwd = smb_full_audit_getwd,
.ntimes = smb_full_audit_ntimes,
.ftruncate = smb_full_audit_ftruncate,
- .posix_fallocate = smb_full_audit_posix_fallocate,
+ .fallocate = smb_full_audit_fallocate,
.lock = smb_full_audit_lock,
.kernel_flock = smb_full_audit_kernel_flock,
.linux_setlease = smb_full_audit_linux_setlease,
.lock = smb_full_audit_lock,
.kernel_flock = smb_full_audit_kernel_flock,
.linux_setlease = smb_full_audit_linux_setlease,
-static int streams_xattr_posix_fallocate(struct vfs_handle_struct *handle,
+static int streams_xattr_fallocate(struct vfs_handle_struct *handle,
struct files_struct *fsp,
struct files_struct *fsp,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len)
{
struct stream_io *sio =
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
SMB_OFF_T offset,
SMB_OFF_T len)
{
struct stream_io *sio =
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
- DEBUG(10, ("streams_xattr_posix_fallocate called for file %s offset %.0f"
+ DEBUG(10, ("streams_xattr_fallocate called for file %s offset %.0f"
"len = %.0f\n",
fsp_str_dbg(fsp), (double)offset, (double)len));
if (sio == NULL) {
"len = %.0f\n",
fsp_str_dbg(fsp), (double)offset, (double)len));
if (sio == NULL) {
- return SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+ return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
}
if (!streams_xattr_recheck(sio)) {
}
if (!streams_xattr_recheck(sio)) {
.unlink = streams_xattr_unlink,
.rename = streams_xattr_rename,
.ftruncate = streams_xattr_ftruncate,
.unlink = streams_xattr_unlink,
.rename = streams_xattr_rename,
.ftruncate = streams_xattr_ftruncate,
- .posix_fallocate = streams_xattr_posix_fallocate,
+ .fallocate = streams_xattr_fallocate,
.streaminfo = streams_xattr_streaminfo,
};
.streaminfo = streams_xattr_streaminfo,
};
-static int smb_time_audit_posix_fallocate(vfs_handle_struct *handle,
+static int smb_time_audit_fallocate(vfs_handle_struct *handle,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len)
{
SMB_OFF_T offset,
SMB_OFF_T len)
{
double timediff;
clock_gettime_mono(&ts1);
double timediff;
clock_gettime_mono(&ts1);
- result = SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+ result = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
if (timediff > audit_timeout) {
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
if (timediff > audit_timeout) {
- smb_time_audit_log("posix_fallocate", timediff);
+ smb_time_audit_log("fallocate", timediff);
.getwd = smb_time_audit_getwd,
.ntimes = smb_time_audit_ntimes,
.ftruncate = smb_time_audit_ftruncate,
.getwd = smb_time_audit_getwd,
.ntimes = smb_time_audit_ntimes,
.ftruncate = smb_time_audit_ftruncate,
- .posix_fallocate = smb_time_audit_posix_fallocate,
+ .fallocate = smb_time_audit_fallocate,
.lock = smb_time_audit_lock,
.kernel_flock = smb_time_audit_kernel_flock,
.linux_setlease = smb_time_audit_linux_setlease,
.lock = smb_time_audit_lock,
.kernel_flock = smb_time_audit_kernel_flock,
.linux_setlease = smb_time_audit_linux_setlease,
"syscall_getwd", /* PR_VALUE_SYSCALL_GETWD */
"syscall_ntimes", /* PR_VALUE_SYSCALL_NTIMES */
"syscall_ftruncate", /* PR_VALUE_SYSCALL_FTRUNCATE */
"syscall_getwd", /* PR_VALUE_SYSCALL_GETWD */
"syscall_ntimes", /* PR_VALUE_SYSCALL_NTIMES */
"syscall_ftruncate", /* PR_VALUE_SYSCALL_FTRUNCATE */
- "syscall_posix_fallocate", /* PR_VALUE_SYSCALL_POSIX_FALLOCATE */
+ "syscall_fallocate", /* PR_VALUE_SYSCALL_FALLOCATE */
"syscall_fcntl_lock", /* PR_VALUE_SYSCALL_FCNTL_LOCK */
"syscall_kernel_flock", /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
"syscall_linux_setlease", /* PR_VALUE_SYSCALL_LINUX_SETLEASE */
"syscall_fcntl_lock", /* PR_VALUE_SYSCALL_FCNTL_LOCK */
"syscall_kernel_flock", /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
"syscall_linux_setlease", /* PR_VALUE_SYSCALL_LINUX_SETLEASE */
}
/****************************************************************************
}
/****************************************************************************
- A slow version of posix_fallocate. Fallback code if SMB_VFS_POSIX_FALLOCATE
- fails. Needs to be outside of the default version of SMB_VFS_POSIX_FALLOCATE
+ A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
+ fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
as this is also called from the default SMB_VFS_FTRUNCATE code.
as this is also called from the default SMB_VFS_FTRUNCATE code.
+ Always extends the file size.
Returns 0 on success, errno on failure.
****************************************************************************/
Returns 0 on success, errno on failure.
****************************************************************************/
/* Only do this on non-stream file handles. */
if (fsp->base_fsp == NULL) {
/* Only do this on non-stream file handles. */
if (fsp->base_fsp == NULL) {
- /* for allocation try posix_fallocate first. This can fail on some
+ /* for allocation try 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
* 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
+ * case we do our own emulation. fallocate implementations can
* return ENOTSUP or EINVAL in cases like that. */
* return ENOTSUP or EINVAL in cases like that. */
- ret = SMB_VFS_POSIX_FALLOCATE(fsp, offset, num_to_write);
+ ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
+ offset, num_to_write);
if (ret == ENOSPC) {
errno = ENOSPC;
ret = -1;
if (ret == ENOSPC) {
errno = ENOSPC;
ret = -1;
if (ret == 0) {
goto out;
}
if (ret == 0) {
goto out;
}
- DEBUG(10,("vfs_fill_sparse: SMB_VFS_POSIX_FALLOCATE failed with "
+ DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
"error %d. Falling back to slow manual allocation\n", ret));
}
"error %d. Falling back to slow manual allocation\n", ret));
}
return handle->fns->ftruncate(handle, fsp, offset);
}
return handle->fns->ftruncate(handle, fsp, offset);
}
-int smb_vfs_call_posix_fallocate(struct vfs_handle_struct *handle,
+int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
struct files_struct *fsp,
struct files_struct *fsp,
+ enum vfs_fallocate_mode mode,
SMB_OFF_T offset,
SMB_OFF_T len)
{
SMB_OFF_T offset,
SMB_OFF_T len)
{
- VFS_FIND(posix_fallocate);
- return handle->fns->posix_fallocate(handle, fsp, offset, len);
+ VFS_FIND(fallocate);
+ return handle->fns->fallocate(handle, fsp, mode, offset, len);
}
int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
}
int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,