[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1732-g000da55

Jeremy Allison jra at samba.org
Thu May 21 01:31:47 GMT 2009


The branch, master has been updated
       via  000da55dd930d151db14ee8eed58e82806522692 (commit)
      from  c1a21d085d758284fe6997a05396f225da683352 (commit)

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


- Log -----------------------------------------------------------------
commit 000da55dd930d151db14ee8eed58e82806522692
Author: Jeremy Allison <jra at samba.org>
Date:   Wed May 20 18:31:36 2009 -0700

    Make cli_posix_open() and cli_posix_mkdir() async.
    Jeremy.

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

Summary of changes:
 source3/client/client.c   |   12 +--
 source3/include/proto.h   |   20 +++-
 source3/libsmb/clifile.c  |  273 +++++++++++++++++++++++++++++++++++---------
 source3/torture/torture.c |   13 +--
 4 files changed, 243 insertions(+), 75 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index f4d9963..59e5c1a 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2296,7 +2296,7 @@ static int cmd_posix_open(void)
 	char *targetname = NULL;
 	struct cli_state *targetcli;
 	mode_t mode;
-	int fnum;
+	uint16_t fnum;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
 		d_printf("posix_open <filename> 0<mode>\n");
@@ -2321,10 +2321,8 @@ static int cmd_posix_open(void)
 		return 1;
 	}
 
-	fnum = cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode);
-	if (fnum == -1) {
-		fnum = cli_posix_open(targetcli, targetname, O_CREAT|O_RDONLY, mode);
-		if (fnum != -1) {
+	if (!NT_STATUS_IS_OK(cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode, &fnum))) {
+		if (!NT_STATUS_IS_OK(cli_posix_open(targetcli, targetname, O_CREAT|O_RDONLY, mode, &fnum))) {
 			d_printf("posix_open file %s: for read/write fnum %d\n", targetname, fnum);
 		} else {
 			d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
@@ -2344,7 +2342,6 @@ static int cmd_posix_mkdir(void)
 	char *targetname = NULL;
 	struct cli_state *targetcli;
 	mode_t mode;
-	int fnum;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
 		d_printf("posix_mkdir <filename> 0<mode>\n");
@@ -2369,8 +2366,7 @@ static int cmd_posix_mkdir(void)
 		return 1;
 	}
 
-	fnum = cli_posix_mkdir(targetcli, targetname, mode);
-	if (fnum == -1) {
+	if (!NT_STATUS_IS_OK(cli_posix_mkdir(targetcli, targetname, mode))) {
 		d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
 	} else {
 		d_printf("posix_mkdir created directory %s\n", targetname);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index a45fa42..e0b0e59 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2527,14 +2527,28 @@ bool cli_get_ea_list_fnum(struct cli_state *cli, uint16_t fnum,
 		TALLOC_CTX *ctx,
 		size_t *pnum_eas,
 		struct ea_struct **pea_list);
-int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode);
-int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode);
+struct tevent_req *cli_posix_open_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					const char *fname,
+					int flags,
+					mode_t mode);
+NTSTATUS cli_posix_open_recv(struct tevent_req *req, uint16_t *pfnum);
+NTSTATUS cli_posix_open(struct cli_state *cli, const char *fname,
+			int flags, mode_t mode, uint16_t *fnum);
+struct tevent_req *cli_posix_mkdir_send(TALLOC_CTX *mem_ctx,
+                                        struct event_context *ev,
+                                        struct cli_state *cli,
+                                        const char *fname,
+                                        mode_t mode);
+NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req);
+NTSTATUS cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode);
 
 struct tevent_req *cli_posix_unlink_send(TALLOC_CTX *mem_ctx,
 					struct event_context *ev,
 					struct cli_state *cli,
 					const char *fname);
-NTSTATUS cli_posix_unlink_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx);
+NTSTATUS cli_posix_unlink_recv(struct tevent_req *req);
 NTSTATUS cli_posix_unlink(struct cli_state *cli, const char *fname);
 
 struct tevent_req *cli_posix_rmdir_send(TALLOC_CTX *mem_ctx,
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 3c13383..2c80f1d 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -3311,87 +3311,248 @@ static uint32_t open_flags_to_wire(int flags)
  Open a file - POSIX semantics. Returns fnum. Doesn't request oplock.
 ****************************************************************************/
 
-static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int flags, mode_t mode, bool is_dir)
+struct posix_open_state {
+	uint16_t setup;
+	uint8_t *param;
+	uint8_t data[18];
+	uint16_t fnum; /* Out */
+};
+
+static void cli_posix_open_internal_done(struct tevent_req *subreq)
 {
-	unsigned int data_len = 0;
-	unsigned int param_len = 0;
-	uint16_t setup = TRANSACT2_SETPATHINFO;
-	char *param;
-	char data[18];
-	char *rparam=NULL, *rdata=NULL;
-	char *p;
-	uint16_t fnum = (uint16_t)-1;
+	struct tevent_req *req = tevent_req_callback_data(
+				subreq, struct tevent_req);
+	struct posix_open_state *state = tevent_req_data(req, struct posix_open_state);
+	NTSTATUS status;
+	uint8_t *data;
+	uint32_t num_data;
+
+	status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &data, &num_data);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	if (num_data < 12) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+	state->fnum = SVAL(data,2);
+	tevent_req_done(req);
+}
+
+static struct tevent_req *cli_posix_open_internal_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					const char *fname,
+					int flags,
+					mode_t mode,
+					bool is_dir)
+{
+	struct tevent_req *req = NULL, *subreq = NULL;
+	struct posix_open_state *state = NULL;
 	uint32_t wire_flags = open_flags_to_wire(flags);
-	size_t srclen = 2*(strlen(fname)+1);
 
-	param = SMB_MALLOC_ARRAY(char, 6+srclen+2);
-	if (!param) {
-		return false;
+	req = tevent_req_create(mem_ctx, &state, struct posix_open_state);
+	if (req == NULL) {
+		return NULL;
 	}
-	memset(param, '\0', 6);
-	SSVAL(param,0, SMB_POSIX_PATH_OPEN);
-	p = &param[6];
 
-	p += clistr_push(cli, p, fname, srclen, STR_TERMINATE);
-	param_len = PTR_DIFF(p, param);
+	/* Setup setup word. */
+	SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
 
-	if (is_dir) {
-		wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
-		wire_flags |= SMB_O_DIRECTORY;
+	/* Setup param array. */
+	state->param = talloc_array(state, uint8_t, 6);
+	if (tevent_req_nomem(state->param, req)) {
+		return tevent_req_post(req, ev);
 	}
+	memset(state->param, '\0', 6);
+	SSVAL(state->param, 0, SMB_POSIX_PATH_OPEN);
 
-	p = data;
-	SIVAL(p,0,0); /* No oplock. */
-	SIVAL(p,4,wire_flags);
-	SIVAL(p,8,unix_perms_to_wire(mode));
-	SIVAL(p,12,0); /* Top bits of perms currently undefined. */
-	SSVAL(p,16,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */
+	state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+				   strlen(fname)+1, NULL);
 
-	data_len = 18;
+	if (tevent_req_nomem(state->param, req)) {
+		return tevent_req_post(req, ev);
+	}
 
-	if (!cli_send_trans(cli, SMBtrans2,
-			NULL,                        /* name */
-			-1, 0,                          /* fid, flags */
-			&setup, 1, 0,                   /* setup, length, max */
-			param, param_len, 0,            /* param, length, max */
-			(char *)&data,  data_len, cli->max_xmit /* data, length, max */
-			)) {
-		SAFE_FREE(param);
-		return -1;
+	/* Setup data words. */
+	if (is_dir) {
+		wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
+		wire_flags |= SMB_O_DIRECTORY;
 	}
 
-	SAFE_FREE(param);
+	SIVAL(state->data,0,0); /* No oplock. */
+	SIVAL(state->data,4,wire_flags);
+	SIVAL(state->data,8,unix_perms_to_wire(mode));
+	SIVAL(state->data,12,0); /* Top bits of perms currently undefined. */
+	SSVAL(state->data,16,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */
 
-	if (!cli_receive_trans(cli, SMBtrans2,
-		&rparam, &param_len,
-		&rdata, &data_len)) {
-			return -1;
+	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. */
+				talloc_get_size(state->param),/* num param. */
+				2,			/* max returned param. */
+				state->data,		/* data. */
+				18,			/* num data. */
+				12);			/* max returned data. */
+
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
 	}
+	tevent_req_set_callback(subreq, cli_posix_open_internal_done, req);
+	return req;
+}
 
-	fnum = SVAL(rdata,2);
+struct tevent_req *cli_posix_open_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					const char *fname,
+					int flags,
+					mode_t mode)
+{
+	return cli_posix_open_internal_send(mem_ctx, ev,
+				cli, fname, flags, mode, false);
+}
 
-	SAFE_FREE(rdata);
-	SAFE_FREE(rparam);
+NTSTATUS cli_posix_open_recv(struct tevent_req *req, uint16_t *pfnum)
+{
+	struct posix_open_state *state = tevent_req_data(req, struct posix_open_state);
+	NTSTATUS status;
 
-	return fnum;
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	*pfnum = state->fnum;
+	return NT_STATUS_OK;
 }
 
 /****************************************************************************
- open - POSIX semantics.
+ Open - POSIX semantics. Doesn't request oplock.
 ****************************************************************************/
 
-int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode)
+NTSTATUS cli_posix_open(struct cli_state *cli, const char *fname,
+			int flags, mode_t mode, uint16_t *pfnum)
 {
-	return cli_posix_open_internal(cli, fname, flags, mode, False);
+
+	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_posix_open_send(frame,
+				ev,
+				cli,
+				fname,
+				flags,
+				mode);
+	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_posix_open_recv(req, pfnum);
+
+ fail:
+	TALLOC_FREE(frame);
+	if (!NT_STATUS_IS_OK(status)) {
+		cli_set_error(cli, status);
+	}
+	return status;
 }
 
-/****************************************************************************
- mkdir - POSIX semantics.
-****************************************************************************/
+struct tevent_req *cli_posix_mkdir_send(TALLOC_CTX *mem_ctx,
+					struct event_context *ev,
+					struct cli_state *cli,
+					const char *fname,
+					mode_t mode)
+{
+	return cli_posix_open_internal_send(mem_ctx, ev,
+				cli, fname, O_CREAT, mode, true);
+}
 
-int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode)
+NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req)
 {
-	return (cli_posix_open_internal(cli, fname, O_CREAT, mode, True) == -1) ? -1 : 0;
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode)
+{
+	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_posix_mkdir_send(frame,
+				ev,
+				cli,
+				fname,
+				mode);
+	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_posix_mkdir_recv(req);
+
+ fail:
+	TALLOC_FREE(frame);
+	if (!NT_STATUS_IS_OK(status)) {
+		cli_set_error(cli, status);
+	}
+	return status;
 }
 
 /****************************************************************************
@@ -3489,7 +3650,7 @@ struct tevent_req *cli_posix_unlink_send(TALLOC_CTX *mem_ctx,
 	return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, false);
 }
 
-NTSTATUS cli_posix_unlink_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx)
+NTSTATUS cli_posix_unlink_recv(struct tevent_req *req)
 {
 	NTSTATUS status;
 
@@ -3538,7 +3699,7 @@ NTSTATUS cli_posix_unlink(struct cli_state *cli, const char *fname)
 		goto fail;
 	}
 
-	status = cli_posix_unlink_recv(req, frame);
+	status = cli_posix_unlink_recv(req);
 
  fail:
 	TALLOC_FREE(frame);
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 162ba2b..25a912d 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -4139,7 +4139,7 @@ static bool run_simple_posix_open_test(int dummy)
 	const char *dname = "\\posix:dir";
 	uint16 major, minor;
 	uint32 caplow, caphigh;
-	int fnum1 = -1;
+	uint16_t fnum1 = (uint16_t)-1;
 	bool correct = false;
 
 	printf("Starting simple POSIX open test\n");
@@ -4173,13 +4173,12 @@ static bool run_simple_posix_open_test(int dummy)
 	cli_posix_rmdir(cli1, dname);
 
 	/* Create a directory. */
-	if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
+	if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
 		printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
 		goto out;
 	}
 
-	fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
-	if (fnum1 == -1) {
+	if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
 		printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
 		goto out;
 	}
@@ -4190,8 +4189,7 @@ static bool run_simple_posix_open_test(int dummy)
 	}
 
 	/* Now open the file again for read only. */
-	fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
-	if (fnum1 == -1) {
+	if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
 		printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
 		goto out;
 	}
@@ -4208,8 +4206,7 @@ static bool run_simple_posix_open_test(int dummy)
 	}
 
 	/* Ensure the file has gone. */
-	fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
-	if (fnum1 != -1) {
+	if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
 		printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
 		goto out;
 	}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list