summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-12-14 16:32:10 -0800
committerJeremy Allison <jra@samba.org>2010-12-15 01:38:16 +0100
commit14c70346fc88d05dfabc14b0a932632470fee6fe (patch)
treed1382cdcb7bf0cb0804a7f374b92044b30cc9a83
parent3bc1cf94e3a0febe8d3d53229aa49c3d8eb8c1b6 (diff)
downloadsamba-14c70346fc88d05dfabc14b0a932632470fee6fe.tar.gz
samba-14c70346fc88d05dfabc14b0a932632470fee6fe.tar.bz2
samba-14c70346fc88d05dfabc14b0a932632470fee6fe.zip
Change interface of schedule_smb2_aio_read() to allocate the return DATA_BLOB.
Change smb2_read code to allocate return DATA_BLOB just before the read. Preparing for SMB2 sendfile change which will not need to allocate return buffer. Jeremy
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/smbd/aio.c14
-rw-r--r--source3/smbd/smb2_read.c20
3 files changed, 27 insertions, 10 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 084d97f16e..2ba2153258 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4438,7 +4438,8 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
struct smb_request *smbreq,
files_struct *fsp,
- char *inbuf,
+ TALLOC_CTX *ctx,
+ DATA_BLOB *preadbuf,
SMB_OFF_T startpos,
size_t smb_maxcnt);
NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 7a23d37918..eb8ed6799f 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -385,7 +385,8 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
struct smb_request *smbreq,
files_struct *fsp,
- char *inbuf,
+ TALLOC_CTX *ctx,
+ DATA_BLOB *preadbuf,
SMB_OFF_T startpos,
size_t smb_maxcnt)
{
@@ -427,6 +428,12 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
return NT_STATUS_RETRY;
}
+ /* Create the out buffer. */
+ *preadbuf = data_blob_talloc(ctx, NULL, smb_maxcnt);
+ if (preadbuf->data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
if (!(aio_ex = create_aio_extra(smbreq->smb2req, fsp, 0))) {
return NT_STATUS_NO_MEMORY;
}
@@ -447,7 +454,7 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
/* Now set up the aio record for the read call. */
a->aio_fildes = fsp->fh->fd;
- a->aio_buf = inbuf;
+ a->aio_buf = preadbuf->data;
a->aio_nbytes = smb_maxcnt;
a->aio_offset = startpos;
a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
@@ -1031,7 +1038,8 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
struct smb_request *smbreq,
files_struct *fsp,
- char *inbuf,
+ TALLOC_CTX *ctx,
+ DATA_BLOB *preadbuf,
SMB_OFF_T startpos,
size_t smb_maxcnt)
{
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index b1866d1481..97f12d582c 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -290,16 +290,16 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- state->out_data = data_blob_talloc(state, NULL, in_length);
- if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
- return tevent_req_post(req, ev);
- }
-
state->fsp = fsp;
if (IS_IPC(smbreq->conn)) {
struct tevent_req *subreq = NULL;
+ state->out_data = data_blob_talloc(state, NULL, in_length);
+ if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
if (!fsp_is_np(fsp)) {
tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
return tevent_req_post(req, ev);
@@ -326,7 +326,8 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
status = schedule_smb2_aio_read(fsp->conn,
smbreq,
fsp,
- (char *)state->out_data.data,
+ state,
+ &state->out_data,
(SMB_OFF_T)in_offset,
(size_t)in_length);
@@ -363,6 +364,13 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
+ /* Ok, read into memory. Allocate the out buffer. */
+ state->out_data = data_blob_talloc(state, NULL, in_length);
+ if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+ return tevent_req_post(req, ev);
+ }
+
nread = read_file(fsp,
(char *)state->out_data.data,
in_offset,