r20698: added AIO writing support
authorAndrew Tridgell <tridge@samba.org>
Fri, 12 Jan 2007 05:47:00 +0000 (05:47 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:40:24 +0000 (14:40 -0500)
(This used to be commit dbf54c7b49d427af8112414760369cd21c8b5941)

source4/ntvfs/posix/pvfs_aio.c
source4/ntvfs/posix/pvfs_write.c
source4/ntvfs/posix/vfs_posix.h

index 262b856aa971b748321b699bf51b9f74a2d8d331..f40382b5ecedfe738b7a7f188ec149ad33ea80a3 100644 (file)
@@ -32,10 +32,17 @@ struct pvfs_aio_read_state {
        struct aio_event *ae;
 };
 
+struct pvfs_aio_write_state {
+       struct ntvfs_request *req;
+       union smb_write *wr;
+       struct pvfs_file *f;
+       struct aio_event *ae;
+};
+
 /*
   called when an aio read has finished
 */
-static void pvfs_aio_handler(struct event_context *ev, struct aio_event *ae, 
+static void pvfs_aio_read_handler(struct event_context *ev, struct aio_event *ae, 
                             int ret, void *private)
 {
        struct pvfs_aio_read_state *state = talloc_get_type(private, 
@@ -78,7 +85,7 @@ NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd,
         io_prep_pread(&iocb, f->handle->fd, rd->readx.out.data,
                      maxcnt, rd->readx.in.offset);
        state->ae = event_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb, 
-                                 pvfs_aio_handler, state);
+                                 pvfs_aio_read_handler, state);
        if (state->ae == NULL) {
                DEBUG(0,("Failed event_add_aio\n"));
                talloc_free(state);
@@ -94,3 +101,67 @@ NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd,
        return NT_STATUS_OK;
 }
 
+
+
+
+/*
+  called when an aio write has finished
+*/
+static void pvfs_aio_write_handler(struct event_context *ev, struct aio_event *ae, 
+                            int ret, void *private)
+{
+       struct pvfs_aio_write_state *state = talloc_get_type(private, 
+                                                           struct pvfs_aio_write_state);
+       struct pvfs_file *f = state->f;
+       union smb_write *wr = state->wr;
+
+       if (ret < 0) {
+               /* errno is -ret on error */
+               state->req->async_states->status = pvfs_map_errno(f->pvfs, -ret);
+               state->req->async_states->send_fn(state->req);
+               return;
+       }
+
+       f->handle->seek_offset = wr->writex.in.offset + ret;
+
+       wr->writex.out.nwritten = ret;
+       wr->writex.out.remaining = 0;
+
+       talloc_steal(ev, state->ae);
+
+       state->req->async_states->status = NT_STATUS_OK;
+       state->req->async_states->send_fn(state->req);
+}
+
+
+/*
+  write to a file
+*/
+NTSTATUS pvfs_aio_pwrite(struct ntvfs_request *req, union smb_write *wr,
+                        struct pvfs_file *f)
+{
+       struct iocb iocb;
+       struct pvfs_aio_write_state *state;
+
+       state = talloc(req, struct pvfs_aio_write_state);
+       NT_STATUS_HAVE_NO_MEMORY(state);
+
+        io_prep_pwrite(&iocb, f->handle->fd, wr->writex.in.data,
+                      wr->writex.in.count, wr->writex.in.offset);
+       state->ae = event_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb, 
+                                 pvfs_aio_write_handler, state);
+       if (state->ae == NULL) {
+               DEBUG(0,("Failed event_add_aio\n"));
+               talloc_free(state);
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       state->req  = req;
+       state->wr   = wr;
+       state->f    = f;
+
+       req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+
+       return NT_STATUS_OK;
+}
+
index 9f582819192ee22edb36b1e17212d4533d65a528..d433a80cc6426f54f4d6517a24687b22f5c3fc60 100644 (file)
@@ -66,6 +66,16 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs,
                                        wr->writex.in.count,
                                        wr->writex.in.offset);
        } else {
+#if HAVE_LINUX_AIO
+               /* possibly try an aio write */
+               if ((req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC) &&
+                   (pvfs->flags & PVFS_FLAG_LINUX_AIO)) {
+                       status = pvfs_aio_pwrite(req, wr, f);
+                       if (NT_STATUS_IS_OK(status)) {
+                               return NT_STATUS_OK;
+                       }
+               }
+#endif
                ret = pwrite(f->handle->fd, 
                             wr->writex.in.data, 
                             wr->writex.in.count,
index 4fd4cb82d8307b6a4f2c5cb229598dd40c99170f..5bb9dcf811f452ebbd63d750a0a65ec364a2b933 100644 (file)
@@ -244,5 +244,7 @@ struct pvfs_acl_ops {
 
 NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd,
                        struct pvfs_file *f, uint32_t maxcnt);
+NTSTATUS pvfs_aio_pwrite(struct ntvfs_request *req, union smb_write *wr,
+                        struct pvfs_file *f);
 
 #endif /* _VFS_POSIX_H_ */