s3: smbd: Fix *allocate* calls to follow POSIX error return convention.
authorJeremy Allison <jra@samba.org>
Fri, 5 Dec 2014 23:31:19 +0000 (15:31 -0800)
committerJeremy Allison <jra@samba.org>
Sun, 7 Dec 2014 23:33:06 +0000 (00:33 +0100)
vfswrap_fallocate() is broken in that it can call posix_fallocate()
which returns an int error (and doesn't set errno) but can also
call Linux fallocate() which returns -1 and sets errno.

Standardize on the -1,errno convention.

Reported by Jones <jones.kstw@gmail.com> who provided the
initial patch. This patch tested and confirmed working
by him as well.

https://bugzilla.samba.org/show_bug.cgi?id=10982

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@suse.de>
source3/modules/vfs_default.c

index 1e1c318a8934c6986fe85d7db989f673edaa86e8..f5b8f9be11dd98493bd29c26586e81a5c54e8ec0 100644 (file)
@@ -1864,15 +1864,14 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
           return ENOTSUP or EINVAL in cases like that. */
        ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
                                pst->st_ex_size, space_to_write);
-       if (ret == ENOSPC) {
-               errno = ENOSPC;
+       if (ret == -1 && errno == ENOSPC) {
                return -1;
        }
        if (ret == 0) {
                return 0;
        }
        DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
-               "error %d. Falling back to slow manual allocation\n", ret));
+               "error %d. Falling back to slow manual allocation\n", errno));
 
        /* available disk space is enough or not? */
        space_avail = get_dfree_info(fsp->conn,
@@ -1888,8 +1887,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
        /* Write out the real space on disk. */
        ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
        if (ret != 0) {
-               errno = ret;
-               ret = -1;
+               return -1;
        }
 
        return 0;
@@ -1974,6 +1972,15 @@ 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);
+               /*
+                * posix_fallocate returns 0 on success, errno on error
+                * and doesn't set errno. Make it behave like fallocate()
+                * which returns -1, and sets errno on failure.
+                */
+               if (result != 0) {
+                       errno = result;
+                       result = -1;
+               }
        } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
                result = sys_fallocate(fsp->fh->fd, mode, offset, len);
        } else {