root/source4/ntvfs/posix/pvfs_aio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pvfs_aio_read_handler
  2. pvfs_aio_pread
  3. pvfs_aio_write_handler
  4. pvfs_aio_pwrite

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    POSIX NTVFS backend - Linux AIO calls
   5 
   6    Copyright (C) Andrew Tridgell 2006
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include <tevent.h>
  24 #include "vfs_posix.h"
  25 #include "system/aio.h"
  26 
  27 struct pvfs_aio_read_state {
  28         struct ntvfs_request *req;
  29         union smb_read *rd;
  30         struct pvfs_file *f;
  31         struct tevent_aio *ae;
  32 };
  33 
  34 struct pvfs_aio_write_state {
  35         struct ntvfs_request *req;
  36         union smb_write *wr;
  37         struct pvfs_file *f;
  38         struct tevent_aio *ae;
  39 };
  40 
  41 /*
  42   called when an aio read has finished
  43 */
  44 static void pvfs_aio_read_handler(struct tevent_context *ev, struct tevent_aio *ae,
     /* [<][>][^][v][top][bottom][index][help] */
  45                              int ret, void *private_data)
  46 {
  47         struct pvfs_aio_read_state *state = talloc_get_type(private_data,
  48                                                             struct pvfs_aio_read_state);
  49         struct pvfs_file *f = state->f;
  50         union smb_read *rd = state->rd;
  51 
  52         if (ret < 0) {
  53                 /* errno is -ret on error */
  54                 state->req->async_states->status = pvfs_map_errno(f->pvfs, -ret);
  55                 state->req->async_states->send_fn(state->req);
  56                 return;
  57         }
  58 
  59         f->handle->position = f->handle->seek_offset = rd->readx.in.offset + ret;
  60 
  61         rd->readx.out.nread = ret;
  62         rd->readx.out.remaining = 0xFFFF;
  63         rd->readx.out.compaction_mode = 0; 
  64 
  65         talloc_steal(ev, state->ae);
  66 
  67         state->req->async_states->status = NT_STATUS_OK;
  68         state->req->async_states->send_fn(state->req);
  69 }
  70 
  71 
  72 /*
  73   read from a file
  74 */
  75 NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd,
     /* [<][>][^][v][top][bottom][index][help] */
  76                         struct pvfs_file *f, uint32_t maxcnt)
  77 {
  78         struct iocb iocb;
  79         struct pvfs_aio_read_state *state;
  80 
  81         state = talloc(req, struct pvfs_aio_read_state);
  82         NT_STATUS_HAVE_NO_MEMORY(state);
  83 
  84         io_prep_pread(&iocb, f->handle->fd, rd->readx.out.data,
  85                       maxcnt, rd->readx.in.offset);
  86         state->ae = tevent_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb,
  87                                    pvfs_aio_read_handler, state);
  88         if (state->ae == NULL) {
  89                 DEBUG(0,("Failed tevent_add_aio\n"));
  90                 talloc_free(state);
  91                 return NT_STATUS_NOT_IMPLEMENTED;
  92         }
  93 
  94         state->req  = req;
  95         state->rd   = rd;
  96         state->f    = f;
  97 
  98         req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
  99 
 100         return NT_STATUS_OK;
 101 }
 102 
 103 
 104 
 105 
 106 /*
 107   called when an aio write has finished
 108 */
 109 static void pvfs_aio_write_handler(struct tevent_context *ev, struct tevent_aio *ae,
     /* [<][>][^][v][top][bottom][index][help] */
 110                              int ret, void *private_data)
 111 {
 112         struct pvfs_aio_write_state *state = talloc_get_type(private_data,
 113                                                             struct pvfs_aio_write_state);
 114         struct pvfs_file *f = state->f;
 115         union smb_write *wr = state->wr;
 116 
 117         if (ret < 0) {
 118                 /* errno is -ret on error */
 119                 state->req->async_states->status = pvfs_map_errno(f->pvfs, -ret);
 120                 state->req->async_states->send_fn(state->req);
 121                 return;
 122         }
 123 
 124         f->handle->seek_offset = wr->writex.in.offset + ret;
 125 
 126         wr->writex.out.nwritten = ret;
 127         wr->writex.out.remaining = 0;
 128 
 129         talloc_steal(ev, state->ae);
 130 
 131         state->req->async_states->status = NT_STATUS_OK;
 132         state->req->async_states->send_fn(state->req);
 133 }
 134 
 135 
 136 /*
 137   write to a file
 138 */
 139 NTSTATUS pvfs_aio_pwrite(struct ntvfs_request *req, union smb_write *wr,
     /* [<][>][^][v][top][bottom][index][help] */
 140                          struct pvfs_file *f)
 141 {
 142         struct iocb iocb;
 143         struct pvfs_aio_write_state *state;
 144 
 145         state = talloc(req, struct pvfs_aio_write_state);
 146         NT_STATUS_HAVE_NO_MEMORY(state);
 147 
 148         io_prep_pwrite(&iocb, f->handle->fd, discard_const(wr->writex.in.data),
 149                        wr->writex.in.count, wr->writex.in.offset);
 150         state->ae = tevent_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb,
 151                                    pvfs_aio_write_handler, state);
 152         if (state->ae == NULL) {
 153                 DEBUG(0,("Failed tevent_add_aio\n"));
 154                 talloc_free(state);
 155                 return NT_STATUS_NOT_IMPLEMENTED;
 156         }
 157 
 158         state->req  = req;
 159         state->wr   = wr;
 160         state->f    = f;
 161 
 162         req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
 163 
 164         return NT_STATUS_OK;
 165 }
 166 

/* [<][>][^][v][top][bottom][index][help] */