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
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
*****************************************************************************/
static struct aio_extra *create_aio_ex_write(files_struct *fsp,
- size_t outbuflen, uint16 mid)
+ size_t inbuflen,
+ size_t outbuflen,
+ uint16 mid)
{
struct aio_extra *aio_ex = SMB_MALLOC_P(struct aio_extra);
SAFE_FREE(aio_ex);
return NULL;
}
- /* Steal the input buffer containing the write data from the main SMB
- * call. */
- /* We must re-allocate a new one here. */
- if (NewInBuffer(&aio_ex->inbuf) == NULL) {
+
+ if (!(aio_ex->inbuf = SMB_MALLOC_ARRAY(char, inbuflen))) {
SAFE_FREE(aio_ex->outbuf);
SAFE_FREE(aio_ex);
return NULL;
}
- /* aio_ex->inbuf now contains the stolen old InBuf containing the data
- * to write. */
-
DLIST_ADD(aio_list_head, aio_ex);
aio_ex->fsp = fsp;
aio_ex->read_req = False;
static void delete_aio_ex(struct aio_extra *aio_ex)
{
DLIST_REMOVE(aio_list_head, aio_ex);
- /* Safe to do as we've removed ourselves from the in use list first. */
- free_InBuffer(aio_ex->inbuf);
-
+ SAFE_FREE(aio_ex->inbuf);
SAFE_FREE(aio_ex->outbuf);
SAFE_FREE(aio_ex);
}
static void signal_handler(int sig, siginfo_t *info, void *unused)
{
- if (signals_received < AIO_PENDING_SIZE - 1) {
+ if (signals_received < AIO_PENDING_SIZE) {
aio_pending_array[signals_received] = info->si_value.sival_int;
signals_received++;
} /* Else signal is lost. */
*****************************************************************************/
BOOL schedule_aio_read_and_X(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int len_outbuf,
+ struct smb_request *req,
files_struct *fsp, SMB_OFF_T startpos,
size_t smb_maxcnt)
{
/* Only do this on non-chained and non-chaining reads not using the
* write cache. */
- if (chain_size !=0 || (CVAL(inbuf,smb_vwv0) != 0xFF)
+ if (chain_size !=0 || (CVAL(req->inbuf,smb_vwv0) != 0xFF)
|| (lp_write_cache_size(SNUM(conn)) != 0) ) {
return False;
}
return False;
}
- /* The following is safe from integer wrap as we've already
- checked smb_maxcnt is 128k or less. */
- bufsize = PTR_DIFF(smb_buf(outbuf),outbuf) + smb_maxcnt;
+ /* The following is safe from integer wrap as we've already checked
+ smb_maxcnt is 128k or less. Wct is 12 for read replies */
- if ((aio_ex = create_aio_ex_read(fsp, bufsize,
- SVAL(inbuf,smb_mid))) == NULL) {
+ bufsize = smb_size + 12 * 2 + smb_maxcnt;
+
+ if ((aio_ex = create_aio_ex_read(fsp, bufsize, req->mid)) == NULL) {
DEBUG(10,("schedule_aio_read_and_X: malloc fail.\n"));
return False;
}
- /* Copy the SMB header already setup in outbuf. */
- memcpy(aio_ex->outbuf, outbuf, smb_buf(outbuf) - outbuf);
+ construct_reply_common((char *)req->inbuf, aio_ex->outbuf);
+ set_message(aio_ex->outbuf, 12, 0, True);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
*****************************************************************************/
BOOL schedule_aio_write_and_X(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int len_outbuf,
- files_struct *fsp, char *data,
- SMB_OFF_T startpos,
- size_t numtowrite)
+ struct smb_request *req,
+ files_struct *fsp, char *data,
+ SMB_OFF_T startpos,
+ size_t numtowrite)
{
struct aio_extra *aio_ex;
SMB_STRUCT_AIOCB *a;
- size_t outbufsize;
- BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
+ size_t inbufsize, outbufsize;
+ BOOL write_through = BITSETW(req->inbuf+smb_vwv7,0);
size_t min_aio_write_size = lp_aio_write_size(SNUM(conn));
if (!min_aio_write_size || (numtowrite < min_aio_write_size)) {
/* Only do this on non-chained and non-chaining reads not using the
* write cache. */
- if (chain_size !=0 || (CVAL(inbuf,smb_vwv0) != 0xFF)
+ if (chain_size !=0 || (CVAL(req->inbuf,smb_vwv0) != 0xFF)
|| (lp_write_cache_size(SNUM(conn)) != 0) ) {
return False;
}
"(mid = %u)\n",
fsp->fsp_name, (double)startpos,
(unsigned int)numtowrite,
- (unsigned int)SVAL(inbuf,smb_mid) ));
+ (unsigned int)req->mid ));
return False;
}
- outbufsize = smb_len(outbuf) + 4;
- if ((aio_ex = create_aio_ex_write(fsp, outbufsize,
- SVAL(inbuf,smb_mid))) == NULL) {
+ inbufsize = smb_len(req->inbuf) + 4;
+ reply_outbuf(req, 6, 0);
+ outbufsize = smb_len(req->outbuf) + 4;
+ if (!(aio_ex = create_aio_ex_write(fsp, inbufsize, outbufsize,
+ req->mid))) {
DEBUG(0,("schedule_aio_write_and_X: malloc fail.\n"));
return False;
}
- /* Paranioa.... */
- SMB_ASSERT(aio_ex->inbuf == inbuf);
+ /* Copy the SMB header already setup in outbuf. */
+ memcpy(aio_ex->inbuf, req->inbuf, inbufsize);
/* Copy the SMB header already setup in outbuf. */
- memcpy(aio_ex->outbuf, outbuf, outbufsize);
+ memcpy(aio_ex->outbuf, req->outbuf, outbufsize);
+ TALLOC_FREE(req->outbuf);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
/* Now set up the aio record for the write call. */
a->aio_fildes = fsp->fh->fd;
- a->aio_buf = data; /* As we've stolen inbuf this points within
- * inbuf. */
+ a->aio_buf = aio_ex->inbuf + (PTR_DIFF(data, req->inbuf));
a->aio_nbytes = numtowrite;
a->aio_offset = startpos;
a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
if (SMB_VFS_AIO_WRITE(fsp,a) == -1) {
DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. "
"Error %s\n", strerror(errno) ));
- /* Replace global InBuf as we're going to do a normal write. */
- set_InBuffer(aio_ex->inbuf);
- aio_ex->inbuf = NULL;
delete_aio_ex(aio_ex);
return False;
}
DEBUG( 3, ( "handle_aio_read_complete file %s max=%d "
"nread=%d\n",
aio_ex->fsp->fsp_name,
- aio_ex->acb.aio_nbytes, (int)nread ) );
+ (int)aio_ex->acb.aio_nbytes, (int)nread ) );
}
smb_setlen(outbuf,outsize - 4);
ret = errno;
} else {
BOOL write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0);
+ NTSTATUS status;
SSVAL(outbuf,smb_vwv2,nwritten);
SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
DEBUG(3,("handle_aio_write: fnum=%d num=%d wrote=%d\n",
fsp->fnum, (int)numtowrite, (int)nwritten));
- sync_file(fsp->conn,fsp, write_through);
+ status = sync_file(fsp->conn,fsp, write_through);
+ if (!NT_STATUS_IS_OK(status)) {
+ UNIXERROR(ERRHRD,ERRdiskfull);
+ ret = errno;
+ DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
+ fsp->fsp_name, nt_errstr(status) ));
+ }
}
show_msg(outbuf);
}
}
-/****************************************************************************
- Check if a buffer was stolen for aio use.
-*****************************************************************************/
-
-BOOL aio_inbuffer_in_use(char *inbuf)
-{
- struct aio_extra *aio_ex;
-
- for( aio_ex = aio_list_head; aio_ex; aio_ex = aio_ex->next) {
- if (aio_ex->inbuf == inbuf) {
- return True;
- }
- }
- return False;
-}
#else
BOOL aio_finished(void)
{
}
BOOL schedule_aio_read_and_X(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int len_outbuf,
+ struct smb_request *req,
files_struct *fsp, SMB_OFF_T startpos,
size_t smb_maxcnt)
{
}
BOOL schedule_aio_write_and_X(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int len_outbuf,
- files_struct *fsp, char *data,
- SMB_OFF_T startpos,
- size_t numtowrite)
+ struct smb_request *req,
+ files_struct *fsp, char *data,
+ SMB_OFF_T startpos,
+ size_t numtowrite)
{
return False;
}
{
return True;
}
-
-BOOL aio_inbuffer_in_use(char *ptr)
-{
- return False;
-}
#endif