Move posix_fallocate into the VFS where it belongs.
authorJeremy Allison <jra@samba.org>
Fri, 3 Dec 2010 00:25:59 +0000 (16:25 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 3 Dec 2010 00:25:59 +0000 (16:25 -0800)
Jeremy.

examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/smbprofile.h
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_streams_xattr.c
source3/modules/vfs_time_audit.c
source3/profile/profile.c
source3/smbd/vfs.c

index 42f4e48cd9017a32e2bf245e358a205010f82c5e..40ee5e9d6ea15a02fa5640f21682376bd04002ff 100644 (file)
@@ -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,
index 42e54a8871d67f617cc01b7a530788c017190e8c..ca22a30564a8f1778999632bcd92f1a7f29ff543 100644 (file)
@@ -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,
index 5015d2a9e4f534d1d100528feb19863ba246f5d6..647bf17e649d979e28938997155472590fc3c3aa 100644 (file)
@@ -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)
index 9121069a276dcacf7e7ac0354767b15a06dfdf38..cb49a17ce2b40b2366daf80005b603c155ebe4d4 100644 (file)
 /* 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);
index 5b38e64cbfd533bba0d7b529644983b58f3e6eeb..2eedd2bfbbb01a968ffe0dc7af0c2126db89f3f3 100644 (file)
 #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) \
index 977a5630acd8167ac832050be44a437f95598099..63993fed3656509640981d78564fbdbf59cd83aa 100644 (file)
@@ -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;
index 3328128d861c6f107a888e90583fae09c8d6c769..b7c0888a2286f8c97a4444ea4adc754e0feaa81a 100644 (file)
@@ -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,
index 218e5ec078875242779655a54ea8ebaaef5c3366..8870c6e47101dc8b186ede4f080e150dd95d4832 100644 (file)
@@ -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,
 };
 
index af4fd3313a2006f3bdee88081fe24c1a8e8d919f..e9481b5d6754e85ff64bb5f21301032f6deceae6 100644 (file)
@@ -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,
index 59b409d8da2f76afd22895247b39e3eb8d054c92..8013fc3956bdfab8617bffbde57df13221b5abbe 100644 (file)
@@ -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 */
index 8757682242ca0b3f14b6bf4a9551b9b319f33cc8..1829e3ae4271091cb8e553bfdfd36015f15b4473 100644 (file)
@@ -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)