From 427fa23ca536f0a0388460f05bd2422e13e04414 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Jan 2007 05:47:00 +0000 Subject: r20698: added AIO writing support (This used to be commit dbf54c7b49d427af8112414760369cd21c8b5941) --- source4/ntvfs/posix/pvfs_aio.c | 75 ++++++++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_write.c | 10 ++++++ source4/ntvfs/posix/vfs_posix.h | 2 ++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/source4/ntvfs/posix/pvfs_aio.c b/source4/ntvfs/posix/pvfs_aio.c index 262b856aa9..f40382b5ec 100644 --- a/source4/ntvfs/posix/pvfs_aio.c +++ b/source4/ntvfs/posix/pvfs_aio.c @@ -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; +} + diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 9f58281919..d433a80cc6 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -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, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4fd4cb82d8..5bb9dcf811 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -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_ */ -- cgit