s3:vfs_default: optimize vfswrap_asys_finished() and read as much as we can
[samba.git] / source3 / modules / vfs_default.c
index 427e3af9ca3a9dee250738306dc92fbca8588596..0f651dca51119879c184cc5485455f472b1fa271 100644 (file)
@@ -41,7 +41,7 @@
    is sure to try and execute them.  These stubs are used to prevent
    this possibility. */
 
-static int vfswrap_connect(vfs_handle_struct *handle,  const char *service, const char *user)
+static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user)
 {
     return 0;    /* Return >= 0 for success */
 }
@@ -52,7 +52,7 @@ static void vfswrap_disconnect(vfs_handle_struct *handle)
 
 /* Disk operations */
 
-static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, uint64_t *bsize,
+static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize,
                               uint64_t *dfree, uint64_t *dsize)
 {
        uint64_t result;
@@ -61,7 +61,7 @@ static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,  const char *path,
        return result;
 }
 
-static int vfswrap_get_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+static int vfswrap_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
 {
 #ifdef HAVE_SYS_QUOTAS
        int result;
@@ -76,7 +76,7 @@ static int vfswrap_get_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_T
 #endif
 }
 
-static int vfswrap_set_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
 {
 #ifdef HAVE_SYS_QUOTAS
        int result;
@@ -100,7 +100,7 @@ static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle,
        return -1;  /* Not implemented. */
 }
 
-static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path, vfs_statvfs_struct *statbuf)
+static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
 {
        return sys_statvfs(path, statbuf);
 }
@@ -347,7 +347,7 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
 
 /* Directory operations */
 
-static DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
+static DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
 {
        DIR *result;
 
@@ -387,14 +387,14 @@ static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
        return result;
 }
 
-static void vfswrap_seekdir(vfs_handle_struct *handle,  DIR *dirp, long offset)
+static void vfswrap_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset)
 {
        START_PROFILE(syscall_seekdir);
        seekdir(dirp, offset);
        END_PROFILE(syscall_seekdir);
 }
 
-static long vfswrap_telldir(vfs_handle_struct *handle,  DIR *dirp)
+static long vfswrap_telldir(vfs_handle_struct *handle, DIR *dirp)
 {
        long result;
        START_PROFILE(syscall_telldir);
@@ -403,14 +403,14 @@ static long vfswrap_telldir(vfs_handle_struct *handle,  DIR *dirp)
        return result;
 }
 
-static void vfswrap_rewinddir(vfs_handle_struct *handle,  DIR *dirp)
+static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp)
 {
        START_PROFILE(syscall_rewinddir);
        rewinddir(dirp);
        END_PROFILE(syscall_rewinddir);
 }
 
-static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mode)
+static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
 {
        int result;
        bool has_dacl = False;
@@ -444,7 +444,7 @@ static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mo
        return result;
 }
 
-static int vfswrap_rmdir(vfs_handle_struct *handle,  const char *path)
+static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path)
 {
        int result;
 
@@ -454,7 +454,7 @@ static int vfswrap_rmdir(vfs_handle_struct *handle,  const char *path)
        return result;
 }
 
-static int vfswrap_closedir(vfs_handle_struct *handle,  DIR *dirp)
+static int vfswrap_closedir(vfs_handle_struct *handle, DIR *dirp)
 {
        int result;
 
@@ -637,6 +637,7 @@ static void vfswrap_asys_finished(struct tevent_context *ev,
 static bool vfswrap_init_asys_ctx(struct smbXsrv_connection *conn)
 {
        int ret;
+       int fd;
 
        if (conn->asys_ctx != NULL) {
                return true;
@@ -646,8 +647,12 @@ static bool vfswrap_init_asys_ctx(struct smbXsrv_connection *conn)
                DEBUG(1, ("asys_context_init failed: %s\n", strerror(ret)));
                return false;
        }
-       conn->asys_fde = tevent_add_fd(conn->ev_ctx, conn,
-                                      asys_signalfd(conn->asys_ctx),
+
+       fd = asys_signalfd(conn->asys_ctx);
+
+       set_blocking(fd, false);
+
+       conn->asys_fde = tevent_add_fd(conn->ev_ctx, conn, fd,
                                       TEVENT_FD_READ,
                                       vfswrap_asys_finished,
                                       conn->asys_ctx);
@@ -783,24 +788,36 @@ static void vfswrap_asys_finished(struct tevent_context *ev,
                return;
        }
 
-       res = asys_result(asys_ctx, &ret, &err, &private_data);
-       if (res == ECANCELED) {
-               return;
-       }
+       while (true) {
+               res = asys_result(asys_ctx, &ret, &err, &private_data);
+               if (res == EINTR || res == EAGAIN) {
+                       return;
+               }
+#ifdef EWOULDBLOCK
+               if (res == EWOULDBLOCK) {
+                       return;
+               }
+#endif
 
-       if (res != 0) {
-               DEBUG(1, ("asys_result returned %s\n", strerror(res)));
-               return;
-       }
+               if (res == ECANCELED) {
+                       return;
+               }
 
-       req = talloc_get_type_abort(private_data, struct tevent_req);
-       state = tevent_req_data(req, struct vfswrap_asys_state);
+               if (res != 0) {
+                       DEBUG(1, ("asys_result returned %s\n", strerror(res)));
+                       return;
+               }
 
-       talloc_set_destructor(state, NULL);
+               req = talloc_get_type_abort(private_data, struct tevent_req);
+               state = tevent_req_data(req, struct vfswrap_asys_state);
 
-       state->ret = ret;
-       state->err = err;
-       tevent_req_done(req);
+               talloc_set_destructor(state, NULL);
+
+               state->ret = ret;
+               state->err = err;
+               tevent_req_defer_callback(req, ev);
+               tevent_req_done(req);
+       }
 }
 
 static ssize_t vfswrap_asys_ssize_t_recv(struct tevent_req *req, int *err)
@@ -979,7 +996,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                              struct files_struct *fsp,
                              TALLOC_CTX *ctx,
                              uint32_t function,
-                             uint16_t req_flags,  /* Needed for UNICODE ... */
+                             uint16_t req_flags, /* Needed for UNICODE ... */
                              const uint8_t *_in_data,
                              uint32_t in_len,
                              uint8_t **_out_data,
@@ -1370,7 +1387,7 @@ static int vfswrap_unlink(vfs_handle_struct *handle,
        return result;
 }
 
-static int vfswrap_chmod(vfs_handle_struct *handle,  const char *path, mode_t mode)
+static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
 {
        int result;
 
@@ -1466,7 +1483,7 @@ static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid
        return result;
 }
 
-static int vfswrap_chdir(vfs_handle_struct *handle,  const char *path)
+static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
 {
        int result;
 
@@ -1780,7 +1797,7 @@ static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
        return result;
 }
 
-static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
+static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
 {
        int result;
 
@@ -1790,7 +1807,7 @@ static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, cons
        return result;
 }
 
-static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *buf, size_t bufsiz)
+static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
 {
        int result;
 
@@ -1800,7 +1817,7 @@ static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *
        return result;
 }
 
-static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
+static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
 {
        int result;
 
@@ -1810,7 +1827,7 @@ static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const c
        return result;
 }
 
-static int vfswrap_mknod(vfs_handle_struct *handle,  const char *pathname, mode_t mode, SMB_DEV_T dev)
+static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
 {
        int result;
 
@@ -1820,7 +1837,7 @@ static int vfswrap_mknod(vfs_handle_struct *handle,  const char *pathname, mode_
        return result;
 }
 
-static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path)
+static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
 {
        char *result;
 
@@ -2039,12 +2056,14 @@ static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
                                    files_struct *fsp,
                                    uint32 security_info,
+                                   TALLOC_CTX *mem_ctx,
                                    struct security_descriptor **ppdesc)
 {
        NTSTATUS result;
 
        START_PROFILE(fget_nt_acl);
-       result = posix_fget_nt_acl(fsp, security_info, ppdesc);
+       result = posix_fget_nt_acl(fsp, security_info,
+                                  mem_ctx, ppdesc);
        END_PROFILE(fget_nt_acl);
        return result;
 }
@@ -2052,12 +2071,14 @@ static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
                                   const char *name,
                                   uint32 security_info,
+                                  TALLOC_CTX *mem_ctx,
                                   struct security_descriptor **ppdesc)
 {
        NTSTATUS result;
 
        START_PROFILE(get_nt_acl);
-       result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
+       result = posix_get_nt_acl(handle->conn, name, security_info,
+                                 mem_ctx, ppdesc);
        END_PROFILE(get_nt_acl);
        return result;
 }
@@ -2081,7 +2102,7 @@ static NTSTATUS vfswrap_audit_file(struct vfs_handle_struct *handle,
        return NT_STATUS_OK; /* Nothing to do here ... */
 }
 
-static int vfswrap_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
+static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
 {
 #ifdef HAVE_NO_ACL
        errno = ENOSYS;
@@ -2111,17 +2132,22 @@ static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode
 #endif
 }
 
-static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type)
+static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,
+                                         const char *path_p,
+                                         SMB_ACL_TYPE_T type,
+                                         TALLOC_CTX *mem_ctx)
 {
-       return sys_acl_get_file(handle, path_p, type);
+       return sys_acl_get_file(handle, path_p, type, mem_ctx);
 }
 
-static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
+static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle,
+                                       files_struct *fsp,
+                                       TALLOC_CTX *mem_ctx)
 {
-       return sys_acl_get_fd(handle, fsp);
+       return sys_acl_get_fd(handle, fsp, mem_ctx);
 }
 
-static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
 {
        return sys_acl_set_file(handle, name, acltype, theacl);
 }
@@ -2131,7 +2157,7 @@ static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
        return sys_acl_set_fd(handle, fsp, theacl);
 }
 
-static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,  const char *path)
+static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
 {
        return sys_acl_delete_def_file(handle, path);
 }
@@ -2232,7 +2258,7 @@ static NTSTATUS vfswrap_durable_cookie(struct vfs_handle_struct *handle,
                                       TALLOC_CTX *mem_ctx,
                                       DATA_BLOB *cookie)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       return vfs_default_durable_cookie(fsp, mem_ctx, cookie);
 }
 
 static NTSTATUS vfswrap_durable_disconnect(struct vfs_handle_struct *handle,
@@ -2241,7 +2267,8 @@ static NTSTATUS vfswrap_durable_disconnect(struct vfs_handle_struct *handle,
                                           TALLOC_CTX *mem_ctx,
                                           DATA_BLOB *new_cookie)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       return vfs_default_durable_disconnect(fsp, old_cookie, mem_ctx,
+                                             new_cookie);
 }
 
 static NTSTATUS vfswrap_durable_reconnect(struct vfs_handle_struct *handle,
@@ -2252,7 +2279,9 @@ static NTSTATUS vfswrap_durable_reconnect(struct vfs_handle_struct *handle,
                                          struct files_struct **fsp,
                                          DATA_BLOB *new_cookie)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       return vfs_default_durable_reconnect(handle->conn, smb1req, op,
+                                            old_cookie, mem_ctx,
+                                            fsp, new_cookie);
 }
 
 static struct vfs_fn_pointers vfs_default_fns = {
@@ -2353,6 +2382,8 @@ static struct vfs_fn_pointers vfs_default_fns = {
 
        .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
        .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
+       .sys_acl_blob_get_file_fn = posix_sys_acl_blob_get_file,
+       .sys_acl_blob_get_fd_fn = posix_sys_acl_blob_get_fd,
        .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
        .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,