[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-2078-g64a1f17

Jeremy Allison jra at samba.org
Fri Jun 5 23:05:20 GMT 2009


The branch, master has been updated
       via  64a1f17aff1d17b74398fb270aac5768fd312cf6 (commit)
      from  68a1ef21971b5c15db5d0a82acc89791ffceaee0 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 64a1f17aff1d17b74398fb270aac5768fd312cf6
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Jun 5 16:06:05 2009 -0700

    Make cli_ftruncate async. Also add a simple test.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h      |    8 ++-
 source3/libsmb/clifile.c     |  188 ++++++++++++++++++++++++++----------------
 source3/libsmb/libsmb_file.c |    2 +-
 source3/torture/torture.c    |   24 ++++++
 4 files changed, 148 insertions(+), 74 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 961b3e0..19314e0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2494,7 +2494,13 @@ struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx,
 				  struct cli_state *cli, uint16_t fnum);
 NTSTATUS cli_close_recv(struct tevent_req *req);
 NTSTATUS cli_close(struct cli_state *cli, uint16_t fnum);
-bool cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size);
+struct tevent_req *cli_ftruncate_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					uint16_t fnum,
+					uint64_t size);
+NTSTATUS cli_ftruncate_recv(struct tevent_req *req);
+NTSTATUS cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size);
 NTSTATUS cli_locktype(struct cli_state *cli, uint16_t fnum,
 		      uint32_t offset, uint32_t len,
 		      int timeout, unsigned char locktype);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 693d976..a2f089c 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1981,45 +1981,6 @@ NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag)
 	return status;
 }
 
-#if 0
-int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag)
-{
-	unsigned int data_len = 1;
-	unsigned int param_len = 6;
-	uint16_t setup = TRANSACT2_SETFILEINFO;
-	char param[6];
-	unsigned char data;
-	char *rparam=NULL, *rdata=NULL;
-
-	memset(param, 0, param_len);
-	SSVAL(param,0,fnum);
-	SSVAL(param,2,SMB_SET_FILE_DISPOSITION_INFO);
-
-	data = flag ? 1 : 0;
-
-	if (!cli_send_trans(cli, SMBtrans2,
-			NULL,                        /* name */
-			-1, 0,                          /* fid, flags */
-			&setup, 1, 0,                   /* setup, length, max */
-			param, param_len, 2,            /* param, length, max */
-			(char *)&data,  data_len, cli->max_xmit /* data, length, max */
-			)) {
-		return false;
-	}
-
-	if (!cli_receive_trans(cli, SMBtrans2,
-			&rparam, &param_len,
-			&rdata, &data_len)) {
-		return false;
-	}
-
-	SAFE_FREE(rdata);
-	SAFE_FREE(rparam);
-
-	return true;
-}
-#endif
-
 struct cli_ntcreate_state {
 	uint16_t vwv[24];
 	uint16_t fnum;
@@ -2506,50 +2467,133 @@ NTSTATUS cli_close(struct cli_state *cli, uint16_t fnum)
  Truncate a file to a specified size
 ****************************************************************************/
 
-bool cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size)
+struct ftrunc_state {
+	uint16_t setup;
+	uint8_t param[6];
+	uint8_t data[8];
+};
+
+static void cli_ftruncate_done(struct tevent_req *subreq)
 {
-	unsigned int param_len = 6;
-	unsigned int data_len = 8;
-	uint16_t setup = TRANSACT2_SETFILEINFO;
-	char param[6];
-	unsigned char data[8];
-	char *rparam=NULL, *rdata=NULL;
-	int saved_timeout = cli->timeout;
+	struct tevent_req *req = tevent_req_callback_data(
+				subreq, struct tevent_req);
+	struct ftrunc_state *state = tevent_req_data(req, struct ftrunc_state);
+	NTSTATUS status;
 
-	SSVAL(param,0,fnum);
-	SSVAL(param,2,SMB_SET_FILE_END_OF_FILE_INFO);
-	SSVAL(param,4,0);
+	status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	tevent_req_done(req);
+}
 
-        SBVAL(data, 0, size);
+struct tevent_req *cli_ftruncate_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					uint16_t fnum,
+					uint64_t size)
+{
+	struct tevent_req *req = NULL, *subreq = NULL;
+	struct ftrunc_state *state = NULL;
 
-	if (!cli_send_trans(cli, SMBtrans2,
-                            NULL,                    /* name */
-                            -1, 0,                   /* fid, flags */
-                            &setup, 1, 0,            /* setup, length, max */
-                            param, param_len, 2,     /* param, length, max */
-                            (char *)&data,  data_len,/* data, length, ... */
-                            cli->max_xmit)) {        /* ... max */
-		cli->timeout = saved_timeout;
-		return False;
+	req = tevent_req_create(mem_ctx, &state, struct ftrunc_state);
+	if (req == NULL) {
+		return NULL;
 	}
 
-	if (!cli_receive_trans(cli, SMBtrans2,
-				&rparam, &param_len,
-				&rdata, &data_len)) {
-		cli->timeout = saved_timeout;
-		SAFE_FREE(rdata);
-		SAFE_FREE(rparam);
-		return False;
-	}
+	/* Setup setup word. */
+	SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
 
-	cli->timeout = saved_timeout;
+	/* Setup param array. */
+	SSVAL(state->param,0,fnum);
+	SSVAL(state->param,2,SMB_SET_FILE_END_OF_FILE_INFO);
+	SSVAL(state->param,4,0);
 
-	SAFE_FREE(rdata);
-	SAFE_FREE(rparam);
+	/* Setup data array. */
+        SBVAL(state->data, 0, size);
 
-	return True;
+	subreq = cli_trans_send(state,			/* mem ctx. */
+				ev,			/* event ctx. */
+				cli,			/* cli_state. */
+				SMBtrans2,		/* cmd. */
+				NULL,			/* pipe name. */
+				-1,			/* fid. */
+				0,			/* function. */
+				0,			/* flags. */
+				&state->setup,		/* setup. */
+				1,			/* num setup uint16_t words. */
+				0,			/* max returned setup. */
+				state->param,		/* param. */
+				6,			/* num param. */
+				2,			/* max returned param. */
+				state->data,		/* data. */
+				8,			/* num data. */
+				0);			/* max returned data. */
+
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, cli_ftruncate_done, req);
+	return req;
+}
+
+NTSTATUS cli_ftruncate_recv(struct tevent_req *req)
+{
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	return NT_STATUS_OK;
 }
 
+NTSTATUS cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct event_context *ev = NULL;
+	struct tevent_req *req = NULL;
+	NTSTATUS status = NT_STATUS_OK;
+
+	if (cli_has_async_calls(cli)) {
+		/*
+		 * Can't use sync call while an async call is in flight
+		 */
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto fail;
+	}
+
+	ev = event_context_init(frame);
+	if (ev == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto fail;
+	}
+
+	req = cli_ftruncate_send(frame,
+				ev,
+				cli,
+				fnum,
+				size);
+	if (req == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto fail;
+	}
+
+	if (!tevent_req_poll(req, ev)) {
+		status = map_nt_error_from_unix(errno);
+		goto fail;
+	}
+
+	status = cli_ftruncate_recv(req);
+
+ fail:
+	TALLOC_FREE(frame);
+	if (!NT_STATUS_IS_OK(status)) {
+		cli_set_error(cli, status);
+	}
+	return status;
+}
 
 /****************************************************************************
  send a lock with a specified locktype
diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c
index abfec17..f6cd8ec 100644
--- a/source3/libsmb/libsmb_file.c
+++ b/source3/libsmb/libsmb_file.c
@@ -867,7 +867,7 @@ SMBC_ftruncate_ctx(SMBCCTX *context,
 	}
 	/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
         
-        if (!cli_ftruncate(targetcli, file->cli_fd, size)) {
+        if (!NT_STATUS_IS_OK(cli_ftruncate(targetcli, file->cli_fd, (uint64_t)size))) {
                 errno = EINVAL;
                 TALLOC_FREE(frame);
                 return -1;
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index d185a71..056b74a 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -4144,6 +4144,7 @@ static bool run_simple_posix_open_test(int dummy)
 	uint16 major, minor;
 	uint32 caplow, caphigh;
 	uint16_t fnum1 = (uint16_t)-1;
+	SMB_STRUCT_STAT sbuf;
 	bool correct = false;
 
 	printf("Starting simple POSIX open test\n");
@@ -4191,6 +4192,29 @@ static bool run_simple_posix_open_test(int dummy)
 		goto out;
 	}
 
+	/* Test ftruncate - set file size. */
+	if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
+		printf("ftruncate failed (%s)\n", cli_errstr(cli1));
+		goto out;
+	}
+
+	/* Ensure st_size == 1000 */
+	if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
+		printf("stat failed (%s)\n", cli_errstr(cli1));
+		goto out;
+	}
+
+	if (sbuf.st_ex_size != 1000) {
+		printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
+		goto out;
+	}
+
+	/* Test ftruncate - set file size back to zero. */
+	if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
+		printf("ftruncate failed (%s)\n", cli_errstr(cli1));
+		goto out;
+	}
+
 	if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
 		printf("close failed (%s)\n", cli_errstr(cli1));
 		goto out;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list