s3: Move the aio_pthread read/write functionality to vfs_default
authorVolker Lendecke <vl@samba.org>
Thu, 12 Jul 2012 08:32:39 +0000 (10:32 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 18 Jul 2012 22:46:29 +0000 (15:46 -0700)
Signed-off-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_aio_pthread.c
source3/modules/vfs_default.c
source3/modules/wscript_build
source3/smbd/globals.h
source3/wscript_build

index 06ac8b866759ae175dbed97bc1fa801a57b872d3..6edb12d95e9dc8d2da872d5e1c826cde2cc844f7 100644 (file)
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
 #include "lib/pthreadpool/pthreadpool.h"
-#include "lib/asys/asys.h"
-#include "lib/util/tevent_unix.h"
 #ifdef HAVE_LINUX_FALLOC_H
 #include <linux/falloc.h>
 #endif
 
-static struct asys_context *asys_ctx;
-struct tevent_fd *asys_fde;
-
-struct aio_pthread_state {
-       struct tevent_req *req;
-       ssize_t ret;
-       int err;
-};
-
-static int aio_pthread_state_destructor(struct aio_pthread_state *s)
-{
-       asys_cancel(asys_ctx, s->req);
-       return 0;
-}
-
-static struct tevent_req *aio_pthread_pread_send(
-       struct vfs_handle_struct *handle,
-       TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-       struct files_struct *fsp, void *data, size_t n, off_t offset)
-{
-       struct tevent_req *req;
-       struct aio_pthread_state *state;
-       int ret;
-
-       req = tevent_req_create(mem_ctx, &state, struct aio_pthread_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->req = req;
-
-       ret = asys_pread(asys_ctx, fsp->fh->fd, data, n, offset, req);
-       if (ret != 0) {
-               tevent_req_error(req, ret);
-               return tevent_req_post(req, ev);
-       }
-       talloc_set_destructor(state, aio_pthread_state_destructor);
-
-       return req;
-}
-
-static struct tevent_req *aio_pthread_pwrite_send(
-       struct vfs_handle_struct *handle,
-       TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-       struct files_struct *fsp, const void *data, size_t n, off_t offset)
-{
-       struct tevent_req *req;
-       struct aio_pthread_state *state;
-       int ret;
-
-       req = tevent_req_create(mem_ctx, &state, struct aio_pthread_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->req = req;
-
-       ret = asys_pwrite(asys_ctx, fsp->fh->fd, data, n, offset, req);
-       if (ret != 0) {
-               tevent_req_error(req, ret);
-               return tevent_req_post(req, ev);
-       }
-       talloc_set_destructor(state, aio_pthread_state_destructor);
-
-       return req;
-}
-
-static void aio_pthread_finished(struct tevent_context *ev,
-                                struct tevent_fd *fde,
-                                uint16_t flags, void *p)
-{
-       struct tevent_req *req;
-       struct aio_pthread_state *state;
-       int res;
-       ssize_t ret;
-       int err;
-       void *private_data;
-
-       if ((flags & TEVENT_FD_READ) == 0) {
-               return;
-       }
-
-       res = asys_result(asys_ctx, &ret, &err, &private_data);
-       if (res == ECANCELED) {
-               return;
-       }
-
-       if (res != 0) {
-               DEBUG(1, ("asys_result returned %s\n", strerror(res)));
-               return;
-       }
-
-       req = talloc_get_type_abort(private_data, struct tevent_req);
-       state = tevent_req_data(req, struct aio_pthread_state);
-
-       talloc_set_destructor(state, NULL);
-
-       state->ret = ret;
-       state->err = err;
-       tevent_req_done(req);
-}
-
-static ssize_t aio_pthread_recv(struct tevent_req *req, int *err)
-{
-       struct aio_pthread_state *state = tevent_req_data(
-               req, struct aio_pthread_state);
-
-       if (tevent_req_is_unix_error(req, err)) {
-               return -1;
-       }
-       *err = state->err;
-       return state->ret;
-}
-
-
 #if defined(HAVE_OPENAT) && defined(USE_LINUX_THREAD_CREDENTIALS)
 
 /************************************************************************
@@ -597,55 +482,10 @@ static int aio_pthread_open_fn(vfs_handle_struct *handle,
 }
 #endif
 
-static int aio_pthread_connect(vfs_handle_struct *handle, const char *service,
-                              const char *user)
-{
-       /*********************************************************************
-        * How many threads to initialize ?
-        * 100 per process seems insane as a default until you realize that
-        * (a) Threads terminate after 1 second when idle.
-        * (b) Throttling is done in SMB2 via the crediting algorithm.
-        * (c) SMB1 clients are limited to max_mux (50) outstanding
-        *     requests and Windows clients don't use this anyway.
-        * Essentially we want this to be unlimited unless smb.conf
-        * says different.
-        *********************************************************************/
-       aio_pending_size = lp_parm_int(
-               SNUM(handle->conn), "aio_pthread", "aio num threads", 100);
-
-       if (asys_ctx == NULL) {
-               int ret;
-
-               ret = asys_context_init(&asys_ctx, aio_pending_size);
-               if (ret != 0) {
-                       DEBUG(1, ("asys_context_init failed: %s\n",
-                                 strerror(ret)));
-                       return -1;
-               }
-
-               asys_fde = tevent_add_fd(handle->conn->sconn->ev_ctx, NULL,
-                                        asys_signalfd(asys_ctx),
-                                        TEVENT_FD_READ, aio_pthread_finished,
-                                        NULL);
-               if (asys_fde == NULL) {
-                       DEBUG(1, ("tevent_add_fd failed\n"));
-                       asys_context_destroy(asys_ctx);
-                       asys_ctx = NULL;
-                       return -1;
-               }
-       }
-       return SMB_VFS_NEXT_CONNECT(handle, service, user);
-}
-
 static struct vfs_fn_pointers vfs_aio_pthread_fns = {
-       .connect_fn = aio_pthread_connect,
 #if defined(HAVE_OPENAT) && defined(USE_LINUX_THREAD_CREDENTIALS)
        .open_fn = aio_pthread_open_fn,
 #endif
-       .pread_send_fn = aio_pthread_pread_send,
-       .pread_recv_fn = aio_pthread_recv,
-       .pwrite_send_fn = aio_pthread_pwrite_send,
-       .pwrite_recv_fn = aio_pthread_recv,
 };
 
 NTSTATUS vfs_aio_pthread_init(void);
index c9d32389c77f1c8fbafffde83fd5a793ce428328..c79eed0b9708d167c40e3516c87b65f259df5208 100644 (file)
@@ -30,6 +30,7 @@
 #include "source3/include/msdfs.h"
 #include "librpc/gen_ndr/ndr_dfsblobs.h"
 #include "lib/util/tevent_unix.h"
+#include "lib/asys/asys.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -580,49 +581,6 @@ static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void
        return result;
 }
 
-struct vfswrap_pread_state {
-       ssize_t ret;
-};
-
-static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
-                                            TALLOC_CTX *mem_ctx,
-                                            struct tevent_context *ev,
-                                            struct files_struct *fsp,
-                                            void *data,
-                                            size_t n, off_t offset)
-{
-       struct tevent_req *req;
-       struct vfswrap_pread_state *state;
-       int saved_errno;
-
-       req = tevent_req_create(req, &state, struct vfswrap_pread_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       START_PROFILE_BYTES(syscall_pread, n);
-       state->ret = sys_pread(fsp->fh->fd, data, n, offset);
-       saved_errno = errno;
-       END_PROFILE(syscall_pread);
-
-       if (state->ret == -1) {
-               tevent_req_error(req, saved_errno);
-               return tevent_req_post(req, ev);
-       }
-       tevent_req_done(req);
-       return tevent_req_post(req, ev);
-}
-
-static ssize_t vfswrap_pread_recv(struct tevent_req *req, int *err)
-{
-       struct vfswrap_pread_state *state = tevent_req_data(
-               req, struct vfswrap_pread_state);
-
-       if (tevent_req_is_unix_error(req, err)) {
-               return -1;
-       }
-       return state->ret;
-}
-
 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
 {
        ssize_t result;
@@ -672,49 +630,159 @@ static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, cons
        return result;
 }
 
-struct vfswrap_pwrite_state {
-       ssize_t retval;
+static void vfswrap_asys_finished(struct tevent_context *ev,
+                                 struct tevent_fd *fde,
+                                 uint16_t flags, void *p);
+
+static bool vfswrap_init_asys_ctx(struct smbXsrv_connection *conn)
+{
+       int ret;
+
+       if (conn->asys_ctx != NULL) {
+               return true;
+       }
+       ret = asys_context_init(&conn->asys_ctx, aio_pending_size);
+       if (ret != 0) {
+               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),
+                                      TEVENT_FD_READ,
+                                      vfswrap_asys_finished,
+                                      conn->asys_ctx);
+       if (conn->asys_fde == NULL) {
+               DEBUG(1, ("tevent_add_fd failed\n"));
+               asys_context_destroy(conn->asys_ctx);
+               conn->asys_ctx = NULL;
+               return false;
+       }
+       return true;
+}
+
+struct vfswrap_asys_state {
+       struct asys_context *asys_ctx;
+       struct tevent_req *req;
+       ssize_t ret;
+       int err;
 };
 
-static struct tevent_req *vfswrap_pwrite_send(
-       struct vfs_handle_struct *handle,
-       TALLOC_CTX *mem_ctx, struct tevent_context *ev,
-       struct files_struct *fsp, const void *data, size_t n, off_t offset)
+static int vfswrap_asys_state_destructor(struct vfswrap_asys_state *s)
+{
+       asys_cancel(s->asys_ctx, s->req);
+       return 0;
+}
+
+static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
+                                            TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct files_struct *fsp,
+                                            void *data,
+                                            size_t n, off_t offset)
 {
        struct tevent_req *req;
-       struct vfswrap_pwrite_state *state;
-       int saved_errno;
+       struct vfswrap_asys_state *state;
+       int ret;
 
-       req = tevent_req_create(mem_ctx, &state,
-                               struct vfswrap_pwrite_state);
+       req = tevent_req_create(mem_ctx, &state, struct vfswrap_asys_state);
        if (req == NULL) {
                return NULL;
        }
+       if (!vfswrap_init_asys_ctx(handle->conn->sconn->conn)) {
+               tevent_req_oom(req);
+               return tevent_req_post(req, ev);
+       }
+       state->asys_ctx = handle->conn->sconn->conn->asys_ctx;
+       state->req = req;
 
-       START_PROFILE_BYTES(syscall_pwrite, n);
-       state->retval = sys_pwrite(fsp->fh->fd, data, n, offset);
-       saved_errno = errno;
-       END_PROFILE(syscall_pwrite);
+       ret = asys_pread(state->asys_ctx, fsp->fh->fd, data, n, offset, req);
+       if (ret != 0) {
+               tevent_req_error(req, ret);
+               return tevent_req_post(req, ev);
+       }
+       talloc_set_destructor(state, vfswrap_asys_state_destructor);
 
-       if (state->retval == -1) {
-               tevent_req_error(req, saved_errno);
-       } else {
-               tevent_req_done(req);
+       return req;
+}
+
+static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
+                                             TALLOC_CTX *mem_ctx,
+                                             struct tevent_context *ev,
+                                             struct files_struct *fsp,
+                                             const void *data,
+                                             size_t n, off_t offset)
+{
+       struct tevent_req *req;
+       struct vfswrap_asys_state *state;
+       int ret;
+
+       req = tevent_req_create(mem_ctx, &state, struct vfswrap_asys_state);
+       if (req == NULL) {
+               return NULL;
        }
-       return tevent_req_post(req, ev);
+       if (!vfswrap_init_asys_ctx(handle->conn->sconn->conn)) {
+               tevent_req_oom(req);
+               return tevent_req_post(req, ev);
+       }
+       state->asys_ctx = handle->conn->sconn->conn->asys_ctx;
+       state->req = req;
+
+       ret = asys_pwrite(state->asys_ctx, fsp->fh->fd, data, n, offset, req);
+       if (ret != 0) {
+               tevent_req_error(req, ret);
+               return tevent_req_post(req, ev);
+       }
+       talloc_set_destructor(state, vfswrap_asys_state_destructor);
+
+       return req;
 }
 
-static ssize_t vfswrap_pwrite_recv(struct tevent_req *req, int *perrno)
+static void vfswrap_asys_finished(struct tevent_context *ev,
+                                       struct tevent_fd *fde,
+                                       uint16_t flags, void *p)
 {
-       struct vfswrap_pwrite_state *state = tevent_req_data(
-               req, struct vfswrap_pwrite_state);
+       struct asys_context *asys_ctx = (struct asys_context *)p;
+       struct tevent_req *req;
+       struct vfswrap_asys_state *state;
+       int res;
+       ssize_t ret;
        int err;
+       void *private_data;
+
+       if ((flags & TEVENT_FD_READ) == 0) {
+               return;
+       }
+
+       res = asys_result(asys_ctx, &ret, &err, &private_data);
+       if (res == ECANCELED) {
+               return;
+       }
+
+       if (res != 0) {
+               DEBUG(1, ("asys_result returned %s\n", strerror(res)));
+               return;
+       }
+
+       req = talloc_get_type_abort(private_data, struct tevent_req);
+       state = tevent_req_data(req, struct vfswrap_asys_state);
+
+       talloc_set_destructor(state, NULL);
+
+       state->ret = ret;
+       state->err = err;
+       tevent_req_done(req);
+}
+
+static ssize_t vfswrap_asys_ssize_t_recv(struct tevent_req *req, int *err)
+{
+       struct vfswrap_asys_state *state = tevent_req_data(
+               req, struct vfswrap_asys_state);
 
-       if (tevent_req_is_unix_error(req, &err)) {
-               *perrno = err;
+       if (tevent_req_is_unix_error(req, err)) {
                return -1;
        }
-       return state->retval;
+       *err = state->err;
+       return state->ret;
 }
 
 static off_t vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
@@ -2236,11 +2304,11 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .read_fn = vfswrap_read,
        .pread_fn = vfswrap_pread,
        .pread_send_fn = vfswrap_pread_send,
-       .pread_recv_fn = vfswrap_pread_recv,
+       .pread_recv_fn = vfswrap_asys_ssize_t_recv,
        .write_fn = vfswrap_write,
        .pwrite_fn = vfswrap_pwrite,
        .pwrite_send_fn = vfswrap_pwrite_send,
-       .pwrite_recv_fn = vfswrap_pwrite_recv,
+       .pwrite_recv_fn = vfswrap_asys_ssize_t_recv,
        .lseek_fn = vfswrap_lseek,
        .sendfile_fn = vfswrap_sendfile,
        .recvfile_fn = vfswrap_recvfile,
index 2f5088ad24ad71bcecbfd67247a3c324b2412cab..aaefd987276bcd0615b341dcfd555d22f7389bc5 100644 (file)
@@ -358,7 +358,7 @@ bld.SAMBA3_MODULE('vfs_aio_fork',
 bld.SAMBA3_MODULE('vfs_aio_pthread',
                  subsystem='vfs',
                  source=VFS_AIO_PTHREAD_SRC,
-                 deps='samba-util tevent LIBASYS',
+                 deps='samba-util tevent',
                  init_function='',
                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_aio_pthread'),
                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_aio_pthread'),
index 80612eb716c93696ac66a5ecbee73db5640857d1..c400181130060401268b7433d2cc9bbab11bc419 100644 (file)
@@ -347,6 +347,12 @@ struct smbXsrv_connection {
 
        struct msg_state *msg_state;
 
+       /*
+        * Link into libasys for asynchronous operations
+        */
+       struct asys_context *asys_ctx;
+       struct tevent_fd *asys_fde;
+
        uint64_t smbd_idle_profstamp;
 
        /*
index 672129dbccaeebef47499cea63abdb91eba15b9d..3b3bdeac9f14f8c404945ceafed2eae93ff9e71e 100755 (executable)
@@ -935,6 +935,7 @@ bld.SAMBA3_LIBRARY('smbd_base',
                     LIBAFS_SETTOKEN
                     RPC_SERVER
                     NDR_SMBXSRV
+                   LIBASYS
                     ccan-hash
                     ''',
                     private_library=True,