2005-06-28 02:53:56 +04:00
/*
Unix SMB / Netbios implementation .
Version 3.0
async_io read handling using POSIX async io .
Copyright ( C ) Jeremy Allison 2005.
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-06-28 02:53:56 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-06-28 02:53:56 +04:00
*/
# include "includes.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2009-01-08 14:03:45 +03:00
# include "smbd/globals.h"
2011-04-28 19:38:09 +04:00
# include "../lib/util/tevent_ntstatus.h"
2005-06-28 02:53:56 +04:00
2012-06-06 03:23:22 +04:00
# if defined(HAVE_AIO)
2005-06-28 02:53:56 +04:00
2010-06-02 03:05:44 +04:00
/****************************************************************************
The buffer we keep around whilst an aio request is in process .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct aio_extra {
files_struct * fsp ;
2010-06-04 22:41:38 +04:00
struct smb_request * smbreq ;
2010-06-02 21:25:56 +04:00
DATA_BLOB outbuf ;
2010-06-02 03:05:44 +04:00
struct lock_struct lock ;
2012-07-06 17:05:02 +04:00
size_t nbyte ;
off_t offset ;
2010-06-08 03:25:18 +04:00
bool write_through ;
2010-06-02 03:05:44 +04:00
} ;
2012-07-12 21:57:47 +04:00
/****************************************************************************
Accessor function to return write_through state .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool aio_write_through_requested ( struct aio_extra * aio_ex )
{
return aio_ex - > write_through ;
}
2012-04-08 22:11:53 +04:00
bool initialize_async_io_handler ( void )
2010-04-02 03:47:59 +04:00
{
2010-07-20 20:34:32 +04:00
return true ;
2010-04-02 03:47:59 +04:00
}
2008-11-03 23:56:02 +03:00
static int aio_extra_destructor ( struct aio_extra * aio_ex )
{
2012-04-13 00:48:29 +04:00
outstanding_aio_calls - - ;
2008-11-03 23:56:02 +03:00
return 0 ;
}
2005-06-28 02:53:56 +04:00
/****************************************************************************
Create the extended aio struct we must keep around for the lifetime
2008-11-03 23:56:02 +03:00
of the aio call .
2005-06-28 02:53:56 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-06-08 03:26:30 +04:00
static struct aio_extra * create_aio_extra ( TALLOC_CTX * mem_ctx ,
files_struct * fsp ,
size_t buflen )
2005-06-28 02:53:56 +04:00
{
2011-06-07 05:44:43 +04:00
struct aio_extra * aio_ex = talloc_zero ( mem_ctx , struct aio_extra ) ;
2005-06-28 02:53:56 +04:00
if ( ! aio_ex ) {
return NULL ;
}
2008-11-03 21:59:11 +03:00
2005-06-28 02:53:56 +04:00
/* The output buffer stored in the aio_ex is the start of
the smb return buffer . The buffer used in the acb
is the start of the reply data portion of that buffer . */
2010-06-08 03:26:30 +04:00
if ( buflen ) {
aio_ex - > outbuf = data_blob_talloc ( aio_ex , NULL , buflen ) ;
if ( ! aio_ex - > outbuf . data ) {
TALLOC_FREE ( aio_ex ) ;
return NULL ;
}
2005-06-28 02:53:56 +04:00
}
2008-11-03 23:56:02 +03:00
talloc_set_destructor ( aio_ex , aio_extra_destructor ) ;
2005-06-28 02:53:56 +04:00
aio_ex - > fsp = fsp ;
2012-04-13 00:48:29 +04:00
outstanding_aio_calls + + ;
2005-06-28 02:53:56 +04:00
return aio_ex ;
}
2012-07-06 11:37:57 +04:00
struct aio_req_fsp_link {
files_struct * fsp ;
struct tevent_req * req ;
} ;
static int aio_del_req_from_fsp ( struct aio_req_fsp_link * lnk )
{
unsigned i ;
files_struct * fsp = lnk - > fsp ;
struct tevent_req * req = lnk - > req ;
for ( i = 0 ; i < fsp - > num_aio_requests ; i + + ) {
if ( fsp - > aio_requests [ i ] = = req ) {
break ;
}
}
if ( i = = fsp - > num_aio_requests ) {
DEBUG ( 1 , ( " req %p not found in fsp %p \n " , req , fsp ) ) ;
return 0 ;
}
fsp - > num_aio_requests - = 1 ;
fsp - > aio_requests [ i ] = fsp - > aio_requests [ fsp - > num_aio_requests ] ;
return 0 ;
}
static bool aio_add_req_to_fsp ( files_struct * fsp , struct tevent_req * req )
{
size_t array_len ;
struct aio_req_fsp_link * lnk ;
lnk = talloc ( req , struct aio_req_fsp_link ) ;
if ( lnk = = NULL ) {
return false ;
}
array_len = talloc_array_length ( fsp - > aio_requests ) ;
if ( array_len < = fsp - > num_aio_requests ) {
struct tevent_req * * tmp ;
tmp = talloc_realloc (
fsp , fsp - > aio_requests , struct tevent_req * ,
fsp - > num_aio_requests + 1 ) ;
if ( tmp = = NULL ) {
TALLOC_FREE ( lnk ) ;
return false ;
}
fsp - > aio_requests = tmp ;
}
fsp - > aio_requests [ fsp - > num_aio_requests ] = req ;
fsp - > num_aio_requests + = 1 ;
lnk - > fsp = fsp ;
lnk - > req = req ;
talloc_set_destructor ( lnk , aio_del_req_from_fsp ) ;
return true ;
}
2012-07-02 14:46:03 +04:00
static void aio_pread_smb1_done ( struct tevent_req * req ) ;
2005-06-28 02:53:56 +04:00
/****************************************************************************
Set up an aio request from a SMBreadX call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-04-06 01:16:21 +04:00
NTSTATUS schedule_aio_read_and_X ( connection_struct * conn ,
2010-06-04 22:41:38 +04:00
struct smb_request * smbreq ,
2012-04-05 08:53:08 +04:00
files_struct * fsp , off_t startpos ,
2005-06-28 02:53:56 +04:00
size_t smb_maxcnt )
{
struct aio_extra * aio_ex ;
size_t bufsize ;
size_t min_aio_read_size = lp_aio_read_size ( SNUM ( conn ) ) ;
2012-07-02 14:46:03 +04:00
struct tevent_req * req ;
2005-06-28 02:53:56 +04:00
2008-02-24 02:01:07 +03:00
if ( fsp - > base_fsp ! = NULL ) {
/* No AIO on streams yet */
DEBUG ( 10 , ( " AIO on streams not yet supported \n " ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2008-02-24 02:01:07 +03:00
}
2008-01-30 13:11:27 +03:00
if ( ( ! min_aio_read_size | | ( smb_maxcnt < min_aio_read_size ) )
& & ! SMB_VFS_AIO_FORCE ( fsp ) ) {
2005-06-28 02:53:56 +04:00
/* Too small a read for aio request. */
DEBUG ( 10 , ( " schedule_aio_read_and_X: read size (%u) too small "
" for minimum aio_read of %u \n " ,
( unsigned int ) smb_maxcnt ,
( unsigned int ) min_aio_read_size ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2007-02-10 16:15:58 +03:00
/* Only do this on non-chained and non-chaining reads not using the
* write cache . */
2010-06-04 22:41:38 +04:00
if ( req_is_in_chain ( smbreq ) | | ( lp_write_cache_size ( SNUM ( conn ) ) ! = 0 ) ) {
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2008-02-24 13:32:22 +03:00
if ( outstanding_aio_calls > = aio_pending_size ) {
2007-02-10 16:15:58 +03:00
DEBUG ( 10 , ( " schedule_aio_read_and_X: Already have %d aio "
" activities outstanding. \n " ,
2005-06-28 02:53:56 +04:00
outstanding_aio_calls ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2007-08-11 20:28:10 +04:00
/* The following is safe from integer wrap as we've already checked
smb_maxcnt is 128 k or less . Wct is 12 for read replies */
bufsize = smb_size + 12 * 2 + smb_maxcnt ;
2005-06-28 02:53:56 +04:00
2010-06-08 03:26:30 +04:00
if ( ( aio_ex = create_aio_extra ( NULL , fsp , bufsize ) ) = = NULL ) {
2005-06-28 02:53:56 +04:00
DEBUG ( 10 , ( " schedule_aio_read_and_X: malloc fail. \n " ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_NO_MEMORY ;
2005-06-28 02:53:56 +04:00
}
2010-06-04 22:41:38 +04:00
construct_reply_common_req ( smbreq , ( char * ) aio_ex - > outbuf . data ) ;
2010-06-02 21:25:56 +04:00
srv_set_message ( ( char * ) aio_ex - > outbuf . data , 12 , 0 , True ) ;
SCVAL ( aio_ex - > outbuf . data , smb_vwv0 , 0xFF ) ; /* Never a chained reply. */
2005-06-28 02:53:56 +04:00
2010-06-04 22:41:38 +04:00
init_strict_lock_struct ( fsp , ( uint64_t ) smbreq - > smbpid ,
2010-04-06 01:16:21 +04:00
( uint64_t ) startpos , ( uint64_t ) smb_maxcnt , READ_LOCK ,
& aio_ex - > lock ) ;
/* Take the lock until the AIO completes. */
if ( ! SMB_VFS_STRICT_LOCK ( conn , fsp , & aio_ex - > lock ) ) {
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_FILE_LOCK_CONFLICT ;
}
2012-07-06 17:05:02 +04:00
aio_ex - > nbyte = smb_maxcnt ;
aio_ex - > offset = startpos ;
2005-06-28 02:53:56 +04:00
2012-07-02 14:46:03 +04:00
req = SMB_VFS_PREAD_SEND ( aio_ex , fsp - > conn - > sconn - > ev_ctx ,
fsp , smb_buf ( aio_ex - > outbuf . data ) ,
smb_maxcnt , startpos ) ;
if ( req = = NULL ) {
2007-02-10 16:15:58 +03:00
DEBUG ( 0 , ( " schedule_aio_read_and_X: aio_read failed. "
" Error %s \n " , strerror ( errno ) ) ) ;
2010-04-06 01:16:21 +04:00
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
2008-11-03 21:59:11 +03:00
TALLOC_FREE ( aio_ex ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2012-07-02 14:46:03 +04:00
tevent_req_set_callback ( req , aio_pread_smb1_done , aio_ex ) ;
2005-06-28 02:53:56 +04:00
2012-07-06 11:37:57 +04:00
if ( ! aio_add_req_to_fsp ( fsp , req ) ) {
DEBUG ( 1 , ( " Could not add req to fsp \n " ) ) ;
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_RETRY ;
}
2010-06-04 22:41:38 +04:00
aio_ex - > smbreq = talloc_move ( aio_ex , & smbreq ) ;
2008-11-03 23:56:02 +03:00
2007-02-10 16:15:58 +03:00
DEBUG ( 10 , ( " schedule_aio_read_and_X: scheduled aio_read for file %s, "
" offset %.0f, len = %u (mid = %u) \n " ,
2009-07-11 01:50:37 +04:00
fsp_str_dbg ( fsp ) , ( double ) startpos , ( unsigned int ) smb_maxcnt ,
2010-06-04 22:41:38 +04:00
( unsigned int ) aio_ex - > smbreq - > mid ) ) ;
2005-06-28 02:53:56 +04:00
2010-04-06 01:16:21 +04:00
return NT_STATUS_OK ;
2005-06-28 02:53:56 +04:00
}
2012-07-02 14:46:03 +04:00
static void aio_pread_smb1_done ( struct tevent_req * req )
{
struct aio_extra * aio_ex = tevent_req_callback_data (
req , struct aio_extra ) ;
files_struct * fsp = aio_ex - > fsp ;
int outsize ;
char * outbuf = ( char * ) aio_ex - > outbuf . data ;
char * data = smb_buf ( outbuf ) ;
ssize_t nread ;
int err ;
nread = SMB_VFS_PREAD_RECV ( req , & err ) ;
TALLOC_FREE ( req ) ;
DEBUG ( 10 , ( " pread_recv returned %d, err = %s \n " , ( int ) nread ,
( nread = = - 1 ) ? strerror ( err ) : " no error " ) ) ;
if ( fsp = = NULL ) {
DEBUG ( 3 , ( " aio_pread_smb1_done: file closed whilst "
" aio outstanding (mid[%llu]). \n " ,
( unsigned long long ) aio_ex - > smbreq - > mid ) ) ;
TALLOC_FREE ( aio_ex ) ;
return ;
}
/* Unlock now we're done. */
SMB_VFS_STRICT_UNLOCK ( fsp - > conn , fsp , & aio_ex - > lock ) ;
if ( nread < 0 ) {
DEBUG ( 3 , ( " handle_aio_read_complete: file %s nread == %d. "
" Error = %s \n " , fsp_str_dbg ( fsp ) , ( int ) nread ,
strerror ( err ) ) ) ;
ERROR_NT ( map_nt_error_from_unix ( err ) ) ;
outsize = srv_set_message ( outbuf , 0 , 0 , true ) ;
} else {
outsize = srv_set_message ( outbuf , 12 , nread , False ) ;
SSVAL ( outbuf , smb_vwv2 , 0xFFFF ) ; /* Remaining - must be * -1. */
SSVAL ( outbuf , smb_vwv5 , nread ) ;
SSVAL ( outbuf , smb_vwv6 , smb_offset ( data , outbuf ) ) ;
SSVAL ( outbuf , smb_vwv7 , ( ( nread > > 16 ) & 1 ) ) ;
SSVAL ( smb_buf ( outbuf ) , - 2 , nread ) ;
2012-07-06 17:05:02 +04:00
aio_ex - > fsp - > fh - > pos = aio_ex - > offset + nread ;
2012-07-02 14:46:03 +04:00
aio_ex - > fsp - > fh - > position_information = aio_ex - > fsp - > fh - > pos ;
DEBUG ( 3 , ( " handle_aio_read_complete file %s max=%d "
" nread=%d \n " , fsp_str_dbg ( fsp ) ,
2012-07-06 17:05:02 +04:00
( int ) aio_ex - > nbyte , ( int ) nread ) ) ;
2012-07-02 14:46:03 +04:00
}
smb_setlen ( outbuf , outsize - 4 ) ;
show_msg ( outbuf ) ;
if ( ! srv_send_smb ( aio_ex - > smbreq - > sconn , outbuf ,
true , aio_ex - > smbreq - > seqnum + 1 ,
IS_CONN_ENCRYPTED ( fsp - > conn ) , NULL ) ) {
exit_server_cleanly ( " handle_aio_read_complete: srv_send_smb "
" failed. " ) ;
}
DEBUG ( 10 , ( " handle_aio_read_complete: scheduled aio_read completed "
" for file %s, offset %.0f, len = %u \n " ,
2012-07-06 17:05:02 +04:00
fsp_str_dbg ( fsp ) , ( double ) aio_ex - > offset ,
2012-07-02 14:46:03 +04:00
( unsigned int ) nread ) ) ;
TALLOC_FREE ( aio_ex ) ;
}
2012-07-02 14:46:03 +04:00
static void aio_pwrite_smb1_done ( struct tevent_req * req ) ;
2005-06-28 02:53:56 +04:00
/****************************************************************************
Set up an aio request from a SMBwriteX call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-04-06 01:16:21 +04:00
NTSTATUS schedule_aio_write_and_X ( connection_struct * conn ,
2010-06-04 22:41:38 +04:00
struct smb_request * smbreq ,
2011-05-05 21:41:59 +04:00
files_struct * fsp , const char * data ,
2012-04-05 08:53:08 +04:00
off_t startpos ,
2007-08-08 23:05:30 +04:00
size_t numtowrite )
2005-06-28 02:53:56 +04:00
{
struct aio_extra * aio_ex ;
2008-11-03 23:56:02 +03:00
size_t bufsize ;
2005-06-28 02:53:56 +04:00
size_t min_aio_write_size = lp_aio_write_size ( SNUM ( conn ) ) ;
2012-07-02 14:46:03 +04:00
struct tevent_req * req ;
2005-06-28 02:53:56 +04:00
2008-02-24 02:01:07 +03:00
if ( fsp - > base_fsp ! = NULL ) {
/* No AIO on streams yet */
DEBUG ( 10 , ( " AIO on streams not yet supported \n " ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2008-02-24 02:01:07 +03:00
}
2008-01-30 13:11:27 +03:00
if ( ( ! min_aio_write_size | | ( numtowrite < min_aio_write_size ) )
& & ! SMB_VFS_AIO_FORCE ( fsp ) ) {
2005-06-28 02:53:56 +04:00
/* Too small a write for aio request. */
2007-02-10 16:15:58 +03:00
DEBUG ( 10 , ( " schedule_aio_write_and_X: write size (%u) too "
" small for minimum aio_write of %u \n " ,
2005-06-28 02:53:56 +04:00
( unsigned int ) numtowrite ,
( unsigned int ) min_aio_write_size ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2010-06-08 03:25:18 +04:00
/* Only do this on non-chained and non-chaining writes not using the
2007-02-10 16:15:58 +03:00
* write cache . */
2010-06-04 22:41:38 +04:00
if ( req_is_in_chain ( smbreq ) | | ( lp_write_cache_size ( SNUM ( conn ) ) ! = 0 ) ) {
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2008-02-24 13:32:22 +03:00
if ( outstanding_aio_calls > = aio_pending_size ) {
2007-02-10 16:15:58 +03:00
DEBUG ( 3 , ( " schedule_aio_write_and_X: Already have %d aio "
" activities outstanding. \n " ,
2005-06-28 02:53:56 +04:00
outstanding_aio_calls ) ) ;
2007-02-10 16:15:58 +03:00
DEBUG ( 10 , ( " schedule_aio_write_and_X: failed to schedule "
" aio_write for file %s, offset %.0f, len = %u "
" (mid = %u) \n " ,
2009-07-11 01:50:37 +04:00
fsp_str_dbg ( fsp ) , ( double ) startpos ,
2007-02-10 16:15:58 +03:00
( unsigned int ) numtowrite ,
2010-06-04 22:41:38 +04:00
( unsigned int ) smbreq - > mid ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2008-11-03 23:56:02 +03:00
bufsize = smb_size + 6 * 2 ;
2010-06-08 03:26:30 +04:00
if ( ! ( aio_ex = create_aio_extra ( NULL , fsp , bufsize ) ) ) {
2005-06-28 02:53:56 +04:00
DEBUG ( 0 , ( " schedule_aio_write_and_X: malloc fail. \n " ) ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_NO_MEMORY ;
2005-06-28 02:53:56 +04:00
}
2010-06-08 03:25:18 +04:00
aio_ex - > write_through = BITSETW ( smbreq - > vwv + 7 , 0 ) ;
2005-06-28 02:53:56 +04:00
2010-06-04 22:41:38 +04:00
construct_reply_common_req ( smbreq , ( char * ) aio_ex - > outbuf . data ) ;
2010-06-02 21:25:56 +04:00
srv_set_message ( ( char * ) aio_ex - > outbuf . data , 6 , 0 , True ) ;
SCVAL ( aio_ex - > outbuf . data , smb_vwv0 , 0xFF ) ; /* Never a chained reply. */
2005-06-28 02:53:56 +04:00
2010-06-04 22:41:38 +04:00
init_strict_lock_struct ( fsp , ( uint64_t ) smbreq - > smbpid ,
2010-04-06 01:16:21 +04:00
( uint64_t ) startpos , ( uint64_t ) numtowrite , WRITE_LOCK ,
& aio_ex - > lock ) ;
/* Take the lock until the AIO completes. */
if ( ! SMB_VFS_STRICT_LOCK ( conn , fsp , & aio_ex - > lock ) ) {
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_FILE_LOCK_CONFLICT ;
}
2012-07-06 17:05:02 +04:00
aio_ex - > nbyte = numtowrite ;
aio_ex - > offset = startpos ;
2005-06-28 02:53:56 +04:00
2012-07-02 14:46:03 +04:00
req = SMB_VFS_PWRITE_SEND ( aio_ex , fsp - > conn - > sconn - > ev_ctx , fsp ,
data , numtowrite , startpos ) ;
if ( req = = NULL ) {
2007-02-10 16:15:58 +03:00
DEBUG ( 3 , ( " schedule_aio_wrote_and_X: aio_write failed. "
" Error %s \n " , strerror ( errno ) ) ) ;
2010-04-06 01:16:21 +04:00
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
2008-11-03 21:59:11 +03:00
TALLOC_FREE ( aio_ex ) ;
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2012-07-02 14:46:03 +04:00
tevent_req_set_callback ( req , aio_pwrite_smb1_done , aio_ex ) ;
2008-11-02 23:52:16 +03:00
2012-07-06 11:37:57 +04:00
if ( ! aio_add_req_to_fsp ( fsp , req ) ) {
DEBUG ( 1 , ( " Could not add req to fsp \n " ) ) ;
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_RETRY ;
}
2010-06-04 22:41:38 +04:00
aio_ex - > smbreq = talloc_move ( aio_ex , & smbreq ) ;
2008-11-03 23:56:02 +03:00
2009-02-03 22:56:35 +03:00
/* This should actually be improved to span the write. */
contend_level2_oplocks_begin ( fsp , LEVEL2_CONTEND_WRITE ) ;
contend_level2_oplocks_end ( fsp , LEVEL2_CONTEND_WRITE ) ;
2008-02-19 17:53:57 +03:00
2010-06-08 03:25:18 +04:00
if ( ! aio_ex - > write_through & & ! lp_syncalways ( SNUM ( fsp - > conn ) )
2007-10-11 00:34:30 +04:00
& & fsp - > aio_write_behind ) {
/* Lie to the client and immediately claim we finished the
* write . */
2010-06-02 21:25:56 +04:00
SSVAL ( aio_ex - > outbuf . data , smb_vwv2 , numtowrite ) ;
SSVAL ( aio_ex - > outbuf . data , smb_vwv4 , ( numtowrite > > 16 ) & 1 ) ;
show_msg ( ( char * ) aio_ex - > outbuf . data ) ;
2010-08-24 22:10:20 +04:00
if ( ! srv_send_smb ( aio_ex - > smbreq - > sconn ,
2010-08-14 16:53:45 +04:00
( char * ) aio_ex - > outbuf . data ,
2010-06-04 22:41:38 +04:00
true , aio_ex - > smbreq - > seqnum + 1 ,
2009-02-09 10:10:34 +03:00
IS_CONN_ENCRYPTED ( fsp - > conn ) ,
2010-06-04 22:41:38 +04:00
& aio_ex - > smbreq - > pcd ) ) {
2010-08-14 00:51:29 +04:00
exit_server_cleanly ( " schedule_aio_write_and_X: "
" srv_send_smb failed. " ) ;
2007-10-11 00:34:30 +04:00
}
DEBUG ( 10 , ( " schedule_aio_write_and_X: scheduled aio_write "
2009-07-11 01:50:37 +04:00
" behind for file %s \n " , fsp_str_dbg ( fsp ) ) ) ;
2007-10-11 00:34:30 +04:00
}
2005-06-28 02:53:56 +04:00
2007-02-10 16:15:58 +03:00
DEBUG ( 10 , ( " schedule_aio_write_and_X: scheduled aio_write for file "
" %s, offset %.0f, len = %u (mid = %u) "
" outstanding_aio_calls = %d \n " ,
2009-07-11 01:50:37 +04:00
fsp_str_dbg ( fsp ) , ( double ) startpos , ( unsigned int ) numtowrite ,
2010-06-04 22:41:38 +04:00
( unsigned int ) aio_ex - > smbreq - > mid , outstanding_aio_calls ) ) ;
2005-06-28 02:53:56 +04:00
2010-04-06 01:16:21 +04:00
return NT_STATUS_OK ;
2005-06-28 02:53:56 +04:00
}
2012-07-02 14:46:03 +04:00
static void aio_pwrite_smb1_done ( struct tevent_req * req )
{
struct aio_extra * aio_ex = tevent_req_callback_data (
req , struct aio_extra ) ;
files_struct * fsp = aio_ex - > fsp ;
char * outbuf = ( char * ) aio_ex - > outbuf . data ;
2012-07-06 17:05:02 +04:00
ssize_t numtowrite = aio_ex - > nbyte ;
2012-07-02 14:46:03 +04:00
ssize_t nwritten ;
int err ;
nwritten = SMB_VFS_PWRITE_RECV ( req , & err ) ;
TALLOC_FREE ( req ) ;
DEBUG ( 10 , ( " pwrite_recv returned %d, err = %s \n " , ( int ) nwritten ,
( nwritten = = - 1 ) ? strerror ( err ) : " no error " ) ) ;
if ( fsp = = NULL ) {
DEBUG ( 3 , ( " aio_pwrite_smb1_done: file closed whilst "
" aio outstanding (mid[%llu]). \n " ,
( unsigned long long ) aio_ex - > smbreq - > mid ) ) ;
TALLOC_FREE ( aio_ex ) ;
return ;
}
/* Unlock now we're done. */
SMB_VFS_STRICT_UNLOCK ( fsp - > conn , fsp , & aio_ex - > lock ) ;
if ( fsp - > aio_write_behind ) {
if ( nwritten ! = numtowrite ) {
if ( nwritten = = - 1 ) {
DEBUG ( 5 , ( " handle_aio_write_complete: "
" aio_write_behind failed ! File %s "
" is corrupt ! Error %s \n " ,
fsp_str_dbg ( fsp ) , strerror ( err ) ) ) ;
} else {
DEBUG ( 0 , ( " handle_aio_write_complete: "
" aio_write_behind failed ! File %s "
" is corrupt ! Wanted %u bytes but "
" only wrote %d \n " , fsp_str_dbg ( fsp ) ,
( unsigned int ) numtowrite ,
( int ) nwritten ) ) ;
}
} else {
DEBUG ( 10 , ( " handle_aio_write_complete: "
" aio_write_behind completed for file %s \n " ,
fsp_str_dbg ( fsp ) ) ) ;
}
/* TODO: should no return success in case of an error !!! */
TALLOC_FREE ( aio_ex ) ;
return ;
}
/* We don't need outsize or set_message here as we've already set the
fixed size length when we set up the aio call . */
if ( nwritten = = - 1 ) {
DEBUG ( 3 , ( " handle_aio_write: file %s wanted %u bytes. "
" nwritten == %d. Error = %s \n " ,
fsp_str_dbg ( fsp ) , ( unsigned int ) numtowrite ,
( int ) nwritten , strerror ( err ) ) ) ;
ERROR_NT ( map_nt_error_from_unix ( err ) ) ;
srv_set_message ( outbuf , 0 , 0 , true ) ;
} else {
NTSTATUS status ;
SSVAL ( outbuf , smb_vwv2 , nwritten ) ;
SSVAL ( outbuf , smb_vwv4 , ( nwritten > > 16 ) & 1 ) ;
if ( nwritten < ( ssize_t ) numtowrite ) {
SCVAL ( outbuf , smb_rcls , ERRHRD ) ;
SSVAL ( outbuf , smb_err , ERRdiskfull ) ;
}
DEBUG ( 3 , ( " handle_aio_write: %s, num=%d wrote=%d \n " ,
fsp_fnum_dbg ( fsp ) , ( int ) numtowrite , ( int ) nwritten ) ) ;
status = sync_file ( fsp - > conn , fsp , aio_ex - > write_through ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ERROR_BOTH ( map_nt_error_from_unix ( errno ) ,
ERRHRD , ERRdiskfull ) ;
srv_set_message ( outbuf , 0 , 0 , true ) ;
DEBUG ( 5 , ( " handle_aio_write: sync_file for %s "
" returned %s \n " ,
fsp_str_dbg ( fsp ) , nt_errstr ( status ) ) ) ;
}
2012-07-06 17:05:02 +04:00
aio_ex - > fsp - > fh - > pos = aio_ex - > offset + nwritten ;
2012-07-02 14:46:03 +04:00
}
show_msg ( outbuf ) ;
if ( ! srv_send_smb ( aio_ex - > smbreq - > sconn , outbuf ,
true , aio_ex - > smbreq - > seqnum + 1 ,
IS_CONN_ENCRYPTED ( fsp - > conn ) ,
NULL ) ) {
exit_server_cleanly ( " handle_aio_write_complete: "
" srv_send_smb failed. " ) ;
}
DEBUG ( 10 , ( " handle_aio_write_complete: scheduled aio_write completed "
" for file %s, offset %.0f, requested %u, written = %u \n " ,
2012-07-06 17:05:02 +04:00
fsp_str_dbg ( fsp ) , ( double ) aio_ex - > offset ,
2012-07-02 14:46:03 +04:00
( unsigned int ) numtowrite , ( unsigned int ) nwritten ) ) ;
TALLOC_FREE ( aio_ex ) ;
}
2011-11-14 12:52:47 +04:00
bool cancel_smb2_aio ( struct smb_request * smbreq )
{
struct smbd_smb2_request * smb2req = smbreq - > smb2req ;
struct aio_extra * aio_ex = NULL ;
if ( smb2req ) {
aio_ex = talloc_get_type ( smbreq - > async_priv ,
struct aio_extra ) ;
}
if ( aio_ex = = NULL ) {
return false ;
}
if ( aio_ex - > fsp = = NULL ) {
return false ;
}
2012-07-06 11:37:57 +04:00
/*
* We let the aio request run . Setting fsp to NULL has the
* effect that the _done routines don ' t send anything out .
*/
2011-11-14 12:52:47 +04:00
2012-07-06 11:37:57 +04:00
aio_ex - > fsp = NULL ;
2011-11-14 12:52:47 +04:00
return true ;
}
2012-07-02 14:46:03 +04:00
static void aio_pread_smb2_done ( struct tevent_req * req ) ;
2010-06-11 00:20:37 +04:00
/****************************************************************************
Set up an aio request from a SMB2 read call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS schedule_smb2_aio_read ( connection_struct * conn ,
struct smb_request * smbreq ,
files_struct * fsp ,
2010-12-15 03:32:10 +03:00
TALLOC_CTX * ctx ,
DATA_BLOB * preadbuf ,
2012-04-05 08:53:08 +04:00
off_t startpos ,
2010-06-11 00:20:37 +04:00
size_t smb_maxcnt )
{
struct aio_extra * aio_ex ;
size_t min_aio_read_size = lp_aio_read_size ( SNUM ( conn ) ) ;
2012-07-02 14:46:03 +04:00
struct tevent_req * req ;
2010-06-11 00:20:37 +04:00
if ( fsp - > base_fsp ! = NULL ) {
/* No AIO on streams yet */
DEBUG ( 10 , ( " AIO on streams not yet supported \n " ) ) ;
return NT_STATUS_RETRY ;
}
if ( ( ! min_aio_read_size | | ( smb_maxcnt < min_aio_read_size ) )
& & ! SMB_VFS_AIO_FORCE ( fsp ) ) {
/* Too small a read for aio request. */
DEBUG ( 10 , ( " smb2: read size (%u) too small "
" for minimum aio_read of %u \n " ,
( unsigned int ) smb_maxcnt ,
( unsigned int ) min_aio_read_size ) ) ;
return NT_STATUS_RETRY ;
}
/* Only do this on reads not using the write cache. */
if ( lp_write_cache_size ( SNUM ( conn ) ) ! = 0 ) {
return NT_STATUS_RETRY ;
}
if ( outstanding_aio_calls > = aio_pending_size ) {
DEBUG ( 10 , ( " smb2: Already have %d aio "
" activities outstanding. \n " ,
outstanding_aio_calls ) ) ;
return NT_STATUS_RETRY ;
}
2010-12-15 03:32:10 +03:00
/* Create the out buffer. */
* preadbuf = data_blob_talloc ( ctx , NULL , smb_maxcnt ) ;
if ( preadbuf - > data = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2010-06-11 00:20:37 +04:00
if ( ! ( aio_ex = create_aio_extra ( smbreq - > smb2req , fsp , 0 ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
init_strict_lock_struct ( fsp , ( uint64_t ) smbreq - > smbpid ,
( uint64_t ) startpos , ( uint64_t ) smb_maxcnt , READ_LOCK ,
& aio_ex - > lock ) ;
/* Take the lock until the AIO completes. */
if ( ! SMB_VFS_STRICT_LOCK ( conn , fsp , & aio_ex - > lock ) ) {
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_FILE_LOCK_CONFLICT ;
}
2012-07-06 17:05:02 +04:00
aio_ex - > nbyte = smb_maxcnt ;
aio_ex - > offset = startpos ;
2010-06-11 00:20:37 +04:00
2012-07-02 14:46:03 +04:00
req = SMB_VFS_PREAD_SEND ( aio_ex , fsp - > conn - > sconn - > ev_ctx , fsp ,
preadbuf - > data , smb_maxcnt , startpos ) ;
if ( req = = NULL ) {
DEBUG ( 0 , ( " smb2: SMB_VFS_PREAD_SEND failed. "
" Error %s \n " , strerror ( errno ) ) ) ;
2010-06-11 00:20:37 +04:00
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_RETRY ;
}
2012-07-02 14:46:03 +04:00
tevent_req_set_callback ( req , aio_pread_smb2_done , aio_ex ) ;
2010-06-11 00:20:37 +04:00
2012-07-06 11:37:57 +04:00
if ( ! aio_add_req_to_fsp ( fsp , req ) ) {
DEBUG ( 1 , ( " Could not add req to fsp \n " ) ) ;
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_RETRY ;
}
2010-06-11 00:20:37 +04:00
/* We don't need talloc_move here as both aio_ex and
* smbreq are children of smbreq - > smb2req . */
aio_ex - > smbreq = smbreq ;
2011-11-14 12:52:47 +04:00
smbreq - > async_priv = aio_ex ;
2010-06-11 00:20:37 +04:00
DEBUG ( 10 , ( " smb2: scheduled aio_read for file %s, "
" offset %.0f, len = %u (mid = %u) \n " ,
fsp_str_dbg ( fsp ) , ( double ) startpos , ( unsigned int ) smb_maxcnt ,
( unsigned int ) aio_ex - > smbreq - > mid ) ) ;
return NT_STATUS_OK ;
}
2012-07-02 14:46:03 +04:00
static void aio_pread_smb2_done ( struct tevent_req * req )
{
struct aio_extra * aio_ex = tevent_req_callback_data (
req , struct aio_extra ) ;
struct tevent_req * subreq = aio_ex - > smbreq - > smb2req - > subreq ;
files_struct * fsp = aio_ex - > fsp ;
NTSTATUS status ;
ssize_t nread ;
int err = 0 ;
nread = SMB_VFS_PREAD_RECV ( req , & err ) ;
TALLOC_FREE ( req ) ;
DEBUG ( 10 , ( " pread_recv returned %d, err = %s \n " , ( int ) nread ,
( nread = = - 1 ) ? strerror ( err ) : " no error " ) ) ;
if ( fsp = = NULL ) {
DEBUG ( 3 , ( " aio_pread_smb2_done: file closed whilst "
" aio outstanding (mid[%llu]). \n " ,
( unsigned long long ) aio_ex - > smbreq - > mid ) ) ;
TALLOC_FREE ( aio_ex ) ;
return ;
}
/* Unlock now we're done. */
SMB_VFS_STRICT_UNLOCK ( fsp - > conn , fsp , & aio_ex - > lock ) ;
/* Common error or success code processing for async or sync
read returns . */
status = smb2_read_complete ( subreq , nread , err ) ;
if ( nread > 0 ) {
2012-07-06 17:05:02 +04:00
fsp - > fh - > pos = aio_ex - > offset + nread ;
2012-07-02 14:46:03 +04:00
fsp - > fh - > position_information = fsp - > fh - > pos ;
}
DEBUG ( 10 , ( " smb2: scheduled aio_read completed "
" for file %s, offset %.0f, len = %u "
" (errcode = %d, NTSTATUS = %s) \n " ,
fsp_str_dbg ( aio_ex - > fsp ) ,
2012-07-06 17:05:02 +04:00
( double ) aio_ex - > offset ,
2012-07-02 14:46:03 +04:00
( unsigned int ) nread ,
err , nt_errstr ( status ) ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
tevent_req_nterror ( subreq , status ) ;
return ;
}
tevent_req_done ( subreq ) ;
}
2012-07-02 14:46:03 +04:00
static void aio_pwrite_smb2_done ( struct tevent_req * req ) ;
2010-06-11 00:20:37 +04:00
/****************************************************************************
Set up an aio request from a SMB2write call .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS schedule_aio_smb2_write ( connection_struct * conn ,
struct smb_request * smbreq ,
files_struct * fsp ,
uint64_t in_offset ,
DATA_BLOB in_data ,
bool write_through )
{
struct aio_extra * aio_ex = NULL ;
size_t min_aio_write_size = lp_aio_write_size ( SNUM ( conn ) ) ;
2012-07-02 14:46:03 +04:00
struct tevent_req * req ;
2010-06-11 00:20:37 +04:00
if ( fsp - > base_fsp ! = NULL ) {
/* No AIO on streams yet */
DEBUG ( 10 , ( " AIO on streams not yet supported \n " ) ) ;
return NT_STATUS_RETRY ;
}
if ( ( ! min_aio_write_size | | ( in_data . length < min_aio_write_size ) )
& & ! SMB_VFS_AIO_FORCE ( fsp ) ) {
/* Too small a write for aio request. */
DEBUG ( 10 , ( " smb2: write size (%u) too "
" small for minimum aio_write of %u \n " ,
( unsigned int ) in_data . length ,
( unsigned int ) min_aio_write_size ) ) ;
return NT_STATUS_RETRY ;
}
/* Only do this on writes not using the write cache. */
if ( lp_write_cache_size ( SNUM ( conn ) ) ! = 0 ) {
return NT_STATUS_RETRY ;
}
if ( outstanding_aio_calls > = aio_pending_size ) {
DEBUG ( 3 , ( " smb2: Already have %d aio "
" activities outstanding. \n " ,
outstanding_aio_calls ) ) ;
return NT_STATUS_RETRY ;
}
if ( ! ( aio_ex = create_aio_extra ( smbreq - > smb2req , fsp , 0 ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
aio_ex - > write_through = write_through ;
init_strict_lock_struct ( fsp , ( uint64_t ) smbreq - > smbpid ,
in_offset , ( uint64_t ) in_data . length , WRITE_LOCK ,
& aio_ex - > lock ) ;
/* Take the lock until the AIO completes. */
if ( ! SMB_VFS_STRICT_LOCK ( conn , fsp , & aio_ex - > lock ) ) {
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_FILE_LOCK_CONFLICT ;
}
2012-07-06 17:05:02 +04:00
aio_ex - > nbyte = in_data . length ;
aio_ex - > offset = in_offset ;
2010-06-11 00:20:37 +04:00
2012-07-02 14:46:03 +04:00
req = SMB_VFS_PWRITE_SEND ( aio_ex , fsp - > conn - > sconn - > ev_ctx , fsp ,
in_data . data , in_data . length , in_offset ) ;
if ( req = = NULL ) {
DEBUG ( 3 , ( " smb2: SMB_VFS_PWRITE_SEND failed. "
" Error %s \n " , strerror ( errno ) ) ) ;
2010-06-11 00:20:37 +04:00
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_RETRY ;
}
2012-07-02 14:46:03 +04:00
tevent_req_set_callback ( req , aio_pwrite_smb2_done , aio_ex ) ;
2010-06-11 00:20:37 +04:00
2012-07-06 11:37:57 +04:00
if ( ! aio_add_req_to_fsp ( fsp , req ) ) {
DEBUG ( 1 , ( " Could not add req to fsp \n " ) ) ;
SMB_VFS_STRICT_UNLOCK ( conn , fsp , & aio_ex - > lock ) ;
TALLOC_FREE ( aio_ex ) ;
return NT_STATUS_RETRY ;
}
2010-06-11 00:20:37 +04:00
/* We don't need talloc_move here as both aio_ex and
* smbreq are children of smbreq - > smb2req . */
aio_ex - > smbreq = smbreq ;
2011-11-14 12:52:47 +04:00
smbreq - > async_priv = aio_ex ;
2010-06-11 00:20:37 +04:00
/* This should actually be improved to span the write. */
contend_level2_oplocks_begin ( fsp , LEVEL2_CONTEND_WRITE ) ;
contend_level2_oplocks_end ( fsp , LEVEL2_CONTEND_WRITE ) ;
/*
* We don ' t want to do write behind due to ownership
* issues of the request structs . Maybe add it if I
* figure those out . JRA .
*/
DEBUG ( 10 , ( " smb2: scheduled aio_write for file "
" %s, offset %.0f, len = %u (mid = %u) "
" outstanding_aio_calls = %d \n " ,
fsp_str_dbg ( fsp ) ,
( double ) in_offset ,
( unsigned int ) in_data . length ,
( unsigned int ) aio_ex - > smbreq - > mid ,
outstanding_aio_calls ) ) ;
return NT_STATUS_OK ;
}
2012-07-02 14:46:03 +04:00
static void aio_pwrite_smb2_done ( struct tevent_req * req )
{
struct aio_extra * aio_ex = tevent_req_callback_data (
req , struct aio_extra ) ;
2012-07-06 17:05:02 +04:00
ssize_t numtowrite = aio_ex - > nbyte ;
2012-07-02 14:46:03 +04:00
struct tevent_req * subreq = aio_ex - > smbreq - > smb2req - > subreq ;
files_struct * fsp = aio_ex - > fsp ;
NTSTATUS status ;
ssize_t nwritten ;
int err = 0 ;
nwritten = SMB_VFS_PWRITE_RECV ( req , & err ) ;
TALLOC_FREE ( req ) ;
DEBUG ( 10 , ( " pwrite_recv returned %d, err = %s \n " , ( int ) nwritten ,
( nwritten = = - 1 ) ? strerror ( err ) : " no error " ) ) ;
if ( fsp = = NULL ) {
DEBUG ( 3 , ( " aio_pwrite_smb2_done: file closed whilst "
" aio outstanding (mid[%llu]). \n " ,
( unsigned long long ) aio_ex - > smbreq - > mid ) ) ;
TALLOC_FREE ( aio_ex ) ;
return ;
}
/* Unlock now we're done. */
SMB_VFS_STRICT_UNLOCK ( fsp - > conn , fsp , & aio_ex - > lock ) ;
status = smb2_write_complete ( subreq , nwritten , err ) ;
DEBUG ( 10 , ( " smb2: scheduled aio_write completed "
" for file %s, offset %.0f, requested %u, "
" written = %u (errcode = %d, NTSTATUS = %s) \n " ,
fsp_str_dbg ( fsp ) ,
2012-07-06 17:05:02 +04:00
( double ) aio_ex - > offset ,
2012-07-02 14:46:03 +04:00
( unsigned int ) numtowrite ,
( unsigned int ) nwritten ,
err , nt_errstr ( status ) ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
tevent_req_nterror ( subreq , status ) ;
return ;
}
tevent_req_done ( subreq ) ;
}
2005-06-28 02:53:56 +04:00
/****************************************************************************
Handle any aio completion inline .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-06-04 22:30:46 +04:00
void smbd_aio_complete_aio_ex ( struct aio_extra * aio_ex )
2005-06-28 02:53:56 +04:00
{
2012-07-06 11:38:33 +04:00
return ;
2009-01-22 20:04:17 +03:00
}
2005-06-28 02:53:56 +04:00
2012-07-06 11:37:57 +04:00
void aio_fsp_close ( files_struct * fsp )
2007-10-11 00:34:30 +04:00
{
2012-07-06 11:37:57 +04:00
unsigned i ;
2007-10-11 00:34:30 +04:00
2012-07-06 11:37:57 +04:00
for ( i = 0 ; i < fsp - > num_aio_requests ; i + + ) {
struct tevent_req * req = fsp - > aio_requests [ i ] ;
struct aio_extra * aio_ex = tevent_req_callback_data (
req , struct aio_extra ) ;
aio_ex - > fsp = NULL ;
2007-10-11 00:34:30 +04:00
}
}
2009-01-22 20:04:17 +03:00
# else
2012-04-08 22:11:53 +04:00
bool initialize_async_io_handler ( void )
{
return false ;
}
2010-04-06 01:16:21 +04:00
NTSTATUS schedule_aio_read_and_X ( connection_struct * conn ,
2010-06-04 22:41:38 +04:00
struct smb_request * smbreq ,
2012-04-05 08:53:08 +04:00
files_struct * fsp , off_t startpos ,
2005-06-28 02:53:56 +04:00
size_t smb_maxcnt )
{
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2010-04-06 01:16:21 +04:00
NTSTATUS schedule_aio_write_and_X ( connection_struct * conn ,
2010-06-04 22:41:38 +04:00
struct smb_request * smbreq ,
2011-05-05 22:38:06 +04:00
files_struct * fsp , const char * data ,
2012-04-05 08:53:08 +04:00
off_t startpos ,
2007-08-08 23:05:30 +04:00
size_t numtowrite )
2005-06-28 02:53:56 +04:00
{
2010-04-06 01:16:21 +04:00
return NT_STATUS_RETRY ;
2005-06-28 02:53:56 +04:00
}
2011-11-14 12:52:47 +04:00
bool cancel_smb2_aio ( struct smb_request * smbreq )
{
return false ;
}
2010-06-11 01:28:55 +04:00
NTSTATUS schedule_smb2_aio_read ( connection_struct * conn ,
struct smb_request * smbreq ,
files_struct * fsp ,
2010-12-15 03:32:10 +03:00
TALLOC_CTX * ctx ,
DATA_BLOB * preadbuf ,
2012-04-05 08:53:08 +04:00
off_t startpos ,
2010-06-11 01:28:55 +04:00
size_t smb_maxcnt )
{
return NT_STATUS_RETRY ;
}
NTSTATUS schedule_aio_smb2_write ( connection_struct * conn ,
struct smb_request * smbreq ,
files_struct * fsp ,
uint64_t in_offset ,
DATA_BLOB in_data ,
bool write_through )
{
return NT_STATUS_RETRY ;
}
2012-07-06 11:37:57 +04:00
void aio_fsp_close ( files_struct * fsp )
{
return ;
}
2007-10-19 04:40:25 +04:00
int wait_for_aio_completion ( files_struct * fsp )
2007-10-11 00:34:30 +04:00
{
2010-06-04 22:41:57 +04:00
return 0 ;
2007-10-11 00:34:30 +04:00
}
2009-01-22 20:04:17 +03:00
2010-04-13 08:40:28 +04:00
void smbd_aio_complete_mid ( uint64_t mid ) ;
2009-01-22 20:04:17 +03:00
2005-06-28 02:53:56 +04:00
# endif