summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-12-02 16:25:59 -0800
committerJeremy Allison <jra@samba.org>2010-12-02 16:25:59 -0800
commit5819a36aef030772f1e9da81655c1f911a10372c (patch)
tree8746c0f52b94f3b2bd722474b653860b10df2a14
parentde8ceb5364de86f9b016251201474f011c16f6cb (diff)
downloadsamba-5819a36aef030772f1e9da81655c1f911a10372c.tar.gz
samba-5819a36aef030772f1e9da81655c1f911a10372c.tar.bz2
samba-5819a36aef030772f1e9da81655c1f911a10372c.zip
Move posix_fallocate into the VFS where it belongs.
Jeremy.
-rw-r--r--examples/VFS/skel_opaque.c8
-rw-r--r--examples/VFS/skel_transparent.c8
-rw-r--r--source3/include/smbprofile.h4
-rw-r--r--source3/include/vfs.h10
-rw-r--r--source3/include/vfs_macros.h5
-rw-r--r--source3/modules/vfs_default.c17
-rw-r--r--source3/modules/vfs_full_audit.c17
-rw-r--r--source3/modules/vfs_streams_xattr.c26
-rw-r--r--source3/modules/vfs_time_audit.c22
-rw-r--r--source3/profile/profile.c1
-rw-r--r--source3/smbd/vfs.c13
11 files changed, 127 insertions, 4 deletions
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 42f4e48cd9..40ee5e9d6e 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -308,6 +308,13 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_
return -1;
}
+static int skel_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+ SMB_OFF_T offset, SMB_OFF_T len)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
errno = ENOSYS;
@@ -813,6 +820,7 @@ struct vfs_fn_pointers skel_transparent_fns = {
.getwd = skel_getwd,
.ntimes = skel_ntimes,
.ftruncate = skel_ftruncate,
+ .posix_fallocate = skel_posix_fallocate,
.lock = skel_lock,
.kernel_flock = skel_kernel_flock,
.linux_setlease = skel_linux_setlease,
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 42e54a8871..ca22a30564 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -292,6 +292,13 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
}
+static int skel_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+ SMB_OFF_T offset,
+ SMB_OFF_T len)
+{
+ return SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, 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)
{
return SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
@@ -757,6 +764,7 @@ struct vfs_fn_pointers skel_transparent_fns = {
.getwd = skel_getwd,
.ntimes = skel_ntimes,
.ftruncate = skel_ftruncate,
+ .posix_fallocate = skel_posix_fallocate,
.lock = skel_lock,
.kernel_flock = skel_kernel_flock,
.linux_setlease = skel_linux_setlease,
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index 5015d2a9e4..647bf17e64 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -179,6 +179,10 @@ enum profile_stats_values
#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_FCNTL_LOCK,
#define syscall_fcntl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, count)
#define syscall_fcntl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, time)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 9121069a27..cb49a17ce2 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -128,6 +128,8 @@
/* Changed to version 28 - Add private_flags uint32_t to CREATE call. */
/* Leave at 28 - not yet released. Change realpath to assume NULL and return a
malloc'ed path. JRA. */
+/* Leave at 28 - not yet released. Move posix_fallocate into the VFS
+ where it belongs. JRA. */
#define SMB_VFS_INTERFACE_VERSION 28
@@ -250,6 +252,10 @@ struct vfs_fn_pointers {
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,
+ struct files_struct *fsp,
+ 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);
int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp,
uint32 share_mode, uint32_t access_mask);
@@ -602,6 +608,10 @@ int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
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,
+ struct files_struct *fsp,
+ SMB_OFF_T offset,
+ SMB_OFF_T len);
bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
struct files_struct *fsp, int op, SMB_OFF_T offset,
SMB_OFF_T count, int type);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 5b38e64cbf..2eedd2bfbb 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -249,6 +249,11 @@
#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_LOCK(fsp, op, offset, count, type) \
smb_vfs_call_lock((fsp)->conn->vfs_handles, (fsp), (op), (offset), (count), (type))
#define SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type) \
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 977a5630ac..63993fed36 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -854,7 +854,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
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. */
- ret = sys_posix_fallocate(fsp->fh->fd, st.st_ex_size, space_to_write);
+ ret = SMB_VFS_POSIX_FALLOCATE(fsp, st.st_ex_size, space_to_write);
if (ret == ENOSPC) {
errno = ENOSPC;
return -1;
@@ -862,7 +862,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
if (ret == 0) {
return 0;
}
- DEBUG(10,("strict_allocate_ftruncate: sys_posix_fallocate failed with "
+ DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_POSIX_FALLOCATE failed with "
"error %d. Falling back to slow manual allocation\n", ret));
/* available disk space is enough or not? */
@@ -974,6 +974,19 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O
return result;
}
+static int vfswrap_posix_fallocate(vfs_handle_struct *handle,
+ files_struct *fsp,
+ 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);
+ return result;
+}
+
static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
bool result;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 3328128d86..b7c0888a22 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -124,6 +124,7 @@ typedef enum _vfs_op_type {
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,
@@ -262,6 +263,7 @@ static struct {
{ 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_LOCK, "lock" },
{ SMB_VFS_OP_KERNEL_FLOCK, "kernel_flock" },
{ SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" },
@@ -1222,6 +1224,20 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp
return result;
}
+static int smb_full_audit_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+ SMB_OFF_T offset,
+ SMB_OFF_T len)
+{
+ int result;
+
+ result = SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+
+ do_log(SMB_VFS_OP_POSIX_FALLOCATE, (result >= 0), handle,
+ "%s", fsp_str_do_log(fsp));
+
+ return result;
+}
+
static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
@@ -2218,6 +2234,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
.getwd = smb_full_audit_getwd,
.ntimes = smb_full_audit_ntimes,
.ftruncate = smb_full_audit_ftruncate,
+ .posix_fallocate = smb_full_audit_posix_fallocate,
.lock = smb_full_audit_lock,
.kernel_flock = smb_full_audit_kernel_flock,
.linux_setlease = smb_full_audit_linux_setlease,
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 218e5ec078..8870c6e471 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -1023,6 +1023,31 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
return 0;
}
+static int streams_xattr_posix_fallocate(struct vfs_handle_struct *handle,
+ struct files_struct *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"
+ "len = %.0f\n",
+ fsp_str_dbg(fsp), (double)offset, (double)len));
+
+ if (sio == NULL) {
+ return SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+ }
+
+ if (!streams_xattr_recheck(sio)) {
+ return -1;
+ }
+
+ /* Let the pwrite code path handle it. */
+ return ENOSYS;
+}
+
+
static struct vfs_fn_pointers vfs_streams_xattr_fns = {
.fs_capabilities = streams_xattr_fs_capabilities,
.open = streams_xattr_open,
@@ -1034,6 +1059,7 @@ static struct vfs_fn_pointers vfs_streams_xattr_fns = {
.unlink = streams_xattr_unlink,
.rename = streams_xattr_rename,
.ftruncate = streams_xattr_ftruncate,
+ .posix_fallocate = streams_xattr_posix_fallocate,
.streaminfo = streams_xattr_streaminfo,
};
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index af4fd3313a..e9481b5d67 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -905,6 +905,27 @@ static int smb_time_audit_ftruncate(vfs_handle_struct *handle,
return result;
}
+static int smb_time_audit_posix_fallocate(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_OFF_T offset,
+ SMB_OFF_T len)
+{
+ int result;
+ struct timespec ts1,ts2;
+ double timediff;
+
+ clock_gettime_mono(&ts1);
+ result = SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+ clock_gettime_mono(&ts2);
+ timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+ if (timediff > audit_timeout) {
+ smb_time_audit_log("posix_fallocate", timediff);
+ }
+
+ return result;
+}
+
static bool smb_time_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
int op, SMB_OFF_T offset, SMB_OFF_T count,
int type)
@@ -2336,6 +2357,7 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
.getwd = smb_time_audit_getwd,
.ntimes = smb_time_audit_ntimes,
.ftruncate = smb_time_audit_ftruncate,
+ .posix_fallocate = smb_time_audit_posix_fallocate,
.lock = smb_time_audit_lock,
.kernel_flock = smb_time_audit_kernel_flock,
.linux_setlease = smb_time_audit_linux_setlease,
diff --git a/source3/profile/profile.c b/source3/profile/profile.c
index 59b409d8da..8013fc3956 100644
--- a/source3/profile/profile.c
+++ b/source3/profile/profile.c
@@ -234,6 +234,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
"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_fcntl_lock", /* PR_VALUE_SYSCALL_FCNTL_LOCK */
"syscall_kernel_flock", /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
"syscall_linux_setlease", /* PR_VALUE_SYSCALL_LINUX_SETLEASE */
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 8757682242..1829e3ae42 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -609,7 +609,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
* 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. */
- ret = sys_posix_fallocate(fsp->fh->fd, offset, num_to_write);
+ ret = SMB_VFS_POSIX_FALLOCATE(fsp, offset, num_to_write);
if (ret == ENOSPC) {
errno = ENOSPC;
ret = -1;
@@ -619,7 +619,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
set_filelen_write_cache(fsp, len);
goto out;
}
- DEBUG(10,("vfs_fill_sparse: sys_posix_fallocate failed with "
+ DEBUG(10,("vfs_fill_sparse: SMB_VFS_POSIX_FALLOCATE failed with "
"error %d. Falling back to slow manual allocation\n", ret));
}
@@ -1439,6 +1439,15 @@ int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
return handle->fns->ftruncate(handle, fsp, offset);
}
+int smb_vfs_call_posix_fallocate(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ SMB_OFF_T offset,
+ SMB_OFF_T len)
+{
+ VFS_FIND(posix_fallocate);
+ return handle->fns->posix_fallocate(handle, fsp, offset, len);
+}
+
int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
struct files_struct *fsp, uint32 share_mode,
uint32_t access_mask)