aa8aee00fbec729b4d03a9dcbf94deba7275f9b6
[nivanova/samba-autobuild/.git] / source3 / smbd / aio.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    async_io read handling using POSIX async io.
5    Copyright (C) Jeremy Allison 2005.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "smbd/smbd.h"
23 #include "smbd/globals.h"
24 #include "../lib/util/tevent_ntstatus.h"
25
26 #if defined(WITH_AIO)
27
28 /* The signal we'll use to signify aio done. */
29 #ifndef RT_SIGNAL_AIO
30 #define RT_SIGNAL_AIO   (SIGRTMIN+3)
31 #endif
32
33 #ifndef HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIVAL_PTR
34 #ifdef HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIGVAL_PTR
35 #define sival_int       sigval_int
36 #define sival_ptr       sigval_ptr
37 #endif
38 #endif
39
40 /****************************************************************************
41  The buffer we keep around whilst an aio request is in process.
42 *****************************************************************************/
43
44 struct aio_extra {
45         struct aio_extra *next, *prev;
46         SMB_STRUCT_AIOCB acb;
47         files_struct *fsp;
48         struct smb_request *smbreq;
49         DATA_BLOB outbuf;
50         struct lock_struct lock;
51         bool write_through;
52         int (*handle_completion)(struct aio_extra *ex, int errcode);
53 };
54
55 /****************************************************************************
56  Initialize the signal handler for aio read/write.
57 *****************************************************************************/
58
59 static void smbd_aio_signal_handler(struct tevent_context *ev_ctx,
60                                     struct tevent_signal *se,
61                                     int signum, int count,
62                                     void *_info, void *private_data)
63 {
64         siginfo_t *info = (siginfo_t *)_info;
65         struct aio_extra *aio_ex = (struct aio_extra *)
66                                 info->si_value.sival_ptr;
67
68         smbd_aio_complete_aio_ex(aio_ex);
69         TALLOC_FREE(aio_ex);
70 }
71
72
73 bool initialize_async_io_handler(void)
74 {
75         static bool tried_signal_setup = false;
76
77         if (aio_signal_event) {
78                 return true;
79         }
80         if (tried_signal_setup) {
81                 return false;
82         }
83         tried_signal_setup = true;
84
85         aio_signal_event = tevent_add_signal(server_event_context(),
86                                              server_event_context(),
87                                              RT_SIGNAL_AIO, SA_SIGINFO,
88                                              smbd_aio_signal_handler,
89                                              NULL);
90         if (!aio_signal_event) {
91                 DEBUG(10, ("Failed to setup RT_SIGNAL_AIO handler\n"));
92                 return false;
93         }
94
95         /* tevent supports 100 signal with SA_SIGINFO */
96         aio_pending_size = 100;
97         return true;
98 }
99
100 static int handle_aio_read_complete(struct aio_extra *aio_ex, int errcode);
101 static int handle_aio_write_complete(struct aio_extra *aio_ex, int errcode);
102 static int handle_aio_smb2_read_complete(struct aio_extra *aio_ex, int errcode);
103 static int handle_aio_smb2_write_complete(struct aio_extra *aio_ex, int errcode);
104
105 static int aio_extra_destructor(struct aio_extra *aio_ex)
106 {
107         DLIST_REMOVE(aio_list_head, aio_ex);
108         outstanding_aio_calls--;
109         return 0;
110 }
111
112 /****************************************************************************
113  Create the extended aio struct we must keep around for the lifetime
114  of the aio call.
115 *****************************************************************************/
116
117 static struct aio_extra *create_aio_extra(TALLOC_CTX *mem_ctx,
118                                         files_struct *fsp,
119                                         size_t buflen)
120 {
121         struct aio_extra *aio_ex = talloc_zero(mem_ctx, struct aio_extra);
122
123         if (!aio_ex) {
124                 return NULL;
125         }
126
127         /* The output buffer stored in the aio_ex is the start of
128            the smb return buffer. The buffer used in the acb
129            is the start of the reply data portion of that buffer. */
130
131         if (buflen) {
132                 aio_ex->outbuf = data_blob_talloc(aio_ex, NULL, buflen);
133                 if (!aio_ex->outbuf.data) {
134                         TALLOC_FREE(aio_ex);
135                         return NULL;
136                 }
137         }
138         DLIST_ADD(aio_list_head, aio_ex);
139         talloc_set_destructor(aio_ex, aio_extra_destructor);
140         aio_ex->fsp = fsp;
141         outstanding_aio_calls++;
142         return aio_ex;
143 }
144
145 /****************************************************************************
146  Set up an aio request from a SMBreadX call.
147 *****************************************************************************/
148
149 NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
150                              struct smb_request *smbreq,
151                              files_struct *fsp, off_t startpos,
152                              size_t smb_maxcnt)
153 {
154         struct aio_extra *aio_ex;
155         SMB_STRUCT_AIOCB *a;
156         size_t bufsize;
157         size_t min_aio_read_size = lp_aio_read_size(SNUM(conn));
158         int ret;
159
160         if (fsp->base_fsp != NULL) {
161                 /* No AIO on streams yet */
162                 DEBUG(10, ("AIO on streams not yet supported\n"));
163                 return NT_STATUS_RETRY;
164         }
165
166         if ((!min_aio_read_size || (smb_maxcnt < min_aio_read_size))
167             && !SMB_VFS_AIO_FORCE(fsp)) {
168                 /* Too small a read for aio request. */
169                 DEBUG(10,("schedule_aio_read_and_X: read size (%u) too small "
170                           "for minimum aio_read of %u\n",
171                           (unsigned int)smb_maxcnt,
172                           (unsigned int)min_aio_read_size ));
173                 return NT_STATUS_RETRY;
174         }
175
176         /* Only do this on non-chained and non-chaining reads not using the
177          * write cache. */
178         if (req_is_in_chain(smbreq) || (lp_write_cache_size(SNUM(conn)) != 0)) {
179                 return NT_STATUS_RETRY;
180         }
181
182         if (outstanding_aio_calls >= aio_pending_size) {
183                 DEBUG(10,("schedule_aio_read_and_X: Already have %d aio "
184                           "activities outstanding.\n",
185                           outstanding_aio_calls ));
186                 return NT_STATUS_RETRY;
187         }
188
189         /* The following is safe from integer wrap as we've already checked
190            smb_maxcnt is 128k or less. Wct is 12 for read replies */
191
192         bufsize = smb_size + 12 * 2 + smb_maxcnt;
193
194         if ((aio_ex = create_aio_extra(NULL, fsp, bufsize)) == NULL) {
195                 DEBUG(10,("schedule_aio_read_and_X: malloc fail.\n"));
196                 return NT_STATUS_NO_MEMORY;
197         }
198         aio_ex->handle_completion = handle_aio_read_complete;
199
200         construct_reply_common_req(smbreq, (char *)aio_ex->outbuf.data);
201         srv_set_message((char *)aio_ex->outbuf.data, 12, 0, True);
202         SCVAL(aio_ex->outbuf.data,smb_vwv0,0xFF); /* Never a chained reply. */
203
204         init_strict_lock_struct(fsp, (uint64_t)smbreq->smbpid,
205                 (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
206                 &aio_ex->lock);
207
208         /* Take the lock until the AIO completes. */
209         if (!SMB_VFS_STRICT_LOCK(conn, fsp, &aio_ex->lock)) {
210                 TALLOC_FREE(aio_ex);
211                 return NT_STATUS_FILE_LOCK_CONFLICT;
212         }
213
214         a = &aio_ex->acb;
215
216         /* Now set up the aio record for the read call. */
217
218         a->aio_fildes = fsp->fh->fd;
219         a->aio_buf = smb_buf(aio_ex->outbuf.data);
220         a->aio_nbytes = smb_maxcnt;
221         a->aio_offset = startpos;
222         a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
223         a->aio_sigevent.sigev_signo  = RT_SIGNAL_AIO;
224         a->aio_sigevent.sigev_value.sival_ptr = aio_ex;
225
226         ret = SMB_VFS_AIO_READ(fsp, a);
227         if (ret == -1) {
228                 DEBUG(0,("schedule_aio_read_and_X: aio_read failed. "
229                          "Error %s\n", strerror(errno) ));
230                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &aio_ex->lock);
231                 TALLOC_FREE(aio_ex);
232                 return NT_STATUS_RETRY;
233         }
234
235         aio_ex->smbreq = talloc_move(aio_ex, &smbreq);
236
237         DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, "
238                   "offset %.0f, len = %u (mid = %u)\n",
239                   fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt,
240                   (unsigned int)aio_ex->smbreq->mid ));
241
242         return NT_STATUS_OK;
243 }
244
245 /****************************************************************************
246  Set up an aio request from a SMBwriteX call.
247 *****************************************************************************/
248
249 NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
250                               struct smb_request *smbreq,
251                               files_struct *fsp, const char *data,
252                               off_t startpos,
253                               size_t numtowrite)
254 {
255         struct aio_extra *aio_ex;
256         SMB_STRUCT_AIOCB *a;
257         size_t bufsize;
258         size_t min_aio_write_size = lp_aio_write_size(SNUM(conn));
259         int ret;
260
261         if (fsp->base_fsp != NULL) {
262                 /* No AIO on streams yet */
263                 DEBUG(10, ("AIO on streams not yet supported\n"));
264                 return NT_STATUS_RETRY;
265         }
266
267         if ((!min_aio_write_size || (numtowrite < min_aio_write_size))
268             && !SMB_VFS_AIO_FORCE(fsp)) {
269                 /* Too small a write for aio request. */
270                 DEBUG(10,("schedule_aio_write_and_X: write size (%u) too "
271                           "small for minimum aio_write of %u\n",
272                           (unsigned int)numtowrite,
273                           (unsigned int)min_aio_write_size ));
274                 return NT_STATUS_RETRY;
275         }
276
277         /* Only do this on non-chained and non-chaining writes not using the
278          * write cache. */
279         if (req_is_in_chain(smbreq) || (lp_write_cache_size(SNUM(conn)) != 0)) {
280                 return NT_STATUS_RETRY;
281         }
282
283         if (outstanding_aio_calls >= aio_pending_size) {
284                 DEBUG(3,("schedule_aio_write_and_X: Already have %d aio "
285                          "activities outstanding.\n",
286                           outstanding_aio_calls ));
287                 DEBUG(10,("schedule_aio_write_and_X: failed to schedule "
288                           "aio_write for file %s, offset %.0f, len = %u "
289                           "(mid = %u)\n",
290                           fsp_str_dbg(fsp), (double)startpos,
291                           (unsigned int)numtowrite,
292                           (unsigned int)smbreq->mid ));
293                 return NT_STATUS_RETRY;
294         }
295
296         bufsize = smb_size + 6*2;
297
298         if (!(aio_ex = create_aio_extra(NULL, fsp, bufsize))) {
299                 DEBUG(0,("schedule_aio_write_and_X: malloc fail.\n"));
300                 return NT_STATUS_NO_MEMORY;
301         }
302         aio_ex->handle_completion = handle_aio_write_complete;
303         aio_ex->write_through = BITSETW(smbreq->vwv+7,0);
304
305         construct_reply_common_req(smbreq, (char *)aio_ex->outbuf.data);
306         srv_set_message((char *)aio_ex->outbuf.data, 6, 0, True);
307         SCVAL(aio_ex->outbuf.data,smb_vwv0,0xFF); /* Never a chained reply. */
308
309         init_strict_lock_struct(fsp, (uint64_t)smbreq->smbpid,
310                 (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
311                 &aio_ex->lock);
312
313         /* Take the lock until the AIO completes. */
314         if (!SMB_VFS_STRICT_LOCK(conn, fsp, &aio_ex->lock)) {
315                 TALLOC_FREE(aio_ex);
316                 return NT_STATUS_FILE_LOCK_CONFLICT;
317         }
318
319         a = &aio_ex->acb;
320
321         /* Now set up the aio record for the write call. */
322
323         a->aio_fildes = fsp->fh->fd;
324         a->aio_buf = discard_const_p(char, data);
325         a->aio_nbytes = numtowrite;
326         a->aio_offset = startpos;
327         a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
328         a->aio_sigevent.sigev_signo  = RT_SIGNAL_AIO;
329         a->aio_sigevent.sigev_value.sival_ptr = aio_ex;
330
331         ret = SMB_VFS_AIO_WRITE(fsp, a);
332         if (ret == -1) {
333                 DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. "
334                          "Error %s\n", strerror(errno) ));
335                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &aio_ex->lock);
336                 TALLOC_FREE(aio_ex);
337                 return NT_STATUS_RETRY;
338         }
339
340         aio_ex->smbreq = talloc_move(aio_ex, &smbreq);
341
342         /* This should actually be improved to span the write. */
343         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_WRITE);
344         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_WRITE);
345
346         if (!aio_ex->write_through && !lp_syncalways(SNUM(fsp->conn))
347             && fsp->aio_write_behind) {
348                 /* Lie to the client and immediately claim we finished the
349                  * write. */
350                 SSVAL(aio_ex->outbuf.data,smb_vwv2,numtowrite);
351                 SSVAL(aio_ex->outbuf.data,smb_vwv4,(numtowrite>>16)&1);
352                 show_msg((char *)aio_ex->outbuf.data);
353                 if (!srv_send_smb(aio_ex->smbreq->sconn,
354                                 (char *)aio_ex->outbuf.data,
355                                 true, aio_ex->smbreq->seqnum+1,
356                                 IS_CONN_ENCRYPTED(fsp->conn),
357                                 &aio_ex->smbreq->pcd)) {
358                         exit_server_cleanly("schedule_aio_write_and_X: "
359                                             "srv_send_smb failed.");
360                 }
361                 DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
362                           "behind for file %s\n", fsp_str_dbg(fsp)));
363         }
364
365         DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file "
366                   "%s, offset %.0f, len = %u (mid = %u) "
367                   "outstanding_aio_calls = %d\n",
368                   fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite,
369                   (unsigned int)aio_ex->smbreq->mid, outstanding_aio_calls ));
370
371         return NT_STATUS_OK;
372 }
373
374 bool cancel_smb2_aio(struct smb_request *smbreq)
375 {
376         struct smbd_smb2_request *smb2req = smbreq->smb2req;
377         struct aio_extra *aio_ex = NULL;
378         int ret;
379
380         if (smb2req) {
381                 aio_ex = talloc_get_type(smbreq->async_priv,
382                                          struct aio_extra);
383         }
384
385         if (aio_ex == NULL) {
386                 return false;
387         }
388
389         if (aio_ex->fsp == NULL) {
390                 return false;
391         }
392
393         ret = SMB_VFS_AIO_CANCEL(aio_ex->fsp, &aio_ex->acb);
394         if (ret != AIO_CANCELED) {
395                 return false;
396         }
397
398         return true;
399 }
400
401 /****************************************************************************
402  Set up an aio request from a SMB2 read call.
403 *****************************************************************************/
404
405 NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
406                                 struct smb_request *smbreq,
407                                 files_struct *fsp,
408                                 TALLOC_CTX *ctx,
409                                 DATA_BLOB *preadbuf,
410                                 off_t startpos,
411                                 size_t smb_maxcnt)
412 {
413         struct aio_extra *aio_ex;
414         SMB_STRUCT_AIOCB *a;
415         size_t min_aio_read_size = lp_aio_read_size(SNUM(conn));
416         int ret;
417
418         if (fsp->base_fsp != NULL) {
419                 /* No AIO on streams yet */
420                 DEBUG(10, ("AIO on streams not yet supported\n"));
421                 return NT_STATUS_RETRY;
422         }
423
424         if ((!min_aio_read_size || (smb_maxcnt < min_aio_read_size))
425             && !SMB_VFS_AIO_FORCE(fsp)) {
426                 /* Too small a read for aio request. */
427                 DEBUG(10,("smb2: read size (%u) too small "
428                         "for minimum aio_read of %u\n",
429                         (unsigned int)smb_maxcnt,
430                         (unsigned int)min_aio_read_size ));
431                 return NT_STATUS_RETRY;
432         }
433
434         /* Only do this on reads not using the write cache. */
435         if (lp_write_cache_size(SNUM(conn)) != 0) {
436                 return NT_STATUS_RETRY;
437         }
438
439         if (outstanding_aio_calls >= aio_pending_size) {
440                 DEBUG(10,("smb2: Already have %d aio "
441                         "activities outstanding.\n",
442                         outstanding_aio_calls ));
443                 return NT_STATUS_RETRY;
444         }
445
446         /* Create the out buffer. */
447         *preadbuf = data_blob_talloc(ctx, NULL, smb_maxcnt);
448         if (preadbuf->data == NULL) {
449                 return NT_STATUS_NO_MEMORY;
450         }
451
452         if (!(aio_ex = create_aio_extra(smbreq->smb2req, fsp, 0))) {
453                 return NT_STATUS_NO_MEMORY;
454         }
455         aio_ex->handle_completion = handle_aio_smb2_read_complete;
456
457         init_strict_lock_struct(fsp, (uint64_t)smbreq->smbpid,
458                 (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
459                 &aio_ex->lock);
460
461         /* Take the lock until the AIO completes. */
462         if (!SMB_VFS_STRICT_LOCK(conn, fsp, &aio_ex->lock)) {
463                 TALLOC_FREE(aio_ex);
464                 return NT_STATUS_FILE_LOCK_CONFLICT;
465         }
466
467         a = &aio_ex->acb;
468
469         /* Now set up the aio record for the read call. */
470
471         a->aio_fildes = fsp->fh->fd;
472         a->aio_buf = preadbuf->data;
473         a->aio_nbytes = smb_maxcnt;
474         a->aio_offset = startpos;
475         a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
476         a->aio_sigevent.sigev_signo  = RT_SIGNAL_AIO;
477         a->aio_sigevent.sigev_value.sival_ptr = aio_ex;
478
479         ret = SMB_VFS_AIO_READ(fsp, a);
480         if (ret == -1) {
481                 DEBUG(0,("smb2: aio_read failed. "
482                         "Error %s\n", strerror(errno) ));
483                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &aio_ex->lock);
484                 TALLOC_FREE(aio_ex);
485                 return NT_STATUS_RETRY;
486         }
487
488         /* We don't need talloc_move here as both aio_ex and
489          * smbreq are children of smbreq->smb2req. */
490         aio_ex->smbreq = smbreq;
491         smbreq->async_priv = aio_ex;
492
493         DEBUG(10,("smb2: scheduled aio_read for file %s, "
494                 "offset %.0f, len = %u (mid = %u)\n",
495                 fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt,
496                 (unsigned int)aio_ex->smbreq->mid ));
497
498         return NT_STATUS_OK;
499 }
500
501 /****************************************************************************
502  Set up an aio request from a SMB2write call.
503 *****************************************************************************/
504
505 NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
506                                 struct smb_request *smbreq,
507                                 files_struct *fsp,
508                                 uint64_t in_offset,
509                                 DATA_BLOB in_data,
510                                 bool write_through)
511 {
512         struct aio_extra *aio_ex = NULL;
513         SMB_STRUCT_AIOCB *a = NULL;
514         size_t min_aio_write_size = lp_aio_write_size(SNUM(conn));
515         int ret;
516
517         if (fsp->base_fsp != NULL) {
518                 /* No AIO on streams yet */
519                 DEBUG(10, ("AIO on streams not yet supported\n"));
520                 return NT_STATUS_RETRY;
521         }
522
523         if ((!min_aio_write_size || (in_data.length < min_aio_write_size))
524             && !SMB_VFS_AIO_FORCE(fsp)) {
525                 /* Too small a write for aio request. */
526                 DEBUG(10,("smb2: write size (%u) too "
527                         "small for minimum aio_write of %u\n",
528                         (unsigned int)in_data.length,
529                         (unsigned int)min_aio_write_size ));
530                 return NT_STATUS_RETRY;
531         }
532
533         /* Only do this on writes not using the write cache. */
534         if (lp_write_cache_size(SNUM(conn)) != 0) {
535                 return NT_STATUS_RETRY;
536         }
537
538         if (outstanding_aio_calls >= aio_pending_size) {
539                 DEBUG(3,("smb2: Already have %d aio "
540                         "activities outstanding.\n",
541                         outstanding_aio_calls ));
542                 return NT_STATUS_RETRY;
543         }
544
545         if (!(aio_ex = create_aio_extra(smbreq->smb2req, fsp, 0))) {
546                 return NT_STATUS_NO_MEMORY;
547         }
548
549         aio_ex->handle_completion = handle_aio_smb2_write_complete;
550         aio_ex->write_through = write_through;
551
552         init_strict_lock_struct(fsp, (uint64_t)smbreq->smbpid,
553                 in_offset, (uint64_t)in_data.length, WRITE_LOCK,
554                 &aio_ex->lock);
555
556         /* Take the lock until the AIO completes. */
557         if (!SMB_VFS_STRICT_LOCK(conn, fsp, &aio_ex->lock)) {
558                 TALLOC_FREE(aio_ex);
559                 return NT_STATUS_FILE_LOCK_CONFLICT;
560         }
561
562         a = &aio_ex->acb;
563
564         /* Now set up the aio record for the write call. */
565
566         a->aio_fildes = fsp->fh->fd;
567         a->aio_buf = in_data.data;
568         a->aio_nbytes = in_data.length;
569         a->aio_offset = in_offset;
570         a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
571         a->aio_sigevent.sigev_signo  = RT_SIGNAL_AIO;
572         a->aio_sigevent.sigev_value.sival_ptr = aio_ex;
573
574         ret = SMB_VFS_AIO_WRITE(fsp, a);
575         if (ret == -1) {
576                 DEBUG(3,("smb2: aio_write failed. "
577                         "Error %s\n", strerror(errno) ));
578                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &aio_ex->lock);
579                 TALLOC_FREE(aio_ex);
580                 return NT_STATUS_RETRY;
581         }
582
583         /* We don't need talloc_move here as both aio_ex and
584         * smbreq are children of smbreq->smb2req. */
585         aio_ex->smbreq = smbreq;
586         smbreq->async_priv = aio_ex;
587
588         /* This should actually be improved to span the write. */
589         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_WRITE);
590         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_WRITE);
591
592         /*
593          * We don't want to do write behind due to ownership
594          * issues of the request structs. Maybe add it if I
595          * figure those out. JRA.
596          */
597
598         DEBUG(10,("smb2: scheduled aio_write for file "
599                 "%s, offset %.0f, len = %u (mid = %u) "
600                 "outstanding_aio_calls = %d\n",
601                 fsp_str_dbg(fsp),
602                 (double)in_offset,
603                 (unsigned int)in_data.length,
604                 (unsigned int)aio_ex->smbreq->mid,
605                 outstanding_aio_calls ));
606
607         return NT_STATUS_OK;
608 }
609
610 /****************************************************************************
611  Complete the read and return the data or error back to the client.
612  Returns errno or zero if all ok.
613 *****************************************************************************/
614
615 static int handle_aio_read_complete(struct aio_extra *aio_ex, int errcode)
616 {
617         int outsize;
618         char *outbuf = (char *)aio_ex->outbuf.data;
619         char *data = smb_buf(outbuf);
620         ssize_t nread = SMB_VFS_AIO_RETURN(aio_ex->fsp,&aio_ex->acb);
621
622         if (nread < 0) {
623                 /* We're relying here on the fact that if the fd is
624                    closed then the aio will complete and aio_return
625                    will return an error. Hopefully this is
626                    true.... JRA. */
627
628                 DEBUG( 3,( "handle_aio_read_complete: file %s nread == %d. "
629                            "Error = %s\n",
630                            fsp_str_dbg(aio_ex->fsp), (int)nread, strerror(errcode)));
631
632                 ERROR_NT(map_nt_error_from_unix(errcode));
633                 outsize = srv_set_message(outbuf,0,0,true);
634         } else {
635                 outsize = srv_set_message(outbuf,12,nread,False);
636                 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be * -1. */
637                 SSVAL(outbuf,smb_vwv5,nread);
638                 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
639                 SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
640                 SSVAL(smb_buf(outbuf),-2,nread);
641
642                 aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nread;
643                 aio_ex->fsp->fh->position_information = aio_ex->fsp->fh->pos;
644
645                 DEBUG( 3, ( "handle_aio_read_complete file %s max=%d "
646                             "nread=%d\n",
647                             fsp_str_dbg(aio_ex->fsp),
648                             (int)aio_ex->acb.aio_nbytes, (int)nread ) );
649
650         }
651         smb_setlen(outbuf,outsize - 4);
652         show_msg(outbuf);
653         if (!srv_send_smb(aio_ex->smbreq->sconn, outbuf,
654                         true, aio_ex->smbreq->seqnum+1,
655                         IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) {
656                 exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
657                                     "failed.");
658         }
659
660         DEBUG(10,("handle_aio_read_complete: scheduled aio_read completed "
661                   "for file %s, offset %.0f, len = %u\n",
662                   fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset,
663                   (unsigned int)nread ));
664
665         return errcode;
666 }
667
668 /****************************************************************************
669  Complete the write and return the data or error back to the client.
670  Returns error code or zero if all ok.
671 *****************************************************************************/
672
673 static int handle_aio_write_complete(struct aio_extra *aio_ex, int errcode)
674 {
675         files_struct *fsp = aio_ex->fsp;
676         char *outbuf = (char *)aio_ex->outbuf.data;
677         ssize_t numtowrite = aio_ex->acb.aio_nbytes;
678         ssize_t nwritten = SMB_VFS_AIO_RETURN(fsp,&aio_ex->acb);
679
680         if (fsp->aio_write_behind) {
681                 if (nwritten != numtowrite) {
682                         if (nwritten == -1) {
683                                 DEBUG(5,("handle_aio_write_complete: "
684                                          "aio_write_behind failed ! File %s "
685                                          "is corrupt ! Error %s\n",
686                                          fsp_str_dbg(fsp), strerror(errcode)));
687                         } else {
688                                 DEBUG(0,("handle_aio_write_complete: "
689                                          "aio_write_behind failed ! File %s "
690                                          "is corrupt ! Wanted %u bytes but "
691                                          "only wrote %d\n", fsp_str_dbg(fsp),
692                                          (unsigned int)numtowrite,
693                                          (int)nwritten ));
694                                 errcode = EIO;
695                         }
696                 } else {
697                         DEBUG(10,("handle_aio_write_complete: "
698                                   "aio_write_behind completed for file %s\n",
699                                   fsp_str_dbg(fsp)));
700                 }
701                 /* TODO: should no return 0 in case of an error !!! */
702                 return 0;
703         }
704
705         /* We don't need outsize or set_message here as we've already set the
706            fixed size length when we set up the aio call. */
707
708         if(nwritten == -1) {
709                 DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. "
710                            "nwritten == %d. Error = %s\n",
711                            fsp_str_dbg(fsp), (unsigned int)numtowrite,
712                            (int)nwritten, strerror(errcode) ));
713
714                 ERROR_NT(map_nt_error_from_unix(errcode));
715                 srv_set_message(outbuf,0,0,true);
716         } else {
717                 NTSTATUS status;
718
719                 SSVAL(outbuf,smb_vwv2,nwritten);
720                 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
721                 if (nwritten < (ssize_t)numtowrite) {
722                         SCVAL(outbuf,smb_rcls,ERRHRD);
723                         SSVAL(outbuf,smb_err,ERRdiskfull);
724                 }
725
726                 DEBUG(3,("handle_aio_write: fnum=%d num=%d wrote=%d\n",
727                          fsp->fnum, (int)numtowrite, (int)nwritten));
728                 status = sync_file(fsp->conn,fsp, aio_ex->write_through);
729                 if (!NT_STATUS_IS_OK(status)) {
730                         errcode = errno;
731                         ERROR_BOTH(map_nt_error_from_unix(errcode),
732                                    ERRHRD, ERRdiskfull);
733                         srv_set_message(outbuf,0,0,true);
734                         DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
735                                  fsp_str_dbg(fsp), nt_errstr(status)));
736                 }
737
738                 aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten;
739         }
740
741         show_msg(outbuf);
742         if (!srv_send_smb(aio_ex->smbreq->sconn, outbuf,
743                           true, aio_ex->smbreq->seqnum+1,
744                           IS_CONN_ENCRYPTED(fsp->conn),
745                           NULL)) {
746                 exit_server_cleanly("handle_aio_write_complete: "
747                                     "srv_send_smb failed.");
748         }
749
750         DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
751                   "for file %s, offset %.0f, requested %u, written = %u\n",
752                   fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset,
753                   (unsigned int)numtowrite, (unsigned int)nwritten ));
754
755         return errcode;
756 }
757
758 /****************************************************************************
759  Complete the read and return the data or error back to the client.
760  Returns errno or zero if all ok.
761 *****************************************************************************/
762
763 static int handle_aio_smb2_read_complete(struct aio_extra *aio_ex, int errcode)
764 {
765         NTSTATUS status;
766         struct tevent_req *subreq = aio_ex->smbreq->smb2req->subreq;
767         ssize_t nread = SMB_VFS_AIO_RETURN(aio_ex->fsp,&aio_ex->acb);
768
769         /* Common error or success code processing for async or sync
770            read returns. */
771
772         status = smb2_read_complete(subreq, nread, errcode);
773
774         if (nread > 0) {
775                 aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nread;
776                 aio_ex->fsp->fh->position_information = aio_ex->fsp->fh->pos;
777         }
778
779         DEBUG(10,("smb2: scheduled aio_read completed "
780                 "for file %s, offset %.0f, len = %u "
781                 "(errcode = %d, NTSTATUS = %s)\n",
782                 fsp_str_dbg(aio_ex->fsp),
783                 (double)aio_ex->acb.aio_offset,
784                 (unsigned int)nread,
785                 errcode,
786                 nt_errstr(status) ));
787
788         if (!NT_STATUS_IS_OK(status)) {
789                 tevent_req_nterror(subreq, status);
790                 return errcode;
791         }
792
793         tevent_req_done(subreq);
794         return errcode;
795 }
796
797 /****************************************************************************
798  Complete the SMB2 write and return the data or error back to the client.
799  Returns error code or zero if all ok.
800 *****************************************************************************/
801
802 static int handle_aio_smb2_write_complete(struct aio_extra *aio_ex, int errcode)
803 {
804         files_struct *fsp = aio_ex->fsp;
805         ssize_t numtowrite = aio_ex->acb.aio_nbytes;
806         ssize_t nwritten = SMB_VFS_AIO_RETURN(fsp,&aio_ex->acb);
807         struct tevent_req *subreq = aio_ex->smbreq->smb2req->subreq;
808         NTSTATUS status;
809
810         status = smb2_write_complete(subreq, nwritten, errcode);
811
812         DEBUG(10,("smb2: scheduled aio_write completed "
813                 "for file %s, offset %.0f, requested %u, "
814                 "written = %u (errcode = %d, NTSTATUS = %s)\n",
815                 fsp_str_dbg(fsp),
816                 (double)aio_ex->acb.aio_offset,
817                 (unsigned int)numtowrite,
818                 (unsigned int)nwritten,
819                 errcode,
820                 nt_errstr(status) ));
821
822         if (!NT_STATUS_IS_OK(status)) {
823                 tevent_req_nterror(subreq, status);
824                 return errcode;
825         }
826
827         tevent_req_done(subreq);
828         return errcode;
829 }
830
831 /****************************************************************************
832  Handle any aio completion. Returns True if finished (and sets *perr if err
833  was non-zero), False if not.
834 *****************************************************************************/
835
836 static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
837 {
838         files_struct *fsp = NULL;
839         int err;
840
841         if(!aio_ex) {
842                 DEBUG(3, ("handle_aio_completed: Non-existing aio_ex passed\n"));
843                 return false;
844         }
845
846         if (!aio_ex->fsp) {
847                 DEBUG(3, ("handle_aio_completed: aio_ex->fsp == NULL\n"));
848                 return false;
849         }
850
851         fsp = aio_ex->fsp;
852
853         /* Ensure the operation has really completed. */
854         err = SMB_VFS_AIO_ERROR(fsp, &aio_ex->acb);
855         if (err == EINPROGRESS) {
856                 DEBUG(10,( "handle_aio_completed: operation mid %llu still in "
857                         "process for file %s\n",
858                         (unsigned long long)aio_ex->smbreq->mid,
859                         fsp_str_dbg(aio_ex->fsp)));
860                 return False;
861         }
862
863         if (err == ECANCELED) {
864                 DEBUG(10,( "handle_aio_completed: operation mid %llu canceled "
865                         "for file %s\n",
866                         (unsigned long long)aio_ex->smbreq->mid,
867                         fsp_str_dbg(aio_ex->fsp)));
868         }
869
870         /* Unlock now we're done. */
871         SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &aio_ex->lock);
872
873         err = aio_ex->handle_completion(aio_ex, err);
874         if (err) {
875                 *perr = err; /* Only save non-zero errors. */
876         }
877
878         return True;
879 }
880
881 /****************************************************************************
882  Handle any aio completion inline.
883 *****************************************************************************/
884
885 void smbd_aio_complete_aio_ex(struct aio_extra *aio_ex)
886 {
887         files_struct *fsp = NULL;
888         int ret = 0;
889
890         DEBUG(10,("smbd_aio_complete_mid: mid[%llu]\n",
891                 (unsigned long long)aio_ex->smbreq->mid));
892
893         fsp = aio_ex->fsp;
894         if (fsp == NULL) {
895                 /* file was closed whilst I/O was outstanding. Just
896                  * ignore. */
897                 DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst "
898                         "aio outstanding (mid[%llu]).\n",
899                         (unsigned long long)aio_ex->smbreq->mid));
900                 return;
901         }
902
903         if (!handle_aio_completed(aio_ex, &ret)) {
904                 return;
905         }
906 }
907
908 /****************************************************************************
909  We're doing write behind and the client closed the file. Wait up to 45
910  seconds (my arbitrary choice) for the aio to complete. Return 0 if all writes
911  completed, errno to return if not.
912 *****************************************************************************/
913
914 #define SMB_TIME_FOR_AIO_COMPLETE_WAIT 45
915
916 int wait_for_aio_completion(files_struct *fsp)
917 {
918         struct aio_extra *aio_ex;
919         const SMB_STRUCT_AIOCB **aiocb_list;
920         int aio_completion_count = 0;
921         time_t start_time = time_mono(NULL);
922         int seconds_left;
923
924         for (seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT;
925              seconds_left >= 0;) {
926                 int err = 0;
927                 int i;
928                 struct timespec ts;
929
930                 aio_completion_count = 0;
931                 for( aio_ex = aio_list_head; aio_ex; aio_ex = aio_ex->next) {
932                         if (aio_ex->fsp == fsp) {
933                                 aio_completion_count++;
934                         }
935                 }
936
937                 if (!aio_completion_count) {
938                         return 0;
939                 }
940
941                 DEBUG(3,("wait_for_aio_completion: waiting for %d aio events "
942                          "to complete.\n", aio_completion_count ));
943
944                 aiocb_list = SMB_MALLOC_ARRAY(const SMB_STRUCT_AIOCB *,
945                                               aio_completion_count);
946                 if (!aiocb_list) {
947                         return ENOMEM;
948                 }
949
950                 for( i = 0, aio_ex = aio_list_head;
951                      aio_ex;
952                      aio_ex = aio_ex->next) {
953                         if (aio_ex->fsp == fsp) {
954                                 aiocb_list[i++] = &aio_ex->acb;
955                         }
956                 }
957
958                 /* Now wait up to seconds_left for completion. */
959                 ts.tv_sec = seconds_left;
960                 ts.tv_nsec = 0;
961
962                 DEBUG(10,("wait_for_aio_completion: %d events, doing a wait "
963                           "of %d seconds.\n",
964                           aio_completion_count, seconds_left ));
965
966                 err = SMB_VFS_AIO_SUSPEND(fsp, aiocb_list,
967                                           aio_completion_count, &ts);
968
969                 DEBUG(10,("wait_for_aio_completion: returned err = %d, "
970                           "errno = %s\n", err, strerror(errno) ));
971
972                 if (err == -1 && errno == EAGAIN) {
973                         DEBUG(0,("wait_for_aio_completion: aio_suspend timed "
974                                  "out waiting for %d events after a wait of "
975                                  "%d seconds\n", aio_completion_count,
976                                  seconds_left));
977                         /* Timeout. */
978                         SAFE_FREE(aiocb_list);
979                         /* We're hosed here - IO may complete
980                            and trample over memory if we free
981                            the aio_ex struct, but if we don't
982                            we leak IO requests. I think smb_panic()
983                            if the right thing to do here. JRA.
984                         */
985                         smb_panic("AIO suspend timed out - cannot continue.");
986                         return EIO;
987                 }
988
989                 /* One or more events might have completed - process them if
990                  * so. */
991                 for( i = 0; i < aio_completion_count; i++) {
992                         aio_ex = (struct aio_extra *)aiocb_list[i]->aio_sigevent.sigev_value.sival_ptr;
993
994                         if (!handle_aio_completed(aio_ex, &err)) {
995                                 continue;
996                         }
997                         TALLOC_FREE(aio_ex);
998                 }
999
1000                 SAFE_FREE(aiocb_list);
1001                 seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT
1002                         - (time_mono(NULL) - start_time);
1003         }
1004
1005         /* We timed out - we don't know why. Return ret if already an error,
1006          * else EIO. */
1007         DEBUG(10,("wait_for_aio_completion: aio_suspend timed out waiting "
1008                   "for %d events\n",
1009                   aio_completion_count));
1010
1011         return EIO;
1012 }
1013
1014 #else
1015
1016 bool initialize_async_io_handler(void)
1017 {
1018         return false;
1019 }
1020
1021 NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
1022                              struct smb_request *smbreq,
1023                              files_struct *fsp, off_t startpos,
1024                              size_t smb_maxcnt)
1025 {
1026         return NT_STATUS_RETRY;
1027 }
1028
1029 NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
1030                               struct smb_request *smbreq,
1031                               files_struct *fsp, const char *data,
1032                               off_t startpos,
1033                               size_t numtowrite)
1034 {
1035         return NT_STATUS_RETRY;
1036 }
1037
1038 bool cancel_smb2_aio(struct smb_request *smbreq)
1039 {
1040         return false;
1041 }
1042
1043 NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
1044                                 struct smb_request *smbreq,
1045                                 files_struct *fsp,
1046                                 TALLOC_CTX *ctx,
1047                                 DATA_BLOB *preadbuf,
1048                                 off_t startpos,
1049                                 size_t smb_maxcnt)
1050 {
1051         return NT_STATUS_RETRY;
1052 }
1053
1054 NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
1055                                 struct smb_request *smbreq,
1056                                 files_struct *fsp,
1057                                 uint64_t in_offset,
1058                                 DATA_BLOB in_data,
1059                                 bool write_through)
1060 {
1061         return NT_STATUS_RETRY;
1062 }
1063
1064 int wait_for_aio_completion(files_struct *fsp)
1065 {
1066         return 0;
1067 }
1068
1069 void smbd_aio_complete_mid(uint64_t mid);
1070
1071 #endif