[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Tue Nov 15 10:48:04 MST 2011
The branch, master has been updated
via 31cd1fb s3:smbd/aio: handle_aio_completed() should do nothing if aio_ex->fsp is NULL
via 21eb145 s3:smbd/aio: pass ECANCELED to the smb2 aio handlers
via 483b79c s3:smb2_read: make it possible to cancel aio reads
via 3fbf322 s3:smb2_write: make it possible to cancel aio writes
via 2802be7 s3:smbd/aio: add cancel_smb2_aio()
via 0cd6769 s3:smb2_ioctl: STATUS_PENDING is defered by 1 millisecond for SMB2_IOCTL
via 05246ae s3:smb2_create: defer STATUS_PENDING for 2 seconds as before
via 88dd90d s3:smb2_server: pass explicit defer_times to smbd_smb2_request_pending_queue()
via 693cb77 s3:smb2_server: always send STATUS_PENDING responses, but delayed by 0.5 milliseconds
from 10b285c s3-winbind: Don't fail on users without a uid.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 31cd1fbd2b1c2d1635662688e979bb5baa992855
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 09:54:05 2011 +0100
s3:smbd/aio: handle_aio_completed() should do nothing if aio_ex->fsp is NULL
metze
Autobuild-User: Stefan Metzmacher <metze at samba.org>
Autobuild-Date: Tue Nov 15 18:47:55 CET 2011 on sn-devel-104
commit 21eb1450cc2541e23dedf1a0dec24e3313ab8739
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 09:53:25 2011 +0100
s3:smbd/aio: pass ECANCELED to the smb2 aio handlers
metze
commit 483b79cfc4af4dd48089b12b279d174f54132e9d
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 09:33:22 2011 +0100
s3:smb2_read: make it possible to cancel aio reads
metze
commit 3fbf32213a9523ecab4bc201018d94f38b561b0b
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 09:33:22 2011 +0100
s3:smb2_write: make it possible to cancel aio writes
metze
commit 2802be75e38d5ae64ad5ec36e46d0799c77eec30
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 09:52:47 2011 +0100
s3:smbd/aio: add cancel_smb2_aio()
metze
commit 0cd67698ca69d82936da29658103ce449d797c25
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 15:29:37 2011 +0100
s3:smb2_ioctl: STATUS_PENDING is defered by 1 millisecond for SMB2_IOCTL
metze
commit 05246ae6238483eff759897d8a6aa9be7f49529f
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 15:50:47 2011 +0100
s3:smb2_create: defer STATUS_PENDING for 2 seconds as before
metze
commit 88dd90d9288e49c33f4e8d528bf109a40fc997d8
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 14 15:42:55 2011 +0100
s3:smb2_server: pass explicit defer_times to smbd_smb2_request_pending_queue()
metze
commit 693cb77b2fdb96205ab83bb2c22b67fe91de61b0
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Nov 9 11:47:33 2011 +0100
s3:smb2_server: always send STATUS_PENDING responses, but delayed by 0.5 milliseconds
In future we'll pass the delay from the caller.
metze
-----------------------------------------------------------------------
Summary of changes:
source3/smbd/aio.c | 48 +++++++++-
source3/smbd/globals.h | 5 +-
source3/smbd/proto.h | 1 +
source3/smbd/smb2_break.c | 2 +-
source3/smbd/smb2_create.c | 42 ++------
source3/smbd/smb2_find.c | 2 +-
source3/smbd/smb2_flush.c | 2 +-
source3/smbd/smb2_getinfo.c | 2 +-
source3/smbd/smb2_ioctl.c | 2 +-
source3/smbd/smb2_lock.c | 2 +-
source3/smbd/smb2_notify.c | 2 +-
source3/smbd/smb2_read.c | 25 +++--
source3/smbd/smb2_server.c | 227 +++++++++++++++++++++++--------------------
source3/smbd/smb2_setinfo.c | 2 +-
source3/smbd/smb2_write.c | 25 +++--
15 files changed, 223 insertions(+), 166 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 98a35ed..d367826 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -49,6 +49,7 @@ struct aio_extra {
DATA_BLOB outbuf;
struct lock_struct lock;
bool write_through;
+ bool pass_cancel;
int (*handle_completion)(struct aio_extra *ex, int errcode);
};
@@ -380,6 +381,37 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
return NT_STATUS_OK;
}
+bool cancel_smb2_aio(struct smb_request *smbreq)
+{
+ struct smbd_smb2_request *smb2req = smbreq->smb2req;
+ struct aio_extra *aio_ex = NULL;
+ int ret;
+
+ if (smbreq) {
+ smb2req = smbreq->smb2req;
+ }
+
+ 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;
+ }
+
+ ret = SMB_VFS_AIO_CANCEL(aio_ex->fsp, &aio_ex->acb);
+ if (ret != AIO_CANCELED) {
+ return false;
+ }
+
+ return true;
+}
+
/****************************************************************************
Set up an aio request from a SMB2 read call.
*****************************************************************************/
@@ -440,6 +472,7 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
return NT_STATUS_NO_MEMORY;
}
aio_ex->handle_completion = handle_aio_smb2_read_complete;
+ aio_ex->pass_cancel = true;
init_strict_lock_struct(fsp, (uint64_t)smbreq->smbpid,
(uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
@@ -476,6 +509,7 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
/* We don't need talloc_move here as both aio_ex and
* smbreq are children of smbreq->smb2req. */
aio_ex->smbreq = smbreq;
+ smbreq->async_priv = aio_ex;
DEBUG(10,("smb2: scheduled aio_read for file %s, "
"offset %.0f, len = %u (mid = %u)\n",
@@ -540,6 +574,7 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
aio_ex->handle_completion = handle_aio_smb2_write_complete;
aio_ex->write_through = write_through;
+ aio_ex->pass_cancel = true;
init_strict_lock_struct(fsp, (uint64_t)smbreq->smbpid,
in_offset, (uint64_t)in_data.length, WRITE_LOCK,
@@ -576,6 +611,7 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
/* We don't need talloc_move here as both aio_ex and
* smbreq are children of smbreq->smb2req. */
aio_ex->smbreq = smbreq;
+ smbreq->async_priv = aio_ex;
/* This should actually be improved to span the write. */
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_WRITE);
@@ -835,6 +871,11 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
return false;
}
+ if (!aio_ex->fsp) {
+ DEBUG(3, ("handle_aio_completed: aio_ex->fsp == NULL\n"));
+ return false;
+ }
+
fsp = aio_ex->fsp;
/* Ensure the operation has really completed. */
@@ -850,7 +891,7 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
/* Unlock now we're done. */
SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &aio_ex->lock);
- if (err == ECANCELED) {
+ if (!aio_ex->pass_cancel && err == ECANCELED) {
/* If error is ECANCELED then don't return anything to the
* client. */
DEBUG(10,( "handle_aio_completed: operation mid %llu"
@@ -1039,6 +1080,11 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
return NT_STATUS_RETRY;
}
+bool cancel_smb2_aio(struct smb_request *smbreq)
+{
+ return false;
+}
+
NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
struct smb_request *smbreq,
files_struct *fsp,
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 2e94b55..a02988a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -259,7 +259,8 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
uint8_t oplock_level);
NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
- struct tevent_req *subreq);
+ struct tevent_req *subreq,
+ uint32_t defer_time);
struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
void remove_smb2_chained_fsp(files_struct *fsp);
@@ -347,7 +348,7 @@ struct smbd_smb2_request {
int current_idx;
bool do_signing;
- bool async;
+ struct tevent_timer *async_te;
bool cancelled;
bool compound_related;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 0a68a6c..fe90766 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -86,6 +86,7 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
uint64_t in_offset,
DATA_BLOB in_data,
bool write_through);
+bool cancel_smb2_aio(struct smb_request *smbreq);
int wait_for_aio_completion(files_struct *fsp);
void cancel_aio_by_fsp(files_struct *fsp);
void smbd_aio_complete_aio_ex(struct aio_extra *aio_ex);
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index ce583ac..9899d92 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -78,7 +78,7 @@ NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_oplock_break_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_oplock_break_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 29696dc..6d7d4ac 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -244,7 +244,13 @@ NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
}
tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
- return smbd_smb2_request_pending_queue(smb2req, tsubreq);
+ /*
+ * For now we keep the logic that we do not send STATUS_PENDING
+ * for sharing violations, so we just wait 2 seconds.
+ *
+ * TODO: we need more tests for this.
+ */
+ return smbd_smb2_request_pending_queue(smb2req, tsubreq, 2000000);
}
static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
@@ -437,7 +443,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
}
- if (!smb2req->async) {
+ if (smb2req->subreq == NULL) {
/* New create call. */
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_create_state);
@@ -445,7 +451,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
return NULL;
}
state->smb2req = smb2req;
- smb2req->subreq = req; /* So we can find this when going async. */
smb1req = smbd_smb2_fake_smb_request(smb2req);
if (tevent_req_nomem(smb1req, req)) {
@@ -892,7 +897,7 @@ bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
if (!smb2req) {
return false;
}
- if (!smb2req->async) {
+ if (smb2req->subreq == NULL) {
return false;
}
req = smb2req->subreq;
@@ -1201,35 +1206,6 @@ bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
return false;
}
-#if 1
- /* Boo - turns out this isn't what W2K8R2
- does. It actually sends the STATUS_PENDING
- message followed by the STATUS_SHARING_VIOLATION
- message. Surely this means that all open
- calls (even on directories) will potentially
- fail in a chain.... ? And I've seen directory
- opens as the start of a chain. JRA.
-
- Update: 19th May 2010. Talking with Microsoft
- engineers at the plugfest this is a bug in
- Windows. Re-enable this code.
- */
- /*
- * More subtlety. To match W2K8R2 don't
- * send a "gone async" message if it's simply
- * a STATUS_SHARING_VIOLATION (short) wait, not
- * an oplock break wait. We do this by prematurely
- * setting smb2req->async flag.
- */
- if (timeout.tv_sec < 2) {
- DEBUG(10,("push_deferred_open_message_smb2: "
- "short timer wait (usec = %u). "
- "Don't send async message.\n",
- (unsigned int)timeout.tv_usec ));
- smb2req->async = true;
- }
-#endif
-
/* Re-schedule us to retry on timer expiry. */
end_time = timeval_sum(&request_time, &timeout);
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 6369e7f..9b1179f 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -135,7 +135,7 @@ NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_find_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_find_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 5f3c42a..3464c58 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -64,7 +64,7 @@ NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_flush_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_flush_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index c5d2d62..81d781a 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -118,7 +118,7 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_getinfo_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 5a766e1..b7b4592 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -110,7 +110,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_ioctl_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 1000);
}
static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index ed1d688..4f88bb8 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -133,7 +133,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_lock_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 49c6a54..5375e21 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -95,7 +95,7 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_notify_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_notify_done(struct tevent_req *subreq)
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 405e82d..0862209 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -100,7 +100,7 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
}
tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
- return smbd_smb2_request_pending_queue(req, subreq);
+ return smbd_smb2_request_pending_queue(req, subreq, 500);
}
static void smbd_smb2_request_read_done(struct tevent_req *subreq)
@@ -169,6 +169,7 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq)
struct smbd_smb2_read_state {
struct smbd_smb2_request *smb2req;
+ struct smb_request *smbreq;
files_struct *fsp;
uint64_t in_file_id_volatile;
uint32_t in_length;
@@ -364,6 +365,17 @@ NTSTATUS smb2_read_complete(struct tevent_req *req, ssize_t nread, int err)
return NT_STATUS_OK;
}
+static bool smbd_smb2_read_cancel(struct tevent_req *req)
+{
+ struct smbd_smb2_read_state *state =
+ tevent_req_data(req,
+ struct smbd_smb2_read_state);
+
+ state->smb2req->cancelled = true;
+
+ return cancel_smb2_aio(state->smbreq);
+}
+
static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
@@ -403,6 +415,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(smbreq, req)) {
return tevent_req_post(req, ev);
}
+ state->smbreq = smbreq;
fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);
if (fsp == NULL) {
@@ -466,14 +479,10 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(status)) {
/*
- * Doing an async read. Don't
- * send a "gone async" message
- * as we expect this to be less
- * than the client timeout period.
- * JRA. FIXME for offline files..
- * FIXME. Add cancel code..
+ * Doing an async read, allow this
+ * request to be canceled
*/
- smb2req->async = true;
+ tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
return req;
}
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 33e95ad..dbb0089 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -711,15 +711,6 @@ static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *re
newreq->session = req->session;
newreq->do_signing = req->do_signing;
newreq->current_idx = req->current_idx;
- newreq->async = false;
- newreq->cancelled = false;
- /* Note we are leaving:
- ->tcon
- ->smb1req
- ->compat_chain_fsp
- uninitialized as NULL here as
- they're not used in the interim
- response code. JRA. */
outvec = talloc_zero_array(newreq, struct iovec, count);
if (!outvec) {
@@ -844,19 +835,20 @@ static void smbd_smb2_request_pending_writev_done(struct tevent_req *subreq)
TALLOC_FREE(state);
}
+static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data);
+
NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
- struct tevent_req *subreq)
+ struct tevent_req *subreq,
+ uint32_t defer_time)
{
NTSTATUS status;
- struct smbd_smb2_request_pending_state *state = NULL;
int i = req->current_idx;
- uint8_t *reqhdr = NULL;
- uint8_t *hdr = NULL;
- uint8_t *body = NULL;
- uint32_t flags = 0;
- uint64_t message_id = 0;
- uint64_t async_id = 0;
- struct iovec *outvec = NULL;
+ struct timeval defer_endtime;
+ uint8_t *outhdr = NULL;
+ uint32_t flags;
if (!tevent_req_is_in_progress(subreq)) {
return NT_STATUS_OK;
@@ -865,7 +857,14 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
req->subreq = subreq;
subreq = NULL;
- if (req->async) {
+ if (req->async_te) {
+ /* We're already async. */
+ return NT_STATUS_OK;
+ }
+
+ outhdr = (uint8_t *)req->out.vector[i].iov_base;
+ flags = IVAL(outhdr, SMB2_HDR_FLAGS);
+ if (flags & SMB2_HDR_FLAG_ASYNC) {
/* We're already async. */
return NT_STATUS_OK;
}
@@ -888,6 +887,8 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
}
if (req->out.vector_count > 4) {
+ struct iovec *outvec = NULL;
+
/* This is a compound reply. We
* must do an interim response
* followed by the async response
@@ -911,18 +912,94 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
*/
req->compound_related = false;
req->sconn->smb2.compound_related_in_progress = false;
+
+ /* Re-arrange the in.vectors. */
+ req->in.vector[1] = req->in.vector[i];
+ req->in.vector[2] = req->in.vector[i+1];
+ req->in.vector[3] = req->in.vector[i+2];
+ req->in.vector_count = 4;
+
+ /* Reset the new in size. */
+ smb2_setup_nbt_length(req->in.vector, 4);
+
+ /* Now recreate the out.vectors. */
+ outvec = talloc_zero_array(req, struct iovec, 4);
+ if (!outvec) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* 0 is always boilerplate and must
+ * be of size 4 for the length field. */
+
+ outvec[0].iov_base = req->out.nbt_hdr;
+ outvec[0].iov_len = 4;
+ SIVAL(req->out.nbt_hdr, 0, 0);
+
+ if (!dup_smb2_vec3(outvec, &outvec[1], &req->out.vector[i])) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ TALLOC_FREE(req->out.vector);
+
+ req->out.vector = outvec;
+
+ req->current_idx = 1;
+ req->out.vector_count = 4;
+
--
Samba Shared Repository
More information about the samba-cvs
mailing list