s3/vfs: change fallocate mode flags from enum->uint32_t
authorDavid Disseldorp <ddiss@samba.org>
Mon, 9 Feb 2015 17:21:59 +0000 (18:21 +0100)
committerJeremy Allison <jra@samba.org>
Mon, 9 Mar 2015 20:27:07 +0000 (21:27 +0100)
The Linux fallocate syscall offers a mode parameter which can take the
following flags:
FALLOC_FL_KEEP_SIZE
FALLOC_FL_PUNCH_HOLE (since 2.6.38)
FALLOC_FL_COLLAPSE_RANGE (since 3.15)
FALLOC_FL_ZERO_RANGE (since 3.14)

The flags are not exclusive, e.g. FALLOC_FL_PUNCH_HOLE must be specified
alongside FALLOC_FL_KEEP_SIZE.

Samba currently takes a vfs_fallocate_mode enum parameter for the VFS
fallocate hook, taking either an EXTEND_SIZE or KEEP_SIZE value. This
commit changes the fallocate hook such that it accepts a uint32_t flags
parameter, in preparation for PUNCH_HOLE and ZERO_RANGE support.

Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
14 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/proto.h
source3/include/vfs.h
source3/lib/system.c
source3/modules/vfs_ceph.c
source3/modules/vfs_default.c
source3/modules/vfs_fruit.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_streams_xattr.c
source3/modules/vfs_time_audit.c
source3/smbd/vfs.c

index 2a53c8a9d31176497e8d229e15a5e5c49886b3d0..b6b1aefe5b002e9f1e8380be68480e2efb17bbd3 100644 (file)
@@ -393,7 +393,7 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static int skel_fallocate(vfs_handle_struct *handle, files_struct *fsp,
-                         enum vfs_fallocate_mode mode, off_t offset, off_t len)
+                         uint32_t mode, off_t offset, off_t len)
 {
        errno = ENOSYS;
        return -1;
index eb561db04312a679166f462485f42777a72a1203..f7ed537025e9e763d6e39a82d54350b915701116 100644 (file)
@@ -490,7 +490,7 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static int skel_fallocate(vfs_handle_struct *handle, files_struct *fsp,
-                         enum vfs_fallocate_mode mode, off_t offset, off_t len)
+                         uint32_t mode, off_t offset, off_t len)
 {
        return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
 }
index 64bce03d722828752519208e8b5ffca89f5957ef..c66283b9066fbe4c68ccb27961170214796664ba 100644 (file)
@@ -255,7 +255,7 @@ int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf,
 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf,
              bool fake_dir_create_times);
 int sys_posix_fallocate(int fd, off_t offset, off_t len);
-int sys_fallocate(int fd, enum vfs_fallocate_mode mode, off_t offset, off_t len);
+int sys_fallocate(int fd, uint32_t mode, off_t offset, off_t len);
 void kernel_flock(int fd, uint32 share_mode, uint32 access_mask);
 DIR *sys_fdopendir(int fd);
 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev);
index 13143c2e8d954eb5f144ed3f7334a92afa7265d7..3d0b82b508413be8ab252c9cc1ce9417fd1361ba 100644 (file)
 /* Version 32 - Add in and out create context blobs to create_file */
 /* Version 32 - Remove unnecessary SMB_VFS_DISK_FREE() small_query parameter */
 /* Bump to version 33 - Samba 4.3 will ship with that. */
+/* Version 33 - change fallocate mode flags param from enum->uint32_t */
 
 #define SMB_VFS_INTERFACE_VERSION 33
 
@@ -487,9 +488,8 @@ enum vfs_translate_direction {
        vfs_translate_to_windows
 };
 
-enum vfs_fallocate_mode {
-       VFS_FALLOCATE_EXTEND_SIZE = 0,
-       VFS_FALLOCATE_KEEP_SIZE = 1
+enum vfs_fallocate_flags {
+       VFS_FALLOCATE_FL_KEEP_SIZE              = 0x0001,
 };
 
 /*
@@ -609,7 +609,7 @@ struct vfs_fn_pointers {
        int (*ftruncate_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t offset);
        int (*fallocate_fn)(struct vfs_handle_struct *handle,
                            struct files_struct *fsp,
-                           enum vfs_fallocate_mode mode,
+                           uint32_t mode,
                            off_t offset,
                            off_t len);
        bool (*lock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, off_t offset, off_t count, int type);
@@ -1050,10 +1050,10 @@ int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
                           struct files_struct *fsp, off_t offset);
 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
-                       struct files_struct *fsp,
-                       enum vfs_fallocate_mode mode,
-                       off_t offset,
-                       off_t len);
+                          struct files_struct *fsp,
+                          uint32_t mode,
+                          off_t offset,
+                          off_t len);
 bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
                       struct files_struct *fsp, int op, off_t offset,
                       off_t count, int type);
index 4f3e214a5416eef651962a311c4b3b0d07ff74b9..fca5855ec3d6eab4b7ed807910f64681d97ab462 100644 (file)
@@ -478,18 +478,19 @@ int sys_posix_fallocate(int fd, off_t offset, off_t len)
 #include <linux/falloc.h>
 #endif
 
-int sys_fallocate(int fd, enum vfs_fallocate_mode mode, off_t offset, off_t len)
+int sys_fallocate(int fd, uint32_t mode, off_t offset, off_t len)
 {
 #if 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:
+       int lmode = 0;
+
+       if (mode & VFS_FALLOCATE_FL_KEEP_SIZE) {
+               lmode |= FALLOC_FL_KEEP_SIZE;
+               mode &= ~VFS_FALLOCATE_FL_KEEP_SIZE;
+       }
+
+       if (mode != 0) {
+               DEBUG(2, ("unmapped fallocate flags: %lx\n",
+                     (unsigned long)mode));
                errno = EINVAL;
                return -1;
        }
index 096742863c2aee4f4c148907f6982e9928248706..d53a2de3380c974fe5e3573aaba648dba2c370d4 100644 (file)
@@ -796,8 +796,7 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str
           emulation is being done by the libc (like on AIX with JFS1). In that
           case we do our own emulation. fallocate implementations can
           return ENOTSUP or EINVAL in cases like that. */
-       ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
-                               pst->st_ex_size, space_to_write);
+       ret = SMB_VFS_FALLOCATE(fsp, 0, pst->st_ex_size, space_to_write);
        if (ret == -1 && errno == ENOSPC) {
                return -1;
        }
index 31648f69fe484fa581addd16ccb5b626a63cb1f4..fdb90e410922654be62fb6fdb5b1d6bc23688fd2 100644 (file)
@@ -1861,8 +1861,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. fallocate implementations can
           return ENOTSUP or EINVAL in cases like that. */
-       ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
-                               pst->st_ex_size, space_to_write);
+       ret = SMB_VFS_FALLOCATE(fsp, 0, pst->st_ex_size, space_to_write);
        if (ret == -1 && errno == ENOSPC) {
                return -1;
        }
@@ -1962,14 +1961,14 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t
 
 static int vfswrap_fallocate(vfs_handle_struct *handle,
                        files_struct *fsp,
-                       enum vfs_fallocate_mode mode,
+                       uint32_t mode,
                        off_t offset,
                        off_t len)
 {
        int result;
 
        START_PROFILE(syscall_fallocate);
-       if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
+       if (mode == 0) {
                result = sys_posix_fallocate(fsp->fh->fd, offset, len);
                /*
                 * posix_fallocate returns 0 on success, errno on error
@@ -1980,11 +1979,9 @@ static int vfswrap_fallocate(vfs_handle_struct *handle,
                        errno = result;
                        result = -1;
                }
-       } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
-               result = sys_fallocate(fsp->fh->fd, mode, offset, len);
        } else {
-               errno = EINVAL;
-               result = -1;
+               /* sys_fallocate handles filtering of unsupported mode flags */
+               result = sys_fallocate(fsp->fh->fd, mode, offset, len);
        }
        END_PROFILE(syscall_fallocate);
        return result;
index 0445e04cf0ee95d374011a41b3fc6cca9a856483..fbee3217a8094c6e3337eaa6187c1195640f3c19 100644 (file)
@@ -3039,7 +3039,7 @@ exit:
 
 static int fruit_fallocate(struct vfs_handle_struct *handle,
                           struct files_struct *fsp,
-                          enum vfs_fallocate_mode mode,
+                          uint32_t mode,
                           off_t offset,
                           off_t len)
 {
index b7a4eeeeb44794f374cd1781725eeadc0efbb5cc..87a2f9c3bc4d173eebd4fbffb03f2d949efa2e6a 100644 (file)
@@ -1452,7 +1452,7 @@ static int smb_full_audit_ftruncate(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,
+                          uint32_t mode,
                           off_t offset,
                           off_t len)
 {
index 09c789c790c4e3386c42bc6d17029c9001616496..2c7266e27b4fcf660ddf9a56e2915e9bd541b57d 100644 (file)
@@ -927,9 +927,10 @@ static int vfs_gluster_ftruncate(struct vfs_handle_struct *handle,
 
 static int vfs_gluster_fallocate(struct vfs_handle_struct *handle,
                                 struct files_struct *fsp,
-                                enum vfs_fallocate_mode mode,
+                                uint32_t mode,
                                 off_t offset, off_t len)
 {
+       /* TODO: add support using glfs_fallocate() and glfs_zerofill() */
        errno = ENOTSUP;
        return -1;
 }
index 21707c5f6ccbb120ef17efd5af6cb1585cb90d1c..999e83b16a01dbf8ccfd330e684f166afae71343 100644 (file)
@@ -1843,7 +1843,7 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gpfs_fallocate(struct vfs_handle_struct *handle,
-                      struct files_struct *fsp, enum vfs_fallocate_mode mode,
+                      struct files_struct *fsp, uint32_t mode,
                       off_t offset, off_t len)
 {
        int ret;
@@ -1859,8 +1859,9 @@ static int vfs_gpfs_fallocate(struct vfs_handle_struct *handle,
                return -1;
        }
 
-       if (mode == VFS_FALLOCATE_KEEP_SIZE) {
-               DEBUG(10, ("Unsupported VFS_FALLOCATE_KEEP_SIZE\n"));
+       if (mode != 0) {
+               DEBUG(10, ("unmapped fallocate flags: %lx\n",
+                     (unsigned long)mode));
                errno = ENOTSUP;
                return -1;
        }
index b3c1df15c399a98e1b2d36697460303619436d63..52a9059d80d12468a3e2cfc5765568d04e1323da 100644 (file)
@@ -1093,7 +1093,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
 
 static int streams_xattr_fallocate(struct vfs_handle_struct *handle,
                                        struct files_struct *fsp,
-                                       enum vfs_fallocate_mode mode,
+                                       uint32_t mode,
                                        off_t offset,
                                        off_t len)
 {
index 04552ec9d0cfadf9d69a1220288942332b38ec3d..45e30acfd17b398ebeb67058e1b5ceb2bb3a5698 100644 (file)
@@ -1209,7 +1209,7 @@ static int smb_time_audit_ftruncate(vfs_handle_struct *handle,
 
 static int smb_time_audit_fallocate(vfs_handle_struct *handle,
                                    files_struct *fsp,
-                                   enum vfs_fallocate_mode mode,
+                                   uint32_t mode,
                                    off_t offset,
                                    off_t len)
 {
index 381bb8d2af1fbb679a3ded72c56aaa82d7d6b99f..1e20963da1a2bbe12c1721bd71a56a406e05c549 100644 (file)
@@ -573,7 +573,8 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
        if (lp_strict_allocate(SNUM(fsp->conn))) {
                /* 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);
+               ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
+                                       0, len);
        } else {
                ret = 0;
        }
@@ -728,8 +729,7 @@ int vfs_fill_sparse(files_struct *fsp, off_t len)
                 * emulation is being done by the libc (like on AIX with JFS1). In that
                 * case we do our own emulation. fallocate implementations can
                 * return ENOTSUP or EINVAL in cases like that. */
-               ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
-                               offset, num_to_write);
+               ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
                if (ret == -1 && errno == ENOSPC) {
                        goto out;
                }
@@ -2023,10 +2023,10 @@ int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
 }
 
 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
-                               struct files_struct *fsp,
-                               enum vfs_fallocate_mode mode,
-                               off_t offset,
-                               off_t len)
+                          struct files_struct *fsp,
+                          uint32_t mode,
+                          off_t offset,
+                          off_t len)
 {
        VFS_FIND(fallocate);
        return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);