2 Unix SMB/CIFS implementation.
4 POSIX NTVFS backend - Linux AIO calls
6 Copyright (C) Andrew Tridgell 2006
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.
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.
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/>.
24 #include "vfs_posix.h"
25 #include "system/aio.h"
27 struct pvfs_aio_read_state
{
28 struct ntvfs_request
*req
;
31 struct tevent_aio
*ae
;
34 struct pvfs_aio_write_state
{
35 struct ntvfs_request
*req
;
38 struct tevent_aio
*ae
;
42 called when an aio read has finished
44 static void pvfs_aio_read_handler(struct tevent_context
*ev
, struct tevent_aio
*ae
,
45 int ret
, void *private_data
)
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
;
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
);
59 f
->handle
->position
= f
->handle
->seek_offset
= rd
->readx
.in
.offset
+ ret
;
61 rd
->readx
.out
.nread
= ret
;
62 rd
->readx
.out
.remaining
= 0xFFFF;
63 rd
->readx
.out
.compaction_mode
= 0;
65 talloc_steal(ev
, state
->ae
);
67 state
->req
->async_states
->status
= NT_STATUS_OK
;
68 state
->req
->async_states
->send_fn(state
->req
);
75 NTSTATUS
pvfs_aio_pread(struct ntvfs_request
*req
, union smb_read
*rd
,
76 struct pvfs_file
*f
, uint32_t maxcnt
)
79 struct pvfs_aio_read_state
*state
;
81 state
= talloc(req
, struct pvfs_aio_read_state
);
82 NT_STATUS_HAVE_NO_MEMORY(state
);
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"));
91 return NT_STATUS_NOT_IMPLEMENTED
;
98 req
->async_states
->state
|= NTVFS_ASYNC_STATE_ASYNC
;
107 called when an aio write has finished
109 static void pvfs_aio_write_handler(struct tevent_context
*ev
, struct tevent_aio
*ae
,
110 int ret
, void *private_data
)
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
;
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
);
124 f
->handle
->seek_offset
= wr
->writex
.in
.offset
+ ret
;
126 wr
->writex
.out
.nwritten
= ret
;
127 wr
->writex
.out
.remaining
= 0;
129 talloc_steal(ev
, state
->ae
);
131 state
->req
->async_states
->status
= NT_STATUS_OK
;
132 state
->req
->async_states
->send_fn(state
->req
);
139 NTSTATUS
pvfs_aio_pwrite(struct ntvfs_request
*req
, union smb_write
*wr
,
143 struct pvfs_aio_write_state
*state
;
145 state
= talloc(req
, struct pvfs_aio_write_state
);
146 NT_STATUS_HAVE_NO_MEMORY(state
);
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"));
155 return NT_STATUS_NOT_IMPLEMENTED
;
162 req
->async_states
->state
|= NTVFS_ASYNC_STATE_ASYNC
;